[PATCH v10 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index ecf613761e78..d42b1ecaf490 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -187,6 +187,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.15.0
[PATCH v10 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index d42b1ecaf490..e8036cddb272 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -613,6 +613,7 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -628,6 +629,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.15.0
[PATCH v10 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 619 drivers/scsi/ufs/ufs-hisi.h | 115 4 files changed, 744 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..e09fe6ab3572 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -100,3 +100,12 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. + +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 918f5791202d..2c50f03d8c4a 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o ufshcd-core-objs := ufshcd.o ufs-sysfs.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..524861cd0ffd --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,619 @@ +/* + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * Released under the GPLv2 only. + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err = 0; + u32 tx_fsm_val_0 = 0; + u32 tx_fsm_val_1 = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hi3660_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); +} + +static void ufs_hi3660_soc_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + u32 reg; + + if (!IS_ERR(host->rst)) + reset_control_assert(host->rst); + + /* HC_PSW powerup */ + ufs_sys_ctrl_set_bits(host, BIT_UFS_PSW_MTCMOS_EN, PSW_POWER_CTRL); + udelay(10); + /* notify PWR ready */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_PWR_READY,
[PATCH v10 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 41 ++ .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 10 +- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 18 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 619 + drivers/scsi/ufs/ufs-hisi.h| 115 8 files changed, 821 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h Major changes in v10: - solve review comments from Rob Herring. *Modify the "reset-names" describe in ufs-hisi.txt binding file. *List clocks in ufs-hisi.txt binding file. *remove the "arst" and keep only "rst" in the binging files. *remove the "arst" member from both dts and c code. Major changes in v9: - solve review comments from Rob Herring. *remove freq-table-hz in ufs-hisi.txt binding file. *Move the rst to the ufshcd_pltfm.txt common binding file. *Modify the member "assert" of UFS host structure to "arst". Major changes in v8: - solve review comments from zhangfei. *Add Version history. - solve review comments from Rob Herring. *remove freq-table-hz. - solve review comments from Riku Voipio. *Add MODULE_DEVICE_TABLE for ufs driver. -- Major changes in v7: - solve review comments from Philippe Ombredanne. *use the new SPDX license ids instead of the GNU General Public License. -- 2.15.0
[PATCH v10 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 41 ++ .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 10 -- 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..a48c44817367 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,41 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs + host controller present on Hi36xx chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ref_clk", "phy_clk" is optional +- freq-table-hz : Array of operating frequencies stored in the same + order as the clocks property. If this property is not + defined or a value in the array is "0" then it is assumed + that the frequency is set by the parent clock or a + fixed rate clock source. +- resets: describe reset node register +- reset-names : reset node register, the "rst" corresponds to reset the whole UFS IP. + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + resets = <&crg_rst 0x84 12>; + reset-names = "rst"; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index c39dfef76a18..2df00524bd21 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -41,6 +41,8 @@ Optional properties: -lanes-per-direction : number of lanes available per direction - either 1 or 2. Note that it is assume same number of lanes is used both directions at once. If not specified, default is 2 lanes per direction. +- resets: reset node register +- reset-names : describe reset node register, the "rst" corresponds to reset the whole UFS IP. Note: If above properties are not defined it can be assumed that the supply regulators or clocks are always on. @@ -61,9 +63,11 @@ Example: vccq-max-microamp = 20; vccq2-max-microamp = 20; - clocks = <&core 0>, <&ref 0>, <&iface 0>; - clock-names = "core_clk", "ref_clk", "iface_clk"; - freq-table-hz = <1 2>, <0 0>, <0 0>; + clocks = <&core 0>, <&ref 0>, <&phy 0>, <&iface 0>; + clock-names = "core_clk", "ref_clk", "phy_clk", "iface_clk"; + freq-table-hz = <1 2>, <0 0>, <0 0>, <0 0>; + resets = <&reset 0 1>; + reset-names = "rst"; phys = <&ufsphy1>; phy-names = "ufsphy"; }; -- 2.15.0
[PATCH v10 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 18 ++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index ec3eb8e33a3a..04438621c6c3 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -892,6 +892,24 @@ reset-gpios = <&gpio11 1 0 >; }; + /* UFS */ + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + resets = <&crg_rst 0x84 12>; + reset-names = "rst"; + }; + /* SD */ dwmmc1: dwmmc1@ff37f000 { #address-cells = <1>; -- 2.15.0
[PATCH v9 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 621 drivers/scsi/ufs/ufs-hisi.h | 114 4 files changed, 745 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..10c3e60d86a5 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -100,3 +100,12 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. + +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + help + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 918f5791202d..2c50f03d8c4a 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o ufshcd-core-objs := ufshcd.o ufs-sysfs.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..bb9b1cc198db --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,621 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err = 0; + u32 tx_fsm_val_0 = 0; + u32 tx_fsm_val_1 = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hi3660_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); +} + +static void ufs_hi3660_soc_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + u32 reg; + + if (!IS_ERR(host->rst)) + reset_control_assert(host->rst); + + /* HC_PSW powerup */ + ufs_sys_ctrl_set_bits(host, BIT_UFS_PSW_MTCMOS_EN, PSW_POWER_CTRL); + udelay(10); + /* notify PWR ready */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_PWR_READY, HC_LP_CTRL); + ufs_sys_ctrl_write
[PATCH v9 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 29 + .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 10 +- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 621 + drivers/scsi/ufs/ufs-hisi.h| 114 8 files changed, 812 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h Major changes in v9: - solve review comments from Rob Herring. *remove clocks/clock-names/freq-table-hz from ufs-hisi.txt binding file. *Move the rst to the ufshcd_pltfm.txt common binding file. *Modify the member "assert" of UFS host structure to "arst". -- Major changes in v8: - solve review comments from zhangfei. *Add Version history. - solve review comments from Rob Herring. *remove freq-table-hz. - solve review comments from Riku Voipio. *Add MODULE_DEVICE_TABLE for ufs driver. -- Major changes in v7: - solve review comments from Philippe Ombredanne. *use the new SPDX license ids instead of the GNU General Public License. -- 2.15.0
[PATCH v9 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index ec3eb8e33a3a..e9013d40a613 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -892,6 +892,26 @@ reset-gpios = <&gpio11 1 0 >; }; + /* UFS */ + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "arst"; + }; + /* SD */ dwmmc1: dwmmc1@ff37f000 { #address-cells = <1>; -- 2.15.0
[PATCH v9 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index ecf613761e78..d42b1ecaf490 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -187,6 +187,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.15.0
[PATCH v9 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 29 ++ .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 10 +--- 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..d49ab7d8f31d --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,29 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs + host controller present on Hi36xx chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- resets: reset node register, the "arst" corresponds to reset the APB/AXI bus. +- reset-names : describe reset node register + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 7>; + reset-names = "arst"; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index c39dfef76a18..adcfb79f63f5 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -41,6 +41,8 @@ Optional properties: -lanes-per-direction : number of lanes available per direction - either 1 or 2. Note that it is assume same number of lanes is used both directions at once. If not specified, default is 2 lanes per direction. +- resets: reset node register, the "rst" corresponds to reset the whole UFS IP. +- reset-names : describe reset node register Note: If above properties are not defined it can be assumed that the supply regulators or clocks are always on. @@ -61,9 +63,11 @@ Example: vccq-max-microamp = 20; vccq2-max-microamp = 20; - clocks = <&core 0>, <&ref 0>, <&iface 0>; - clock-names = "core_clk", "ref_clk", "iface_clk"; - freq-table-hz = <1 2>, <0 0>, <0 0>; + clocks = <&core 0>, <&ref 0>, <&phy 0>, <&iface 0>; + clock-names = "core_clk", "ref_clk", "phy_clk", "iface_clk"; + freq-table-hz = <1 2>, <0 0>, <0 0>, <0 0>; + resets = <&reset 0 1>; + reset-names = "rst"; phys = <&ufsphy1>; phy-names = "ufsphy"; }; -- 2.15.0
[PATCH v9 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index d42b1ecaf490..e8036cddb272 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -613,6 +613,7 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -628,6 +629,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.15.0
[PATCH v8 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index ab0b95ba5ae5..d0dfa97fdad1 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -904,6 +904,25 @@ reset-gpios = <&gpio11 1 0 >; }; + /* UFS */ + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + /* SD */ dwmmc1: dwmmc1@ff37f000 { #address-cells = <1>; -- 2.15.0
[PATCH v8 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 37 ++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..0d21b57496cf --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,37 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs + host controller present on Hi36xx chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ref_clk", "phy_clk" is optional +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; -- 2.15.0
[PATCH v8 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 6356c6da34ea..fa6f921eed86 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -174,6 +174,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.15.0
[PATCH v8 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 37 ++ arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 623 + drivers/scsi/ufs/ufs-hisi.h| 116 7 files changed, 816 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- Major changes in v7: - solve review comments from Philippe Ombredanne. *use the new SPDX license ids instead of the GNU General Public License. Major changes in v8: - solve review comments from zhangfei. *Add Version history. - solve review comments from Rob Herring. *remove freq-table-hz. - solve review comments from Riku Voipio. *Add MODULE_DEVICE_TABLE for ufs driver. 2.15.0
[PATCH v8 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 623 drivers/scsi/ufs/ufs-hisi.h | 116 + 4 files changed, 749 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..e09fe6ab3572 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -100,3 +100,12 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. + +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 9310c6c83041..e1ebf1031437 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..c1eaf862a44c --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,623 @@ +/* + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * Released under the GPLv2 only. + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err = 0; + u32 tx_fsm_val_0 = 0; + u32 tx_fsm_val_1 = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hi3660_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); +} + +static void ufs_hi3660_soc_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + u32 reg; + + if (!IS_ERR(host->rst)) + reset_control_assert(host->rst); + + /* HC_PSW powerup */ + ufs_sys_ctrl_set_bits(host, BIT_UFS_PSW_MTCMOS_EN, PSW_POWER_CTRL); + udelay(10); + /* notify PWR ready */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_PWR_READY,
[PATCH v8 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index fa6f921eed86..7be4ee2ac680 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -572,6 +572,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -587,6 +588,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.15.0
[PATCH v7 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index fa6f921eed86..7be4ee2ac680 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -572,6 +572,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -587,6 +588,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.15.0
[PATCH v7 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 6356c6da34ea..fa6f921eed86 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -174,6 +174,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.15.0
[PATCH v7 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index ab0b95ba5ae5..3c57346366ad 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -904,6 +904,26 @@ reset-gpios = <&gpio11 1 0 >; }; + /* UFS */ + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + /* SD */ dwmmc1: dwmmc1@ff37f000 { #address-cells = <1>; -- 2.15.0
[PATCH v7 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 43 ++ arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 621 + drivers/scsi/ufs/ufs-hisi.h| 116 7 files changed, 821 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.15.0
[PATCH v7 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 43 ++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..175693e47d6b --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,43 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs + host controller present on Hi36xx chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ref_clk", "phy_clk" is optional +- freq-table-hz: Array of operating frequencies stored in the same + order as the clocks property. If this property is not + defined or a value in the array is "0" then it is assumed + that the frequency is set by the parent clock or a + fixed rate clock source. +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; -- 2.15.0
[PATCH v7 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 621 drivers/scsi/ufs/ufs-hisi.h | 116 + 4 files changed, 747 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..e09fe6ab3572 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -100,3 +100,12 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. + +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 9310c6c83041..2e40fcd5f8b3 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..2f3326cc016c --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,621 @@ +/* + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * Released under the GPLv2 only. + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err = 0; + u32 tx_fsm_val_0 = 0; + u32 tx_fsm_val_1 = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hi3660_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); +} + +static void ufs_hi3660_soc_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + u32 reg; + + if (!IS_ERR(host->rst)) + reset_control_assert(host->rst); + + /* HC_PSW poweru
[PATCH v6 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 38 ++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..73e10698960e --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,38 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs", "jedec,ufs-1.1" for hisi ufs + host controller present on Hi36xx chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ref_clk", "phy_clk" is optional +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; -- 2.15.0
[PATCH v6 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 6356c6da34ea..fa6f921eed86 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -174,6 +174,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.15.0
[PATCH v6 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 624 drivers/scsi/ufs/ufs-hisi.h | 122 + 4 files changed, 756 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..e09fe6ab3572 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -100,3 +100,12 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. + +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 9310c6c83041..e1ebf1031437 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..0c9551b3bfb2 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,624 @@ +/* + * + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err = 0; + u32 tx_fsm_val_0 = 0; + u32 tx_fsm_val_1 = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hi3660_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); +} + +static void ufs_hi3660_soc_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + u32 reg; + + if (!IS_ERR(host->rst)) + reset_control_assert(host->rst); + + /* HC_PSW poweru
[PATCH v6 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index fa6f921eed86..7be4ee2ac680 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -572,6 +572,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -587,6 +588,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.15.0
[PATCH v6 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index ab0b95ba5ae5..3c57346366ad 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -904,6 +904,26 @@ reset-gpios = <&gpio11 1 0 >; }; + /* UFS */ + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "ref_clk", "phy_clk"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + /* SD */ dwmmc1: dwmmc1@ff37f000 { #address-cells = <1>; -- 2.15.0
[PATCH v6 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 38 ++ arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 20 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 624 + drivers/scsi/ufs/ufs-hisi.h| 122 7 files changed, 825 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.15.0
[PATCH v4 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 47 ++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..ee114a65143d --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,47 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs" for hisi ufs host controller +present on Hi3660 chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "clk_ref", "clk_phy" is optional +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Optional properties for board device: +- reset-gpio : specifies to reset devices + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + + &ufs { + reset-gpio = <&gpio18 1 0>; + status = "okay"; + }; + -- 2.11.0
[PATCH v4 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 625 drivers/scsi/ufs/ufs-hisi.h | 161 4 files changed, 796 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..bf2ff5628b15 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM If unsure, say N. +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. + config SCSI_UFS_DWC_TC_PLATFORM tristate "DesignWare platform support using a G210 Test Chip" depends on SCSI_UFSHCD_PLATFORM diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 6e77cb0bfee9..9f2c17029a38 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..8b7aea2d44c5 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,625 @@ +/* + * + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err; + u32 tx_fsm_val_0; + u32 tx_fsm_val_1; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hisi_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN
[PATCH v5 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 34480e9af2e7..8aff981915f5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -168,6 +168,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.11.0
[PATCH v5 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8aff981915f5..0a8a843cd0be 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -555,6 +555,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -570,6 +571,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.11.0
[PATCH v5 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 46 ++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..17da633c9ed5 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,46 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs" for hisi ufs host controller +present on Hi3660 chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "clk_ref", "clk_phy" is optional +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Optional properties for board device: +- reset-gpios : specifies to reset devices + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + + &ufs { + reset-gpios = <&gpio18 1 0>; + }; + -- 2.11.0
[PATCH v5 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 625 drivers/scsi/ufs/ufs-hisi.h | 161 4 files changed, 796 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..bf2ff5628b15 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM If unsure, say N. +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. + config SCSI_UFS_DWC_TC_PLATFORM tristate "DesignWare platform support using a G210 Test Chip" depends on SCSI_UFSHCD_PLATFORM diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 6e77cb0bfee9..9f2c17029a38 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..38a2e238c5e1 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,625 @@ +/* + * + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err; + u32 tx_fsm_val_0; + u32 tx_fsm_val_1; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hisi_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN
[PATCH v5 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++ 2 files changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index fd4705c451e2..677d0e41667f 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -276,3 +276,8 @@ interrupts = <3 IRQ_TYPE_EDGE_RISING>; }; }; + +&ufs { + reset-gpios = <&gpio18 1 0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index b7a90d632959..a24ab8472347 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -978,5 +978,24 @@ clocks = <&crg_ctrl HI3660_OSC32K>; clock-names = "apb_pclk"; }; + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; }; }; -- 2.11.0
[PATCH v5 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 46 ++ arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 625 + drivers/scsi/ufs/ufs-hisi.h| 161 ++ 8 files changed, 877 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.11.0
[PATCH v4 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 34480e9af2e7..8aff981915f5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -168,6 +168,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.11.0
[PATCH v4 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8aff981915f5..0a8a843cd0be 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -555,6 +555,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -570,6 +571,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.11.0
[PATCH v4 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++ 2 files changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index fd4705c451e2..457645a2b53f 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -276,3 +276,8 @@ interrupts = <3 IRQ_TYPE_EDGE_RISING>; }; }; + +&ufs { + reset-gpio = <&gpio18 1 0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index b7a90d632959..a24ab8472347 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -978,5 +978,24 @@ clocks = <&crg_ctrl HI3660_OSC32K>; clock-names = "apb_pclk"; }; + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; }; }; -- 2.11.0
[PATCH v4 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 47 ++ arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 625 + drivers/scsi/ufs/ufs-hisi.h| 161 ++ 8 files changed, 878 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.11.0
[PATCH v4 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board. Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 47 ++ arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 625 + drivers/scsi/ufs/ufs-hisi.h| 161 ++ 8 files changed, 878 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.11.0
[PATCH v4 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code. Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 625 drivers/scsi/ufs/ufs-hisi.h | 161 4 files changed, 796 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..bf2ff5628b15 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM If unsure, say N. +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. + config SCSI_UFS_DWC_TC_PLATFORM tristate "DesignWare platform support using a G210 Test Chip" depends on SCSI_UFSHCD_PLATFORM diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 6e77cb0bfee9..9f2c17029a38 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..8b7aea2d44c5 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,625 @@ +/* + * + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err; + u32 tx_fsm_val_0; + u32 tx_fsm_val_1; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hisi_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN
[PATCH v4 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 34480e9af2e7..8aff981915f5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -168,6 +168,9 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.11.0
[PATCH v4 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon. Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 47 ++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..ee114a65143d --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,47 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs" for hisi ufs host controller +present on Hi3660 chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "clk_ref", "clk_phy" is optional +- resets: reset node register, one reset the clk and the other reset the controller +- reset-names : describe reset node register + +Optional properties for board device: +- reset-gpio : specifies to reset devices + +Example: + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; + + &ufs { + reset-gpio = <&gpio18 1 0>; + status = "okay"; + }; + -- 2.11.0
[PATCH v4 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8aff981915f5..0a8a843cd0be 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -555,6 +555,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -570,6 +571,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.11.0
[PATCH v4 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon. Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 5 + arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 19 +++ 2 files changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index fd4705c451e2..457645a2b53f 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -276,3 +276,8 @@ interrupts = <3 IRQ_TYPE_EDGE_RISING>; }; }; + +&ufs { + reset-gpio = <&gpio18 1 0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index b7a90d632959..a24ab8472347 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -978,5 +978,24 @@ clocks = <&crg_ctrl HI3660_OSC32K>; clock-names = "apb_pclk"; }; + + ufs: ufs@ff3b { + compatible = "hisilicon,hi3660-ufs", "jedec,ufs-1.1"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + /* offset: 0x84; bit: 12 */ + /* offset: 0x84; bit: 7 */ + resets = <&crg_rst 0x84 12>, + <&crg_rst 0x84 7>; + reset-names = "rst", "assert"; + }; }; }; -- 2.11.0
[PATCH v3 1/5] scsi: ufs: add Hisilicon ufs driver code
add Hisilicon ufs driver code Signed-off-by: Li Wei Signed-off-by: Geng Jianfeng Signed-off-by: Zang Leigang Signed-off-by: Yu Jianfeng --- drivers/scsi/ufs/Kconfig| 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c | 634 drivers/scsi/ufs/ufs-hisi.h | 163 4 files changed, 807 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e27b4d4e6ae2..bf2ff5628b15 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -80,6 +80,15 @@ config SCSI_UFSHCD_PLATFORM If unsure, say N. +config SCSI_UFS_HISI + tristate "Hisilicon specific hooks to UFS controller platform driver" + depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM + ---help--- + This selects the Hisilicon specific additions to UFSHCD platform driver. + + Select this if you have UFS controller on Hisilicon chipset. + If unsure, say N. + config SCSI_UFS_DWC_TC_PLATFORM tristate "DesignWare platform support using a G210 Test Chip" depends on SCSI_UFSHCD_PLATFORM diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 6e77cb0bfee9..9f2c17029a38 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c new file mode 100644 index ..7c3ff7060428 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -0,0 +1,634 @@ +/* + * + * HiSilicon Hi UFS Driver + * + * Copyright (c) 2016-2017 Linaro Ltd. + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-hisi.h" +#include "ufshci.h" + +static int ufs_hisi_check_hibern8(struct ufs_hba *hba) +{ + int err; + u32 tx_fsm_val_0; + u32 tx_fsm_val_1; + unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS); + + do { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), + &tx_fsm_val_0); + err |= ufshcd_dme_get(hba, + UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && + tx_fsm_val_1 == TX_FSM_HIBERN8)) + break; + + /* sleep for max. 200us */ + usleep_range(100, 200); + } while (time_before(jiffies, timeout)); + + /* +* we might have scheduled out for long during polling so +* check the state again. +*/ + if (time_after(jiffies, timeout)) { + err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0), +&tx_fsm_val_0); + err |= ufshcd_dme_get(hba, +UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1); + } + + if (err) { + dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", + __func__, err); + } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || +tx_fsm_val_1 != TX_FSM_HIBERN8) { + err = -1; + dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n", + __func__, tx_fsm_val_0, tx_fsm_val_1); + } + + return err; +} + +static void ufs_hisi_clk_init(struct ufs_hba *hba) +{ + struct ufs_hisi_host *host = ufshcd_get_variant(hba); + + ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL); + if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN) + mdelay(1); + /* use abb clk */ + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL); + ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN); + /* open mphy ref clk */ + ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN
[PATCH v3 3/5] arm64: dts: add ufs dts node
arm64: dts: add ufs node for Hisilicon Signed-off-by: Li Wei --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index c6a1961e8d55..0ae01d7480df 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -848,5 +848,21 @@ &sdio_cfg_func>; status = "disabled"; }; + + ufs: ufs@ff3b { + compatible = "jedec,ufs-1.1", "hisilicon,hi3660-ufs"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + reset-gpio = <&gpio18 1 0>; + status = "okay"; + }; }; }; -- 2.11.0
[PATCH v3 0/5] scsi: ufs: add ufs driver code for Hisilicon Hi3660 SoC
This patchset adds driver support for UFS for Hi3660 SoC. It is verified on HiKey960 board Li Wei (5): scsi: ufs: add Hisilicon ufs driver code dt-bindings: scsi: ufs: add document for hisi-ufs arm64: dts: add ufs dts node arm64: defconfig: enable configs for Hisilicon ufs arm64: defconfig: enable f2fs and squashfs Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 35 ++ arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 16 + arch/arm64/configs/defconfig | 11 + drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hisi.c| 634 + drivers/scsi/ufs/ufs-hisi.h| 163 ++ 7 files changed, 869 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt create mode 100644 drivers/scsi/ufs/ufs-hisi.c create mode 100644 drivers/scsi/ufs/ufs-hisi.h -- 2.11.0
[PATCH v3 2/5] dt-bindings: scsi: ufs: add document for hisi-ufs
add ufs node document for Hisilicon Signed-off-by: Li Wei --- Documentation/devicetree/bindings/ufs/ufs-hisi.txt | 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-hisi.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-hisi.txt b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt new file mode 100644 index ..cfc84c821d50 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-hisi.txt @@ -0,0 +1,35 @@ +* Hisilicon Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +Required properties: +- compatible: compatible list, contains one of the following - + "hisilicon,hi3660-ufs" for hisi ufs host controller +present on Hi3660 chipset. +- reg : should contain UFS register address space & UFS SYS CTRL register address, +- interrupt-parent : interrupt device +- interrupts: interrupt number +- clocks : List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "clk_ref", "clk_phy" is optional + +Optional properties for board device: +- reset-gpio : specifies to reset devices + +Example: + + ufs: ufs@ff3b { + compatible = "jedec,ufs-1.1", "hisilicon,hi3660-ufs"; + /* 0: HCI standard */ + /* 1: UFS SYS CTRL */ + reg = <0x0 0xff3b 0x0 0x1000>, + <0x0 0xff3b1000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, + <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; + clock-names = "clk_ref", "clk_phy"; + freq-table-hz = <0 0>, <0 0>; + reset-gpio = <&gpio18 1 0>; + } -- 2.11.0
[PATCH v3 5/5] arm64: defconfig: enable f2fs and squashfs
Partitions in HiKey960 are formatted as f2fs and squashfs. f2fs is for userdata; squashfs is for system. Both partitions are required by Android. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 7514ecf08f2a..61fcabcd7645 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -527,6 +527,7 @@ CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_F2FS_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y @@ -542,6 +543,13 @@ CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -- 2.11.0
[PATCH v3 4/5] arm64: defconfig: enable configs for Hisilicon ufs
This enable configs for Hisilicon Hi UFS driver. Signed-off-by: Li Wei Signed-off-by: Zhangfei Gao Signed-off-by: Guodong Xu --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b4ca115b3be1..7514ecf08f2a 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -164,6 +164,9 @@ CONFIG_EEPROM_AT25=m CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -- 2.11.0
[PATCH v10 2/2] mmc: dw_mmc-k3: add sd support for hi3660
Add sd card support for hi3660 soc Signed-off-by: Li Wei Signed-off-by: Chen Jun --- Major changes in v3: - solve review comments from Heiner Kallweit. *use the GENMASK and FIELD_PREP macros replace the bit shift operation. *use usleep_range() replace udelay() and mdelay(). Major changes in v4: - solve review comments from Jaehoon Chung. *move common register for dwmmc controller to dwmmc header file. *modify definitions type of some register variables. *get rid of the magic numbers. Major changes in v5: - further improve coding style. Major changes in v6: - solve review comments for Jaehoon Chung. *modify dw_mci_hi3660_set_ios() to static. *fix the comment style. Major changes in v7: - solve review comments for John Stultz. *remove reset code in dw_mmc-k3.c,use reset in core mmc. Major changes in v8: - modify patch v7 name and dependency order. Major changes in v9: - solve review comments for Ulf Hansson. *use mmc_regulator_set_vqmmc() instead of regulator_set_voltage(). Major change in v10: - solve review comments for Shawn Lin. *remove PULL_DOWN/UP macro unused. drivers/mmc/host/dw_mmc-k3.c | 298 +++ drivers/mmc/host/dw_mmc.h| 2 + 2 files changed, 300 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..64cda84b2302 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -8,6 +8,8 @@ * (at your option) any later version. */ +#include +#include #include #include #include @@ -28,7 +30,35 @@ #define AO_SCTRL_SEL18 BIT(10) #define AO_SCTRL_CTRL3 0x40C +#define DWMMC_SDIO_ID 2 + +#define SOC_SCTRL_SCPERCTRL5(0x314) +#define SDCARD_IO_SEL18 BIT(2) + +#define SDCARD_RD_THRESHOLD (512) + +#define GENCLK_DIV (7) + +#define GPIO_CLK_ENABLE BIT(16) +#define GPIO_CLK_DIV_MASK GENMASK(11, 8) +#define GPIO_USE_SAMPLE_DLY_MASK GENMASK(13, 13) +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16) +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK GENMASK(25, 21) +#define UHS_REG_EXT_SAMPLE_DLY_MASK GENMASK(30, 26) + +#define TIMING_MODE 3 +#define TIMING_CFG_NUM 10 + +#define NUM_PHASES (40) + +#define ENABLE_SHIFT_MIN_SMPL (4) +#define ENABLE_SHIFT_MAX_SMPL (12) +#define USE_DLY_MIN_SMPL (11) +#define USE_DLY_MAX_SMPL (14) + struct k3_priv { + int ctrl_id; + u32 cur_speed; struct regmap *reg; }; @@ -38,6 +68,41 @@ static unsigned long dw_mci_hi6220_caps[] = { 0 }; +struct hs_timing { + u32 drv_phase; + u32 smpl_dly; + u32 smpl_phase_max; + u32 smpl_phase_min; +}; + +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { + { /* reserved */ }, + { /* SD */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {6, 0, 4, 4,}, /* 1: MMC_HS */ + {6, 0, 3, 3,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 2, 2,}, /* 4: SDR25 */ + {4, 0, 11, 0,}, /* 5: SDR50 */ + {6, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + }, + { /* SDIO */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {0}, /* 1: MMC_HS */ + {6, 0, 15, 15,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 0, 0,}, /* 4: SDR25 */ + {4, 0, 12, 0,}, /* 5: SDR50 */ + {5, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + } +}; + static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) { int ret; @@ -66,6 +131,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host) if (IS_ERR(priv->reg)) priv->reg = NULL; + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); + if (priv->ctrl_id < 0) + priv->ctrl_id = 0; + host->priv = priv; return 0; } @@ -144,7 +213,236 @@ static const struct dw_mci_drv_data hi6220_data = { .execute_tuning = dw_mci_hi6220_execute_tuning, }; +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, +int smpl_phase) +{ + u32 drv_phase; + u32 smpl_dly; + u32 use_smpl_dly = 0; + u32 enable_shift = 0; + u32 reg_value; + int ctrl_id; + struct k3_priv *priv; + + priv = host->priv; + ctrl_id = priv->ctrl_id; + + drv_phase = hs_timing_cfg[ctrl_id][timing].drv_phase; + smpl_dly = hs_timing_cfg[ctrl_id][timing].smpl_dly; + if (s
[PATCH v10 1/2] mmc: dw_mmc: move controller reset before driver init
This commit modifies dw_mci_probe(), it moves reset assertion before drv_data->init(host) Some driver needs to access controller registers in its .init() ops. So, in order to make such access safe, we should do controller reset before .init() being called. Signed-off-by: Wei Li Signed-off-by: Guodong Xu Signed-off-by: Chen Jun --- drivers/mmc/host/dw_mmc.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a9dfb26972f2..f2fa928e1a12 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3067,6 +3067,12 @@ int dw_mci_probe(struct dw_mci *host) goto err_clk_ciu; } + if (!IS_ERR(host->pdata->rstc)) { + reset_control_assert(host->pdata->rstc); + usleep_range(10, 50); + reset_control_deassert(host->pdata->rstc); + } + if (drv_data && drv_data->init) { ret = drv_data->init(host); if (ret) { @@ -3076,12 +3082,6 @@ int dw_mci_probe(struct dw_mci *host) } } - if (!IS_ERR(host->pdata->rstc)) { - reset_control_assert(host->pdata->rstc); - usleep_range(10, 50); - reset_control_deassert(host->pdata->rstc); - } - setup_timer(&host->cmd11_timer, dw_mci_cmd11_timer, (unsigned long)host); -- 2.11.0
[PATCH v9 1/2] mmc: dw_mmc: move controller reset before driver init
This commit modifies dw_mci_probe(), it moves reset assertion before drv_data->init(host) Some driver needs to access controller registers in its .init() ops. So, in order to make such access safe, we should do controller reset before .init() being called. Signed-off-by: Wei Li Signed-off-by: Guodong Xu Signed-off-by: Chen Jun --- drivers/mmc/host/dw_mmc.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a9dfb26972f2..f2fa928e1a12 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3067,6 +3067,12 @@ int dw_mci_probe(struct dw_mci *host) goto err_clk_ciu; } + if (!IS_ERR(host->pdata->rstc)) { + reset_control_assert(host->pdata->rstc); + usleep_range(10, 50); + reset_control_deassert(host->pdata->rstc); + } + if (drv_data && drv_data->init) { ret = drv_data->init(host); if (ret) { @@ -3076,12 +3082,6 @@ int dw_mci_probe(struct dw_mci *host) } } - if (!IS_ERR(host->pdata->rstc)) { - reset_control_assert(host->pdata->rstc); - usleep_range(10, 50); - reset_control_deassert(host->pdata->rstc); - } - setup_timer(&host->cmd11_timer, dw_mci_cmd11_timer, (unsigned long)host); -- 2.11.0
[PATCH v9 2/2] mmc: dw_mmc-k3: add sd support for hi3660
Add sd card support for hi3660 soc Signed-off-by: Li Wei Signed-off-by: Chen Jun -- Major changes in v3: - solve review comments from Heiner Kallweit. *use the GENMASK and FIELD_PREP macros replace the bit shift operation. *use usleep_range() replace udelay() and mdelay(). Major changes in v4: - solve review comments from Jaehoon Chung. *move common register for dwmmc controller to dwmmc header file. *modify definitions type of some register variables. *get rid of the magic numbers. Major changes in v5: - further improve coding style. Major changes in v6: - solve review comments for Jaehoon Chung. *modify dw_mci_hi3660_set_ios() to static. *fix the comment style. Major changes in v7: - solve review comments for John Stultz. *remove reset code in dw_mmc-k3.c,use reset in core mmc. Major changes in v8: - modify patch v7 name and dependency order. Major changes in v9: - solve review comments for Ulf Hansson. *use mmc_regulator_set_vqmmc() instead of regulator_set_voltage(). --- drivers/mmc/host/dw_mmc-k3.c | 301 +++ drivers/mmc/host/dw_mmc.h| 2 + 2 files changed, 303 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..f6910bed55ef 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -8,6 +8,8 @@ * (at your option) any later version. */ +#include +#include #include #include #include @@ -28,7 +30,38 @@ #define AO_SCTRL_SEL18 BIT(10) #define AO_SCTRL_CTRL3 0x40C +#define DWMMC_SDIO_ID 2 + +#define SOC_SCTRL_SCPERCTRL5(0x314) +#define SDCARD_IO_SEL18 BIT(2) + +#define SDCARD_RD_THRESHOLD (512) + +#define GENCLK_DIV (7) + +#define GPIO_CLK_ENABLE BIT(16) +#define GPIO_CLK_DIV_MASK GENMASK(11, 8) +#define GPIO_USE_SAMPLE_DLY_MASK GENMASK(13, 13) +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16) +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK GENMASK(25, 21) +#define UHS_REG_EXT_SAMPLE_DLY_MASK GENMASK(30, 26) + +#define TIMING_MODE 3 +#define TIMING_CFG_NUM 10 + +#define PULL_DOWN BIT(1) +#define PULL_UP BIT(0) + +#define NUM_PHASES (40) + +#define ENABLE_SHIFT_MIN_SMPL (4) +#define ENABLE_SHIFT_MAX_SMPL (12) +#define USE_DLY_MIN_SMPL (11) +#define USE_DLY_MAX_SMPL (14) + struct k3_priv { + int ctrl_id; + u32 cur_speed; struct regmap *reg; }; @@ -38,6 +71,41 @@ static unsigned long dw_mci_hi6220_caps[] = { 0 }; +struct hs_timing { + u32 drv_phase; + u32 smpl_dly; + u32 smpl_phase_max; + u32 smpl_phase_min; +}; + +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { + { /* reserved */ }, + { /* SD */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {6, 0, 4, 4,}, /* 1: MMC_HS */ + {6, 0, 3, 3,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 2, 2,}, /* 4: SDR25 */ + {4, 0, 11, 0,}, /* 5: SDR50 */ + {6, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + }, + { /* SDIO */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {0}, /* 1: MMC_HS */ + {6, 0, 15, 15,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 0, 0,}, /* 4: SDR25 */ + {4, 0, 12, 0,}, /* 5: SDR50 */ + {5, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + } +}; + static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) { int ret; @@ -66,6 +134,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host) if (IS_ERR(priv->reg)) priv->reg = NULL; + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); + if (priv->ctrl_id < 0) + priv->ctrl_id = 0; + host->priv = priv; return 0; } @@ -144,7 +216,236 @@ static const struct dw_mci_drv_data hi6220_data = { .execute_tuning = dw_mci_hi6220_execute_tuning, }; +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, +int smpl_phase) +{ + u32 drv_phase; + u32 smpl_dly; + u32 use_smpl_dly = 0; + u32 enable_shift = 0; + u32 reg_value; + int ctrl_id; + struct k3_priv *priv; + + priv = host->priv; + ctrl_id = priv->ctrl_id; + + drv_phase = hs_timing_cfg[ctrl_id][timing].drv_phase; + smpl_dly = hs_timing_cfg[ctrl_id][tim
[PATCH v8 2/2] mmc: dw_mmc-k3: add sd support for hi3660
Add sd card support for hi3660 soc Signed-off-by: Li Wei Signed-off-by: Chen Jun Major changes in v3: - solve review comments from Heiner Kallweit. *use the GENMASK and FIELD_PREP macros replace the bit shift operation. *use usleep_range() replace udelay() and mdelay(). Major changes in v4: - solve review comments from Jaehoon Chung. *move common register for dwmmc controller to dwmmc header file. *modify definitions type of some register variables. *get rid of the magic numbers. Major changes in v5: - further improve coding style. Major changes in v6: - solve review comments for Jaehoon Chung. *modify dw_mci_hi3660_set_ios() to static. *fix the comment style. Major changes in v7: - solve review comments for John Stultz. *remove reset code in dw_mmc-k3.c,use reset in core mmc. Major changes in v8: - modify patch v7 name and dependency order. --- drivers/mmc/host/dw_mmc-k3.c | 311 +++ drivers/mmc/host/dw_mmc.h| 2 + 2 files changed, 313 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..efe18bf445ff 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -8,6 +8,8 @@ * (at your option) any later version. */ +#include +#include #include #include #include @@ -28,7 +30,38 @@ #define AO_SCTRL_SEL18 BIT(10) #define AO_SCTRL_CTRL3 0x40C +#define DWMMC_SDIO_ID 2 + +#define SOC_SCTRL_SCPERCTRL5(0x314) +#define SDCARD_IO_SEL18 BIT(2) + +#define SDCARD_RD_THRESHOLD (512) + +#define GENCLK_DIV (7) + +#define GPIO_CLK_ENABLE BIT(16) +#define GPIO_CLK_DIV_MASK GENMASK(11, 8) +#define GPIO_USE_SAMPLE_DLY_MASK GENMASK(13, 13) +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16) +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK GENMASK(25, 21) +#define UHS_REG_EXT_SAMPLE_DLY_MASK GENMASK(30, 26) + +#define TIMING_MODE 3 +#define TIMING_CFG_NUM 10 + +#define PULL_DOWN BIT(1) +#define PULL_UP BIT(0) + +#define NUM_PHASES (40) + +#define ENABLE_SHIFT_MIN_SMPL (4) +#define ENABLE_SHIFT_MAX_SMPL (12) +#define USE_DLY_MIN_SMPL (11) +#define USE_DLY_MAX_SMPL (14) + struct k3_priv { + int ctrl_id; + u32 cur_speed; struct regmap *reg; }; @@ -38,6 +71,41 @@ static unsigned long dw_mci_hi6220_caps[] = { 0 }; +struct hs_timing { + u32 drv_phase; + u32 smpl_dly; + u32 smpl_phase_max; + u32 smpl_phase_min; +}; + +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { + { /* reserved */ }, + { /* SD */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {6, 0, 4, 4,}, /* 1: MMC_HS */ + {6, 0, 3, 3,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 2, 2,}, /* 4: SDR25 */ + {4, 0, 11, 0,}, /* 5: SDR50 */ + {6, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + }, + { /* SDIO */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {0}, /* 1: MMC_HS */ + {6, 0, 15, 15,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 0, 0,}, /* 4: SDR25 */ + {4, 0, 12, 0,}, /* 5: SDR50 */ + {5, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + } +}; + static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) { int ret; @@ -66,6 +134,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host) if (IS_ERR(priv->reg)) priv->reg = NULL; + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); + if (priv->ctrl_id < 0) + priv->ctrl_id = 0; + host->priv = priv; return 0; } @@ -144,7 +216,246 @@ static const struct dw_mci_drv_data hi6220_data = { .execute_tuning = dw_mci_hi6220_execute_tuning, }; +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, +int smpl_phase) +{ + u32 drv_phase; + u32 smpl_dly; + u32 use_smpl_dly = 0; + u32 enable_shift = 0; + u32 reg_value; + int ctrl_id; + struct k3_priv *priv; + + priv = host->priv; + ctrl_id = priv->ctrl_id; + + drv_phase = hs_timing_cfg[ctrl_id][timing].drv_phase; + smpl_dly = hs_timing_cfg[ctrl_id][timing].smpl_dly; + if (smpl_phase == -1) + smpl_phase = (hs_timing_cfg[ctrl_id][timing].smpl_phase_max + +hs_timing_cfg[ctrl_id][timing].smpl_phase_min) /
[PATCH v8 1/2] mmc: dw_mmc: move controller reset before driver init
This commit modifies dw_mci_probe(), it moves reset assertion before drv_data->init(host) Some driver needs to access controller registers in its .init() ops. So, in order to make such access safe, we should do controller reset before .init() being called. Signed-off-by: Wei Li Signed-off-by: Guodong Xu Signed-off-by: Chen Jun --- drivers/mmc/host/dw_mmc.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a9dfb26972f2..f2fa928e1a12 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3067,6 +3067,12 @@ int dw_mci_probe(struct dw_mci *host) goto err_clk_ciu; } + if (!IS_ERR(host->pdata->rstc)) { + reset_control_assert(host->pdata->rstc); + usleep_range(10, 50); + reset_control_deassert(host->pdata->rstc); + } + if (drv_data && drv_data->init) { ret = drv_data->init(host); if (ret) { @@ -3076,12 +3082,6 @@ int dw_mci_probe(struct dw_mci *host) } } - if (!IS_ERR(host->pdata->rstc)) { - reset_control_assert(host->pdata->rstc); - usleep_range(10, 50); - reset_control_deassert(host->pdata->rstc); - } - setup_timer(&host->cmd11_timer, dw_mci_cmd11_timer, (unsigned long)host); -- 2.11.0
[PATCH v7 1/3] mmc: dw_mmc-k3: add sd support for hi3660
Add sd card support for hi3660 soc Signed-off-by: Li Wei Signed-off-by: Chen Jun Major changes in v3: - solve review comments from Heiner Kallweit. *use the GENMASK and FIELD_PREP macros replace the bit shift operation. *use usleep_range() replace udelay() and mdelay(). Major changes in v4: - solve review comments from Jaehoon Chung. *move common register for dwmmc controller to dwmmc header file. *modify definitions type of some register variables. *get rid of the magic numbers. Major changes in v5: - further improve coding style. Major changes in v6: - solve review comments for Jaehoon Chung. *modify dw_mci_hi3660_set_ios() to static. *fix the comment style. Major changes in v7: - solve review comments for John Stultz. *remove reset code in dw_mmc-k3.c,use reset in core mmc. --- drivers/mmc/host/dw_mmc-k3.c | 311 +++ drivers/mmc/host/dw_mmc.h| 2 + 2 files changed, 313 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..efe18bf445ff 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -8,6 +8,8 @@ * (at your option) any later version. */ +#include +#include #include #include #include @@ -28,7 +30,38 @@ #define AO_SCTRL_SEL18 BIT(10) #define AO_SCTRL_CTRL3 0x40C +#define DWMMC_SDIO_ID 2 + +#define SOC_SCTRL_SCPERCTRL5(0x314) +#define SDCARD_IO_SEL18 BIT(2) + +#define SDCARD_RD_THRESHOLD (512) + +#define GENCLK_DIV (7) + +#define GPIO_CLK_ENABLE BIT(16) +#define GPIO_CLK_DIV_MASK GENMASK(11, 8) +#define GPIO_USE_SAMPLE_DLY_MASK GENMASK(13, 13) +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16) +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK GENMASK(25, 21) +#define UHS_REG_EXT_SAMPLE_DLY_MASK GENMASK(30, 26) + +#define TIMING_MODE 3 +#define TIMING_CFG_NUM 10 + +#define PULL_DOWN BIT(1) +#define PULL_UP BIT(0) + +#define NUM_PHASES (40) + +#define ENABLE_SHIFT_MIN_SMPL (4) +#define ENABLE_SHIFT_MAX_SMPL (12) +#define USE_DLY_MIN_SMPL (11) +#define USE_DLY_MAX_SMPL (14) + struct k3_priv { + int ctrl_id; + u32 cur_speed; struct regmap *reg; }; @@ -38,6 +71,41 @@ static unsigned long dw_mci_hi6220_caps[] = { 0 }; +struct hs_timing { + u32 drv_phase; + u32 smpl_dly; + u32 smpl_phase_max; + u32 smpl_phase_min; +}; + +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { + { /* reserved */ }, + { /* SD */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {6, 0, 4, 4,}, /* 1: MMC_HS */ + {6, 0, 3, 3,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 2, 2,}, /* 4: SDR25 */ + {4, 0, 11, 0,}, /* 5: SDR50 */ + {6, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + }, + { /* SDIO */ + {7, 0, 15, 15,}, /* 0: LEGACY 400k */ + {0}, /* 1: MMC_HS */ + {6, 0, 15, 15,}, /* 2: SD_HS */ + {6, 0, 15, 15,}, /* 3: SDR12 */ + {6, 0, 0, 0,}, /* 4: SDR25 */ + {4, 0, 12, 0,}, /* 5: SDR50 */ + {5, 4, 15, 0,}, /* 6: SDR104 */ + {0}, /* 7: DDR50 */ + {0}, /* 8: DDR52 */ + {0}, /* 9: HS200 */ + } +}; + static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) { int ret; @@ -66,6 +134,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host) if (IS_ERR(priv->reg)) priv->reg = NULL; + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); + if (priv->ctrl_id < 0) + priv->ctrl_id = 0; + host->priv = priv; return 0; } @@ -144,7 +216,246 @@ static const struct dw_mci_drv_data hi6220_data = { .execute_tuning = dw_mci_hi6220_execute_tuning, }; +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, +int smpl_phase) +{ + u32 drv_phase; + u32 smpl_dly; + u32 use_smpl_dly = 0; + u32 enable_shift = 0; + u32 reg_value; + int ctrl_id; + struct k3_priv *priv; + + priv = host->priv; + ctrl_id = priv->ctrl_id; + + drv_phase = hs_timing_cfg[ctrl_id][timing].drv_phase; + smpl_dly = hs_timing_cfg[ctrl_id][timing].smpl_dly; + if (smpl_phase == -1) + smpl_phase = (hs_timing_cfg[ctrl_id][timing].smpl_phase_max + +hs_timing_cfg[ctrl_id][timing].smpl_phase_min) / 2; + + switch (timing) { + case MMC_TIMING_UHS_SDR104: +
[PATCH v7 2/3] mmc: dw_mmc: move controller reset before driver init op
This commit modifies dw_mci_probe(), it moves reset assertion before drv_data->init(host) Some driver needs to access controller registers in its .init() ops. So, in order to make such access safe, we should do controller reset before .init() being called. Signed-off-by: Wei Li Signed-off-by: Guodong Xu Signed-off-by: Chen Jun --- drivers/mmc/host/dw_mmc.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a9dfb26972f2..f2fa928e1a12 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3067,6 +3067,12 @@ int dw_mci_probe(struct dw_mci *host) goto err_clk_ciu; } + if (!IS_ERR(host->pdata->rstc)) { + reset_control_assert(host->pdata->rstc); + usleep_range(10, 50); + reset_control_deassert(host->pdata->rstc); + } + if (drv_data && drv_data->init) { ret = drv_data->init(host); if (ret) { @@ -3076,12 +3082,6 @@ int dw_mci_probe(struct dw_mci *host) } } - if (!IS_ERR(host->pdata->rstc)) { - reset_control_assert(host->pdata->rstc); - usleep_range(10, 50); - reset_control_deassert(host->pdata->rstc); - } - setup_timer(&host->cmd11_timer, dw_mci_cmd11_timer, (unsigned long)host); -- 2.11.0
Re: [RFC v3 1/7] hashtable: introduce a small and naive hashtable
On 08/07/2012 08:45 AM, Sasha Levin wrote: > This hashtable implementation is using hlist buckets to provide a simple > hashtable to prevent it from getting reimplemented all over the kernel. > > Signed-off-by: Sasha Levin > --- > include/linux/hashtable.h | 82 > + > 1 files changed, 82 insertions(+), 0 deletions(-) > create mode 100644 include/linux/hashtable.h > > diff --git a/include/linux/hashtable.h b/include/linux/hashtable.h > new file mode 100644 > index 000..394652b > --- /dev/null > +++ b/include/linux/hashtable.h > @@ -0,0 +1,82 @@ > +/* > + * Hash table implementation > + * (C) 2012 Sasha Levin > + */ > + > +#ifndef _LINUX_HASHTABLE_H > +#define _LINUX_HASHTABLE_H > + > +#include > +#include > +#include > +#include > + > +#define DEFINE_HASHTABLE(name, bits) \ > + struct hlist_head name[HASH_SIZE(bits)]; > + > +#define HASH_SIZE(bits) (1 << (bits)) > + > +/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit > kernels. */ > +#define hash_min(val, bits) ((sizeof(val)==4)?hash_32((val), > (bits)):hash_long((val), (bits))) > + > +/** > + * hash_init - initialize a hash table > + * @hashtable: hashtable to be initialized > + * @bits: bit count of hashing function > + * > + * Initializes a hash table with 2**bits buckets. > + */ > +static inline void hash_init(struct hlist_head *hashtable, int bits) > +{ > + int i; > + > + for (i = 0; i < HASH_SIZE(bits); i++) > + INIT_HLIST_HEAD(hashtable + i); > +} > + > +/** > + * hash_add - add an object to a hashtable > + * @hashtable: hashtable to add to > + * @bits: bit count used for hashing > + * @node: the &struct hlist_node of the object to be added > + * @key: the key of the object to be added > + */ > +#define hash_add(hashtable, bits, node, key) \ > + hlist_add_head(node, &hashtable[hash_min(key, bits)]); > + > +/** > + * hash_del - remove an object from a hashtable > + * @node: &struct hlist_node of the object to remove > + */ > +static inline void hash_del(struct hlist_node *node) > +{ > + hlist_del_init(node); > +} > + > +/** > + * hash_for_each - iterate over a hashtable > + * @name: hashtable to iterate > + * @bits: bit count of hashing function of the hashtable > + * @bkt: integer to use as bucket loop cursor > + * @node: the &struct list_head to use as a loop cursor for each bucket > + * @obj: the type * to use as a loop cursor for each bucket > + * @member: the name of the hlist_node within the struct > + */ > +#define hash_for_each(name, bits, bkt, node, obj, member)\ > + for (bkt = 0; bkt < HASH_SIZE(bits); bkt++) \ > + hlist_for_each_entry(obj, node, &name[i], member) Where is the 'i' coming from? maybe &name[bkt]? > + > +/** > + * hash_for_each_possible - iterate over all possible objects for a giver key > + * @name: hashtable to iterate > + * @obj: the type * to use as a loop cursor for each bucke > + * @bits: bit count of hashing function of the hashtable > + * @node: the &struct list_head to use as a loop cursor for each bucket > + * @member: the name of the hlist_node within the struct > + * @key: the key of the objects to iterate over > + */ > +#define hash_for_each_possible(name, obj, bits, node, member, key) \ > + hlist_for_each_entry(obj, node, \ > + &name[hash_min(key, bits)], member) > + > +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/