[PATCH] ARM: apq8064: Add pinmux and i2c pinctrl nodes
This patch adds pinmux and i2c pinctrl DT node for IFC6410 board. It also adds necessary DT support for i2c eeprom which is present on IFC6410. Tested on IFC6410 board. Signed-off-by: Kiran Padwal kiran.pad...@smartplayin.com --- arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 29 ++ arch/arm/boot/dts/qcom-apq8064.dtsi| 59 2 files changed, 88 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts index 7c2441d..d52ac3c 100644 --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts @@ -5,6 +5,15 @@ compatible = qcom,apq8064-ifc6410, qcom,apq8064; soc { + pinmux@80 { + i2c1_pins: i2c1_pinmux { + mux { + pins = gpio20, gpio21; + function = gsbi1; + }; + }; + }; + gsbi@1660 { status = ok; qcom,mode = GSBI_PROT_I2C_UART; @@ -12,5 +21,25 @@ status = ok; }; }; + + gsbi1: gsbi@1244 { + qcom,mode = GSBI_PROT_I2C; + status = ok; + + i2c1: i2c@1246 { + status = ok; + + clock-frequency = 20; + + pinctrl-0 = i2c1_pins; + pinctrl-names = default; + + eeprom: eeprom@52 { + compatible = atmel,24c128; + reg = 0x52; + pagesize = 32; + }; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 92bf793..fbebf5c 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -70,6 +70,17 @@ ranges; compatible = simple-bus; + qcom_pinmux: pinmux@80 { + compatible = qcom,apq8064-pinctrl; + reg = 0x80 0x4000; + + gpio-controller; + #gpio-cells = 2; + interrupt-controller; + #interrupt-cells = 2; + interrupts = 0 32 0x4; + }; + intc: interrupt-controller@200 { compatible = qcom,msm-qgic2; interrupt-controller; @@ -133,6 +144,54 @@ regulator; }; + gsbi1: gsbi@1244 { + compatible = qcom,gsbi-v1.0.0; + reg = 0x1244 0x100; + clocks = gcc GSBI1_H_CLK; + clock-names = iface; + #address-cells = 1; + #size-cells = 1; + ranges; + status = disabled; + + i2c@1246 { + compatible = qcom,i2c-qup-v1.1.1; + reg = 0x1246 0x1000; + interrupts = 0 194 0; + + clocks = gcc GSBI1_QUP_CLK, gcc GSBI1_H_CLK; + clock-names = core, iface; + status = disabled; + + #address-cells = 1; + #size-cells = 0; + }; + }; + + gsbi2: gsbi@1248 { + compatible = qcom,gsbi-v1.0.0; + reg = 0x1248 0x100; + clocks = gcc GSBI2_H_CLK; + clock-names = iface; + #address-cells = 1; + #size-cells = 1; + ranges; + status = disabled; + + i2c@124a { + compatible = qcom,i2c-qup-v1.1.1; + reg = 0x124a 0x1000; + interrupts = 0 196 0; + + clocks = gcc GSBI2_QUP_CLK, gcc GSBI2_H_CLK; + clock-names = core, iface; + status = disabled; + + #address-cells = 1; + #size-cells = 0; + }; + }; + gsbi7: gsbi@1660 { status = disabled; compatible = qcom,gsbi-v1.0.0; -- 1.7.9.5 -- To
Re: [PATCH v2 05/10] arm: qcom-msm8974: Add CPU phandles to CPU definitions
On Wednesday 13 August 2014 01:13 AM, Lina Iyer wrote: Add CPU phandle labels for all Krait CPUS. Signed-off-by: Lina Iyer lina.i...@linaro.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 8 1 file changed, 4 insertions(+), 4 deletions(-) Hi Lina, These changes are already done by Stephen's below cpufreq patch whicth adds OPP table for 8974. You might want to sync them up. Author: Stephen Boyd sb...@codeaurora.org Date: Wed Jun 25 05:36:23 2014 +0530 ARM: dts: qcom: Add necessary DT data for Krait cpufreq Add the necessary DT nodes and data so we can probe the cpufreq driver on MSM devices with Krait CPUs. Signed-off-by: Stephen Boyd sb...@codeaurora.org diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi Thanks Pramod -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 02/10] msm: scm: Add SCM warmboot flags for quad core targets.
On Wednesday 13 August 2014 01:13 AM, Lina Iyer wrote: Quad core targets like APQ8074, APQ8064, APQ8084 need SCM support set up warm boot addresses in the Secure Monitor. Extend the SCM flags to support warmboot addresses for seconday cores. Signed-off-by: Lina Iyer lina.i...@linaro.org --- include/soc/qcom/scm-boot.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/soc/qcom/scm-boot.h b/include/soc/qcom/scm-boot.h index 6aabb24..7ae2152 100644 --- a/include/soc/qcom/scm-boot.h +++ b/include/soc/qcom/scm-boot.h @@ -18,6 +18,9 @@ #define SCM_FLAG_COLDBOOT_CPU3 0x20 #define SCM_FLAG_WARMBOOT_CPU0 0x04 #define SCM_FLAG_WARMBOOT_CPU1 0x02 +#define SCM_FLAG_WARMBOOT_CPU2 0x10 +#define SCM_FLAG_WARMBOOT_CPU3 0x40 + An extra line introduced here. int scm_set_boot_addr(phys_addr_t addr, int flags); -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
MSM Camera: 3.10 kernel support for APQ8074?
Hi, I wants to validate OV5640 camera on 3.10 kernel. I don't find any 3.10 tag for APQ8074 in CAF.I've taken 8084 tag(LNX.LA.3.6.1.c2-01500-8084.0), Kernel is booting but Android home screen(GUI) is not up. Ported ov5640 sensor driver, probe is success with reading proper sensor ID. As GUI is not up, I'm trying to capture YUV frames using mm-qcamera-app commandline application. Please clarify me as I don't have any documents Is APQ8084 ISP compatible with APQ8074? Is it possible to validate camera on APQ8074 with 8084 source? Repo: git://codeaurora.org/quic/la/kernel/msm-3.10 Any input is appreciated. ThanksRegards, Alaganraj -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath6kl: Add SDIO device ID for QCA6234X Support
Srinivas Kandagatla srinivas.kandaga...@linaro.org writes: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds device ID 402 to support QCA6234X found in APQ8064 SOC in IFC6410 board. Tested with mainline mmci sdio driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Thanks, applied. -- Kalle Valo -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Wednesday 13 August 2014 01:13 AM, Lina Iyer wrote: Qualcomm chipsets use an separate h/w block to control the logic around the processor cores (cpu and L2). The SPM h/w block regulates power to the cores and controls the power when the core enter low power modes. Each core has its own instance of SPM. The SPM has the following key functions - Configure the h/w dependencies when entering low power modes - Wait for interrupt and wake up on interrupt - Ensure the dependencies are ready before bringing the core out of sleep - Regulating voltage to the core, interfacing with the PMIC. - Optimize power based on runtime recommendations. The driver identifies and configures the SPMs, by reading the nodes and the register values from the devicetree. The SPMs need to be configured to allow the processor to be idled in a low power state. Signed-off-by: Praveen Chidamabram pchid...@codeaurora.org Signed-off-by: Murali Nalajala mnala...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- + snip CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/spm-devices.c b/drivers/soc/qcom/spm-devices.c new file mode 100644 index 000..567e9f9 --- /dev/null +++ b/drivers/soc/qcom/spm-devices.c snip + if (ret) + return ret; + + return dev-cpu_vdd; +} +EXPORT_SYMBOL(msm_spm_get_vdd); + +static void msm_spm_config_q2s(struct msm_spm_device *dev, unsigned int mode) +{ + uint32_t spm_legacy_mode = 0; + uint32_t qchannel_ignore = 0; + uint32_t val = 0; Initialization not needed for val. + + if (!dev-q2s_reg) + return; + + switch (mode) { + case MSM_SPM_MODE_DISABLED: + case MSM_SPM_MODE_CLOCK_GATING: + qchannel_ignore = 1; + spm_legacy_mode = 0; + break; + case MSM_SPM_MODE_RETENTION: + qchannel_ignore = 0; + spm_legacy_mode = 0; + break; + case MSM_SPM_MODE_GDHS: + case MSM_SPM_MODE_POWER_COLLAPSE: + qchannel_ignore = 0; + spm_legacy_mode = 1; + break; + default: + break; + } + + val = spm_legacy_mode 2 | qchannel_ignore 1; + __raw_writel(val, dev-q2s_reg); + mb(); This may need a comment around it. +} + +static int msm_spm_dev_set_low_power_mode(struct msm_spm_device *dev, + unsigned int mode, bool notify_rpm) +{ + uint32_t i; + uint32_t start_addr = 0; + int ret = -EINVAL; + bool pc_mode = false; + + if (!dev-initialized) + return -ENXIO; + + if ((mode == MSM_SPM_MODE_POWER_COLLAPSE) + || (mode == MSM_SPM_MODE_GDHS)) + pc_mode = true; + + if (mode == MSM_SPM_MODE_DISABLED) { + ret = msm_spm_drv_set_spm_enable(dev-reg_data, false); + } else if (!msm_spm_drv_set_spm_enable(dev-reg_data, true)) { + for (i = 0; i dev-num_modes; i++) { + if ((dev-modes[i].mode == mode) + (dev-modes[i].notify_rpm == notify_rpm)) { + start_addr = dev-modes[i].start_addr; + break; + } + } + ret = msm_spm_drv_set_low_power_mode(dev-reg_data, + start_addr, pc_mode); + } + + msm_spm_config_q2s(dev, mode); + + return ret; +} + +static int msm_spm_dev_init(struct msm_spm_device *dev, + struct msm_spm_platform_data *data) +{ + int i, ret = -ENOMEM; + uint32_t offset = 0; + + dev-cpu_vdd = VDD_DEFAULT; + dev-num_modes = data-num_modes; + dev-modes = kmalloc( + sizeof(struct msm_spm_power_modes) * dev-num_modes, + GFP_KERNEL); + + if (!dev-modes) + goto spm_failed_malloc; + + dev-reg_data.major = data-major; + dev-reg_data.minor = data-minor; + ret = msm_spm_drv_init(dev-reg_data, data); + Please remove extra line. + if (ret) + goto spm_failed_init; + + for (i = 0; i dev-num_modes; i++) { + + /* Default offset is 0 and gets updated as we write more + * sequences into SPM + */ + dev-modes[i].start_addr = offset; + ret = msm_spm_drv_write_seq_data(dev-reg_data, + data-modes[i].cmd, offset); + if (ret 0) + goto spm_failed_init; + + dev-modes[i].mode = data-modes[i].mode; + dev-modes[i].notify_rpm = data-modes[i].notify_rpm; + } + msm_spm_drv_reinit(dev-reg_data); + dev-initialized = true; + return 0; + +spm_failed_init: + kfree(dev-modes); Should not we
[PATCH/RFC V2 01/16] scsi: ufs: Allow vendor specific initialization
From: Sujit Reddy Thumma sthu...@codeaurora.org Some vendor specific controller versions might need to configure vendor specific - registers, clocks, voltage regulators etc. to initialize the host controller UTP layer and Uni-Pro stack. Provide some common initialization operations that can be used to configure vendor specifics. The methods can be extended in future, for example, for power mode transitions. The operations are vendor/board specific and hence determined with the help of compatible property in device tree. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index c007a7a..11a3237 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -164,7 +164,13 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mmio_base = pcim_iomap_table(pdev)[0]; - err = ufshcd_init(pdev-dev, hba, mmio_base, pdev-irq); + err = ufshcd_alloc_host(pdev-dev, hba); + if (err) { + dev_err(pdev-dev, Allocation failed\n); + return err; + } + + err = ufshcd_init(hba, mmio_base, pdev-irq); if (err) { dev_err(pdev-dev, Initialization failed\n); return err; diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 5e46232..d727b1a 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -35,9 +35,24 @@ #include linux/platform_device.h #include linux/pm_runtime.h +#include linux/of.h #include ufshcd.h +static const struct of_device_id ufs_of_match[]; +static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) +{ + if (dev-of_node) { + const struct of_device_id *match; + + match = of_match_node(ufs_of_match, dev-of_node); + if (match) + return (struct ufs_hba_variant_ops *)match-data; + } + + return NULL; +} + #ifdef CONFIG_PM /** * ufshcd_pltfrm_suspend - suspend power management function @@ -138,8 +153,8 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mmio_base = devm_ioremap_resource(dev, mem_res); - if (IS_ERR(mmio_base)) { - err = PTR_ERR(mmio_base); + if (IS_ERR(*(void **)mmio_base)) { + err = PTR_ERR(*(void **)mmio_base); goto out; } @@ -150,10 +165,18 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) goto out; } + err = ufshcd_alloc_host(dev, hba); + if (err) { + dev_err(pdev-dev, Allocation failed\n); + goto out; + } + + hba-vops = get_variant_ops(pdev-dev); + pm_runtime_set_active(pdev-dev); pm_runtime_enable(pdev-dev); - err = ufshcd_init(dev, hba, mmio_base, irq); + err = ufshcd_init(hba, mmio_base, irq); if (err) { dev_err(dev, Intialization failed\n); goto out_disable_rpm; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ba27215..d0565b0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3,6 +3,7 @@ * * This code is based on drivers/scsi/ufs/ufshcd.c * Copyright (C) 2011-2013 Samsung India Software Operations + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * Authors: * Santosh Yaraganavi santosh...@samsung.com @@ -31,6 +32,9 @@ * circumstances will the contributor of this Program be liable for * any damages of any kind arising from your use or distribution of * this program. + * + * The Linux Foundation chooses to take subject only to the GPLv2 + * license terms, and distributes only under these terms. */ #include linux/async.h @@ -175,13 +179,14 @@ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) /** * ufshcd_is_device_present - Check if any device connected to * the host controller - * @reg_hcs - host controller status register value + * @hba: pointer to adapter instance * * Returns 1 if device present, 0 if no device detected */ -static inline int ufshcd_is_device_present(u32 reg_hcs) +static inline int ufshcd_is_device_present(struct ufs_hba *hba) { - return (DEVICE_PRESENT reg_hcs) ? 1 : 0; + return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) + DEVICE_PRESENT) ? 1 : 0; } /** @@ -1798,11 +1803,10 @@ out: * @hba: per adapter instance * * To bring UFS host controller to operational state, - * 1. Check if device is present - * 2. Enable required interrupts - * 3. Configure interrupt aggregation - * 4. Program UTRL and UTMRL base addres - * 5. Configure run-stop-registers + * 1. Enable required interrupts + * 2. Configure interrupt
[PATCH/RFC V2 00/16] UFS: Power managment support
This patch seies introduces support for power managment in the driver as well as vendor specific initialization - registers, clocks, voltage regulators etc. It includes also a rework for the init sequnce and other PM pre-requisit such as write protection support, handling well-known LUN, error handling (retries), bkops, START_STOP unit command, and ICC levels settings. -- Changes from V1: - 6 new patches apended at the end - Allow overriding power configuration with controller support and preferences/capabilities Dolev Raviv - Allow overriding power choice with controller capabilities Dolev Raviv - Add support for clock gating and clock scaling Sahitya Tummala - Add capability to control the auto bkops during suspend Subhash Jadavani - Add misc changes for phy/unipro driver usage Dolev Raviv Dolev Raviv (2): scsi: ufs: refactor configuring power mode scsi: ufs: definitions for phy interface Sahitya Tummala (3): scsi: ufs: Add support for clock gating scsi: ufs: Add freq-table-hz property for UFS device scsi: ufs: Add support for clock scaling using devfreq framework Subhash Jadavani (5): scsi: ufs: refactor query descriptor API support scsi: support well known logical units scsi: ufs: introduce well known logical unit in ufs scsi: ufs: add UFS power management support scsi: ufs: add capability to control the auto bkops during suspend Sujit Reddy Thumma (5): scsi: ufs: Allow vendor specific initialization scsi: ufs: Add regulator enable support scsi: ufs: Add clock initialization support scsi: ufs: improve init sequence scsi: sd: Avoid sending medium write commands if device is write protected Yaniv Gardi (1): scsi: ufs: Active Power Mode - configuring bActiveICCLevel .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 37 + drivers/scsi/scsi_scan.c | 16 + drivers/scsi/scsi_sysfs.c |7 + drivers/scsi/sd.c |6 +- drivers/scsi/ufs/Kconfig |2 + drivers/scsi/ufs/ufs.h | 131 +- drivers/scsi/ufs/ufshcd-pci.c | 55 +- drivers/scsi/ufs/ufshcd-pltfrm.c | 282 ++- drivers/scsi/ufs/ufshcd.c | 2400 ++-- drivers/scsi/ufs/ufshcd.h | 277 ++- drivers/scsi/ufs/ufshci.h |9 +- drivers/scsi/ufs/unipro.h | 56 + include/scsi/scsi.h|1 + include/scsi/scsi_host.h |5 + 14 files changed, 2959 insertions(+), 325 deletions(-) -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC V2 02/16] scsi: ufs: Add regulator enable support
From: Sujit Reddy Thumma sthu...@codeaurora.org UFS devices are powered by at most three external power supplies - - VCC - The flash memory core power supply, 2.7V to 3.6V or 1.70V to 1.95V - VCCQ - The controller and I/O power supply, 1.1V to 1.3V - VCCQ2 - Secondary controller and/or I/O power supply, 1.65V to 1.95V For some devices VCCQ or VCCQ2 are optional as they can be generated using internal LDO inside the UFS device. Add DT bindings for voltage regulators that can be controlled from host driver. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 20468b2..65e3117 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -8,9 +8,33 @@ Required properties: - interrupts: interrupt mapping for UFS host controller IRQ - reg : registers mapping +Optional properties: +- vcc-supply: phandle to VCC supply regulator node +- vccq-supply : phandle to VCCQ supply regulator node +- vccq2-supply : phandle to VCCQ2 supply regulator node +- vcc-supply-1p8: For embedded UFS devices, valid VCC range is 1.7-1.95V + or 2.7-3.6V. This boolean property when set, specifies + to use low voltage range of 1.7-1.95V. Note for external + UFS cards this property is invalid and valid VCC range is + always 2.7-3.6V. +- vcc-max-microamp : specifies max. load that can be drawn from vcc supply +- vccq-max-microamp : specifies max. load that can be drawn from vccq supply +- vccq2-max-microamp: specifies max. load that can be drawn from vccq2 supply + +Note: If above properties are not defined it can be assumed that the supply +regulators are always on. + Example: ufshc@0xfc598000 { compatible = jedec,ufs-1.1; reg = 0xfc598000 0x800; interrupts = 0 28 0; + + vcc-supply = xxx_reg1; + vcc-supply-1p8; + vccq-supply = xxx_reg2; + vccq2-supply = xxx_reg3; + vcc-max-microamp = 50; + vccq-max-microamp = 20; + vccq2-max-microamp = 20; }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index fafcf5e..729ce7d 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -362,4 +362,29 @@ struct ufs_query_res { struct utp_upiu_query upiu_res; }; +#define UFS_VREG_VCC_MIN_UV 270 /* uV */ +#define UFS_VREG_VCC_MAX_UV 360 /* uV */ +#define UFS_VREG_VCC_1P8_MIN_UV170 /* uV */ +#define UFS_VREG_VCC_1P8_MAX_UV195 /* uV */ +#define UFS_VREG_VCCQ_MIN_UV 110 /* uV */ +#define UFS_VREG_VCCQ_MAX_UV 130 /* uV */ +#define UFS_VREG_VCCQ2_MIN_UV 165 /* uV */ +#define UFS_VREG_VCCQ2_MAX_UV 195 /* uV */ + +struct ufs_vreg { + struct regulator *reg; + const char *name; + bool enabled; + int min_uV; + int max_uV; + int min_uA; + int max_uA; +}; + +struct ufs_vreg_info { + struct ufs_vreg *vcc; + struct ufs_vreg *vccq; + struct ufs_vreg *vccq2; +}; + #endif /* End of Header */ diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index d727b1a..51e47c4 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -53,6 +53,99 @@ static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) return NULL; } +#define MAX_PROP_SIZE 32 +static int ufshcd_populate_vreg(struct device *dev, const char *name, + struct ufs_vreg **out_vreg) +{ + int ret = 0; + char prop_name[MAX_PROP_SIZE]; + struct ufs_vreg *vreg = NULL; + struct device_node *np = dev-of_node; + + if (!np) { + dev_err(dev, %s: non DT initialization\n, __func__); + goto out; + } + + snprintf(prop_name, MAX_PROP_SIZE, %s-supply, name); + if (!of_parse_phandle(np, prop_name, 0)) { + dev_info(dev, %s: Unable to find %s regulator, assuming enabled\n, + __func__, prop_name); + goto out; + } + + vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); + if (!vreg) { + dev_err(dev, No memory for %s regulator\n, name); + goto out; + } + + vreg-name = kstrdup(name, GFP_KERNEL); + + snprintf(prop_name, MAX_PROP_SIZE, %s-max-microamp, name); + ret = of_property_read_u32(np, prop_name, vreg-max_uA); + if (ret) { + dev_err(dev, %s: unable to find %s err %d\n, + __func__, prop_name, ret); + goto
[PATCH/RFC V2 03/16] scsi: ufs: Add clock initialization support
From: Sujit Reddy Thumma sthu...@codeaurora.org Add generic clock initialization support for UFSHCD platform driver. The clock info is read from device tree using standard clock bindings. A generic max-clock-frequency-hz property is defined to save information on maximum operating clock frequency the h/w supports. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 65e3117..b0f791a 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -21,8 +21,17 @@ Optional properties: - vccq-max-microamp : specifies max. load that can be drawn from vccq supply - vccq2-max-microamp: specifies max. load that can be drawn from vccq2 supply +- 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. +- max-clock-frequency-hz : List of maximum operating frequency 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. + Note: If above properties are not defined it can be assumed that the supply -regulators are always on. +regulators or clocks are always on. Example: ufshc@0xfc598000 { @@ -37,4 +46,8 @@ Example: vcc-max-microamp = 50; vccq-max-microamp = 20; vccq2-max-microamp = 20; + + clocks = core 0, ref 0, iface 0; + clock-names = core_clk, ref_clk, iface_clk; + max-clock-frequency-hz = 1 1920 0; }; diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index 11a3237..1aac2ef 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -170,6 +170,8 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } + INIT_LIST_HEAD(hba-clk_list_head); + err = ufshcd_init(hba, mmio_base, pdev-irq); if (err) { dev_err(pdev-dev, Initialization failed\n); diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 51e47c4..642d80f 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -53,6 +53,71 @@ static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) return NULL; } +static int ufshcd_parse_clock_info(struct ufs_hba *hba) +{ + int ret = 0; + int cnt; + int i; + struct device *dev = hba-dev; + struct device_node *np = dev-of_node; + char *name; + u32 *clkfreq = NULL; + struct ufs_clk_info *clki; + + if (!np) + goto out; + + INIT_LIST_HEAD(hba-clk_list_head); + + cnt = of_property_count_strings(np, clock-names); + if (!cnt || (cnt == -EINVAL)) { + dev_info(dev, %s: Unable to find clocks, assuming enabled\n, + __func__); + } else if (cnt 0) { + dev_err(dev, %s: count clock strings failed, err %d\n, + __func__, cnt); + ret = cnt; + } + + if (cnt = 0) + goto out; + + clkfreq = kzalloc(cnt * sizeof(*clkfreq), GFP_KERNEL); + if (!clkfreq) { + ret = -ENOMEM; + dev_err(dev, %s: memory alloc failed\n, __func__); + goto out; + } + + ret = of_property_read_u32_array(np, + max-clock-frequency-hz, clkfreq, cnt); + if (ret (ret != -EINVAL)) { + dev_err(dev, %s: invalid max-clock-frequency-hz property, %d\n, + __func__, ret); + goto out; + } + + for (i = 0; i cnt; i++) { + ret = of_property_read_string_index(np, + clock-names, i, (const char **)name); + if (ret) + goto out; + + clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); + if (!clki) { + ret = -ENOMEM; + goto out; + } + + clki-max_freq = clkfreq[i]; + clki-name = kstrdup(name, GFP_KERNEL); + list_add_tail(clki-list, hba-clk_list_head); + } +out: + kfree(clkfreq); + return ret; +} + #define MAX_PROP_SIZE 32 static int ufshcd_populate_vreg(struct device *dev, const char *name, struct ufs_vreg **out_vreg) @@ -266,6 +331,12 @@ static int
[PATCH/RFC V2 11/16] scsi: ufs: refactor configuring power mode
Sometimes, the device shall report its maximum power and speed capabilities, but we might not wish to configure it to use those maximum capabilities. This change adds support for the vendor specific host driver to implement power change notify callback. To enable configuring different power modes (number of lanes, gear number and fast/slow modes) it is necessary to split the configuration stage from the stage that reads the device max power mode. In addition, it is not required to read the configuration more than once, thus the configuration is stored after reading it once. Signed-off-by: Dolev Raviv dra...@codeaurora.org Signed-off-by: Yaniv Gardi yga...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index fac71c9..3a66d0d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -178,6 +178,8 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); +static int ufshcd_config_pwr_mode(struct ufs_hba *hba, + struct ufs_pa_layer_attr *desired_pwr_mode); static inline void ufshcd_enable_irq(struct ufs_hba *hba) { @@ -1933,65 +1935,129 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) } /** - * ufshcd_config_max_pwr_mode - Set Change power mode with - * maximum capability attribute information. - * @hba: per adapter instance - * - * Returns 0 on success, non-zero value on failure + * ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device + * @hba: per-adapter instance */ -static int ufshcd_config_max_pwr_mode(struct ufs_hba *hba) +static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba) { - enum {RX = 0, TX = 1}; - u32 lanes[] = {1, 1}; - u32 gear[] = {1, 1}; - u8 pwr[] = {FASTAUTO_MODE, FASTAUTO_MODE}; - int ret; + struct ufs_pa_layer_attr *pwr_info = hba-max_pwr_info.info; + + if (hba-max_pwr_info.is_valid) + return 0; + + pwr_info-pwr_tx = FASTAUTO_MODE; + pwr_info-pwr_rx = FASTAUTO_MODE; + pwr_info-hs_rate = PA_HS_MODE_B; /* Get the connected lane count */ - ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), lanes[RX]); - ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), lanes[TX]); + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), + pwr_info-lane_rx); + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), + pwr_info-lane_tx); + + if (!pwr_info-lane_rx || !pwr_info-lane_tx) { + dev_err(hba-dev, %s: invalid connected lanes value. rx=%d, tx=%d\n, + __func__, + pwr_info-lane_rx, + pwr_info-lane_tx); + return -EINVAL; + } /* * First, get the maximum gears of HS speed. * If a zero value, it means there is no HSGEAR capability. * Then, get the maximum gears of PWM speed. */ - ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), gear[RX]); - if (!gear[RX]) { - ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR), gear[RX]); - pwr[RX] = SLOWAUTO_MODE; + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), pwr_info-gear_rx); + if (!pwr_info-gear_rx) { + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR), + pwr_info-gear_rx); + if (!pwr_info-gear_rx) { + dev_err(hba-dev, %s: invalid max pwm rx gear read = %d\n, + __func__, pwr_info-gear_rx); + return -EINVAL; + } + pwr_info-pwr_rx = SLOWAUTO_MODE; } - ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), gear[TX]); - if (!gear[TX]) { + ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXHSGEAR), + pwr_info-gear_tx); + if (!pwr_info-gear_tx) { ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_MAXRXPWMGEAR), - gear[TX]); - pwr[TX] = SLOWAUTO_MODE; + pwr_info-gear_tx); + if (!pwr_info-gear_tx) { + dev_err(hba-dev, %s: invalid max pwm tx gear read = %d\n, + __func__, pwr_info-gear_tx); + return -EINVAL; + } + pwr_info-pwr_tx = SLOWAUTO_MODE; } + hba-max_pwr_info.is_valid = true; + return 0; +} + +/** + * ufshcd_config_pwr_mode - configure a new power mode + * @hba: per-adapter instance + * @desired_pwr_mode: desired power configuration + */ +static int ufshcd_config_pwr_mode(struct ufs_hba *hba, + struct ufs_pa_layer_attr *desired_pwr_mode) +{ + struct
[PATCH/RFC V2 07/16] scsi: support well known logical units
From: Subhash Jadavani subha...@codeaurora.org REPORT LUNS command has SELECT REPORT field which controls what type of logical units to be reported by device server. According to UFS device standard, if this field is set to 0, REPORT LUNS would report only report standard logical units. If it's set to 1 then it would report only well known logical unit and if it's set to 2 then device would report both standard and well known logical units. Some well-known logical units might not have scsi upper-layer drivers. In such cases, the runtime PM reference count increased during device enumeration will not be decreased, causing the parent device (host) to always be on even during idle. This change allows the SCSI LLD (Low Level Driver) to choose which type of logical units should be detected. Signed-off-by: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 4a6e4ba..5a0e164 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -802,6 +802,14 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, } else { sdev-type = (inq_result[0] 0x1f); sdev-removable = (inq_result[1] 0x80) 7; + + /* +* some devices may respond with wrong type for +* well-known logical units. Force well-known type +* to enumerate them correctly. +*/ + if (scsi_is_wlun(sdev-lun) (sdev-type != TYPE_WLUN)) + sdev-type = TYPE_WLUN; } switch (sdev-type) { @@ -817,6 +825,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, case TYPE_COMM: case TYPE_RAID: case TYPE_OSD: + case TYPE_WLUN: sdev-writeable = 1; break; case TYPE_ROM: @@ -1412,6 +1421,13 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, */ memset(scsi_cmd[1], 0, 5); + if (shost-report_wlus) + /* +* Set SELECT REPORT field to 0x2 which will make device to +* report well known logical units along with standard LUs. +*/ + scsi_cmd[2] = 0x2; + /* * bytes 6 - 9: length of the command. */ diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 5f36788..ba9d0f0 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1060,6 +1060,13 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } } + /* +* put runtime pm reference for well-known logical units, +* drivers are expected to _get_* again during probe. +*/ + if (scsi_is_wlun(sdev-lun)) + scsi_autopm_put_device(sdev); + return error; } diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 91e2e42..6a9b102 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -332,6 +332,7 @@ static inline int scsi_status_is_good(int status) #define TYPE_ENCLOSURE 0x0d/* Enclosure Services Device */ #define TYPE_RBC 0x0e #define TYPE_OSD0x11 +#define TYPE_WLUN 0x1e/* well-known logical unit */ #define TYPE_NO_LUN 0x7f /* SCSI protocols; these are taken from SPC-3 section 7.5 */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index b2bc519..05664c4 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -675,6 +675,11 @@ struct Scsi_Host { unsigned no_write_same:1; /* +* Set SELECT REPORT field to allow detection of well known logical +* units along with standard LUs. +*/ + unsigned report_wlus:1; + /* * Optional work queue to be utilized by the transport */ char work_q_name[20]; -- 1.8.5.2 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC V2 06/16] scsi: ufs: Active Power Mode - configuring bActiveICCLevel
From: Yaniv Gardi yga...@codeaurora.org The maximum power consumption in active is determined by bActiveICCLevel. The configuration is done by reading max current supported by the regulators connected to VCC, VCCQ and VCCQ2 rails on the boards, and reading the current consumption levels from the device for each rails (vcc/vccq/vccq2) using power descriptor. We configure the bActiveICCLevel attribute, with the max value that correspond to the minimum-of(VCC-current-level,VCCQ-current-level, VCCQ2-current-level). In order to minimize resume latency, pre-fetch icc levels and reference clock during initialization and avoid reading them each link startup during resume. Signed-off-by: Raviv Shvili rshv...@codeaurora.org Signed-off-by: Yaniv Gardi yga...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 7ea8e71..b0e1f62 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -115,6 +115,7 @@ enum flag_idn { /* Attribute idn for Query requests */ enum attr_idn { + QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, QUERY_ATTR_IDN_EE_CONTROL = 0x0D, QUERY_ATTR_IDN_EE_STATUS= 0x0E, @@ -174,6 +175,31 @@ enum unit_desc_param { UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22, }; +/* bActiveICCLevel parameter current units */ +enum { + UFSHCD_NANO_AMP = 0, + UFSHCD_MICRO_AMP= 1, + UFSHCD_MILI_AMP = 2, + UFSHCD_AMP = 3, +}; + +#define POWER_DESC_MAX_SIZE0x62 +#define POWER_DESC_MAX_ACTV_ICC_LVLS 16 + +/* Attribute bActiveICCLevel parameter bit masks definitions */ +#define ATTR_ICC_LVL_UNIT_OFFSET 14 +#define ATTR_ICC_LVL_UNIT_MASK (0x3 ATTR_ICC_LVL_UNIT_OFFSET) +#define ATTR_ICC_LVL_VALUE_MASK0x3FF + +/* Power descriptor parameters offsets in bytes */ +enum power_desc_param_offset { + PWR_DESC_LEN= 0x0, + PWR_DESC_TYPE = 0x1, + PWR_DESC_ACTIVE_LVLS_VCC_0 = 0x2, + PWR_DESC_ACTIVE_LVLS_VCCQ_0 = 0x22, + PWR_DESC_ACTIVE_LVLS_VCCQ2_0= 0x42, +}; + /* Exception event mask values */ enum { MASK_EE_STATUS = 0x, diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 1fabff4..a851323 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3265,6 +3265,125 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) } /** + * ufshcd_get_max_icc_level - calculate the ICC level + * @sup_curr_uA: max. current supported by the regulator + * @start_scan: row at the desc table to start scan from + * @buff: power descriptor buffer + * + * Returns calculated max ICC level for specific regulator + */ +static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff) +{ + int i; + int curr_uA; + u16 data; + u16 unit; + + for (i = start_scan; i = 0; i--) { + data = be16_to_cpu(*((u16 *)(buff + 2*i))); + unit = (data ATTR_ICC_LVL_UNIT_MASK) + ATTR_ICC_LVL_UNIT_OFFSET; + curr_uA = data ATTR_ICC_LVL_VALUE_MASK; + switch (unit) { + case UFSHCD_NANO_AMP: + curr_uA = curr_uA / 1000; + break; + case UFSHCD_MILI_AMP: + curr_uA = curr_uA * 1000; + break; + case UFSHCD_AMP: + curr_uA = curr_uA * 1000 * 1000; + break; + case UFSHCD_MICRO_AMP: + default: + break; + } + if (sup_curr_uA = curr_uA) + break; + } + if (i 0) { + i = 0; + pr_err(%s: Couldn't find valid icc_level = %d, __func__, i); + } + + return (u32)i; +} + +/** + * ufshcd_calc_icc_level - calculate the max ICC level + * In case regulators are not initialized we'll return 0 + * @hba: per-adapter instance + * @desc_buf: power descriptor buffer to extract ICC levels from. + * @len: length of desc_buff + * + * Returns calculated ICC level + */ +static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba, + u8 *desc_buf, int len) +{ + u32 icc_level = 0; + + if (!hba-vreg_info.vcc || !hba-vreg_info.vccq || + !hba-vreg_info.vccq2) { + dev_err(hba-dev, + %s: Regulator capability was not set, actvIccLevel=%d, + __func__, icc_level); + goto out; + } + + if (hba-vreg_info.vcc) + icc_level = ufshcd_get_max_icc_level( +
[PATCH/RFC V2 12/16] scsi: ufs: Add support for clock gating
From: Sahitya Tummala stumm...@codeaurora.org The UFS controller clocks can be gated after certain period of inactivity, which is typically less than runtime suspend timeout. In addition to clocks the link will also be put into Hibern8 mode to save more power. The clock gating can be turned on by enabling the capability UFSHCD_CAP_CLK_GATING. To enable entering into Hibern8 mode as part of clock gating, set the capability UFSHCD_CAP_HIBERN8_WITH_CLK_GATING. The tracing events for clock gating can be enabled through debugfs as: echo 1 /sys/kernel/debug/tracing/events/ufs/ufshcd_clk_gating/enable cat /sys/kernel/debug/tracing/trace_pipe Signed-off-by: Sahitya Tummala stumm...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3a66d0d..1e5219c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -177,6 +177,11 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba); +static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, +bool skip_ref_clk); +static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); +static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); +static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static int ufshcd_config_pwr_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *desired_pwr_mode); @@ -498,6 +503,231 @@ static inline int ufshcd_is_hba_active(struct ufs_hba *hba) return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE) 0x1) ? 0 : 1; } +static void ufshcd_ungate_work(struct work_struct *work) +{ + int ret; + unsigned long flags; + struct ufs_hba *hba = container_of(work, struct ufs_hba, + clk_gating.ungate_work); + + cancel_delayed_work_sync(hba-clk_gating.gate_work); + + spin_lock_irqsave(hba-host-host_lock, flags); + if (hba-clk_gating.state == CLKS_ON) { + spin_unlock_irqrestore(hba-host-host_lock, flags); + goto unblock_reqs; + } + + spin_unlock_irqrestore(hba-host-host_lock, flags); + ufshcd_setup_clocks(hba, true); + + /* Exit from hibern8 */ + if (ufshcd_can_hibern8_during_gating(hba)) { + /* Prevent gating in this path */ + hba-clk_gating.is_suspended = true; + if (ufshcd_is_link_hibern8(hba)) { + ret = ufshcd_uic_hibern8_exit(hba); + if (ret) + dev_err(hba-dev, %s: hibern8 exit failed %d\n, + __func__, ret); + else + ufshcd_set_link_active(hba); + } + hba-clk_gating.is_suspended = false; + } +unblock_reqs: + scsi_unblock_requests(hba-host); +} + +/** + * ufshcd_hold - Enable clocks that were gated earlier due to ufshcd_release. + * Also, exit from hibern8 mode and set the link as active. + * @hba: per adapter instance + * @async: This indicates whether caller should ungate clocks asynchronously. + */ +int ufshcd_hold(struct ufs_hba *hba, bool async) +{ + int rc = 0; + unsigned long flags; + + if (!ufshcd_is_clkgating_allowed(hba)) + goto out; +start: + spin_lock_irqsave(hba-host-host_lock, flags); + hba-clk_gating.active_reqs++; + + switch (hba-clk_gating.state) { + case CLKS_ON: + break; + case REQ_CLKS_OFF: + if (cancel_delayed_work(hba-clk_gating.gate_work)) { + hba-clk_gating.state = CLKS_ON; + break; + } + /* +* If we here, it means gating work is either done or +* currently running. Hence, fall through to cancel gating +* work and to enable clocks. +*/ + case CLKS_OFF: + scsi_block_requests(hba-host); + hba-clk_gating.state = REQ_CLKS_ON; + schedule_work(hba-clk_gating.ungate_work); + /* +* fall through to check if we should wait for this +* work to be done or not. +*/ + case REQ_CLKS_ON: + if (async) { + rc = -EAGAIN; + hba-clk_gating.active_reqs--; + break; + } else { + spin_unlock_irqrestore(hba-host-host_lock, flags); + flush_work(hba-clk_gating.ungate_work); + /* Make sure state is CLKS_ON before returning */ + goto start; + } + default: +
[PATCH/RFC V2 09/16] scsi: sd: Avoid sending medium write commands if device is write protected
From: Sujit Reddy Thumma sthu...@codeaurora.org The SYNCHRONIZE_CACHE command is a medium write command and hence can fail when the device is write protected. Avoid sending such commands by making sure that write-cache-enable is disabled even though the device claim to support it. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3663e38..67282bf 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -185,7 +185,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr, if (ct 0) return -EINVAL; rcd = ct 0x01 ? 1 : 0; - wce = ct 0x02 ? 1 : 0; + wce = (ct 0x02) !sdkp-write_prot ? 1 : 0; if (sdkp-cache_override) { sdkp-WCE = wce; @@ -2493,6 +2493,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) sdkp-DPOFUA = 0; } + /* No cache flush allowed for write protected devices */ + if (sdkp-WCE sdkp-write_prot) + sdkp-WCE = 0; + if (sdkp-first_scan || old_wce != sdkp-WCE || old_rcd != sdkp-RCD || old_dpofua != sdkp-DPOFUA) sd_printk(KERN_NOTICE, sdkp, -- 1.8.5.2 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC V2 16/16] scsi: ufs: definitions for phy interface
- Adding some of the definitions missing in unipro.h, including power enumeration. - Read Modify Write Line helper function - Indication for the type of suspend Signed-off-by: Dolev Raviv dra...@codeaurora.org Signed-off-by: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Yaniv Gardi yga...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d9eb2da..1b04cfa 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4924,6 +4924,8 @@ int ufshcd_system_suspend(struct ufs_hba *hba) ret = ufshcd_suspend(hba, UFS_SYSTEM_PM); out: + if (!ret) + hba-is_sys_suspended = true; return ret; } EXPORT_SYMBOL(ufshcd_system_suspend); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index b94b835..d502d70 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -471,6 +471,7 @@ struct ufs_hba { struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; + bool is_sys_suspended; }; /* Returns true if clocks can be gated. Otherwise false */ @@ -496,6 +497,23 @@ static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba) #define ufshcd_readl(hba, reg) \ readl((hba)-mmio_base + (reg)) +/** + * ufshcd_rmwl - read modify write into a register + * @hba - per adapter instance + * @mask - mask to apply on read value + * @val - actual value to write + * @reg - register address + */ +static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) +{ + u32 tmp; + + tmp = ufshcd_readl(hba, reg); + tmp = ~mask; + tmp |= (val mask); + ufshcd_writel(hba, tmp, reg); +} + int ufshcd_alloc_host(struct device *, struct ufs_hba **); int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); void ufshcd_remove(struct ufs_hba *); diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h index 0bb8041..3fc3e21 100644 --- a/drivers/scsi/ufs/unipro.h +++ b/drivers/scsi/ufs/unipro.h @@ -13,6 +13,44 @@ #define _UNIPRO_H_ /* + * M-TX Configuration Attributes + */ +#define TX_MODE0x0021 +#define TX_HSRATE_SERIES 0x0022 +#define TX_HSGEAR 0x0023 +#define TX_PWMGEAR 0x0024 +#define TX_AMPLITUDE 0x0025 +#define TX_HS_SLEWRATE 0x0026 +#define TX_SYNC_SOURCE 0x0027 +#define TX_HS_SYNC_LENGTH 0x0028 +#define TX_HS_PREPARE_LENGTH 0x0029 +#define TX_LS_PREPARE_LENGTH 0x002A +#define TX_HIBERN8_CONTROL 0x002B +#define TX_LCC_ENABLE 0x002C +#define TX_PWM_BURST_CLOSURE_EXTENSION 0x002D +#define TX_BYPASS_8B10B_ENABLE 0x002E +#define TX_DRIVER_POLARITY 0x002F +#define TX_HS_UNTERMINATED_LINE_DRIVE_ENABLE 0x0030 +#define TX_LS_TERMINATED_LINE_DRIVE_ENABLE 0x0031 +#define TX_LCC_SEQUENCER 0x0032 +#define TX_MIN_ACTIVATETIME0x0033 +#define TX_PWM_G6_G7_SYNC_LENGTH 0x0034 + +/* + * M-RX Configuration Attributes + */ +#define RX_MODE0x00A1 +#define RX_HSRATE_SERIES 0x00A2 +#define RX_HSGEAR 0x00A3 +#define RX_PWMGEAR 0x00A4 +#define RX_LS_TERMINATED_ENABLE0x00A5 +#define RX_HS_UNTERMINATED_ENABLE 0x00A6 +#define RX_ENTER_HIBERN8 0x00A7 +#define RX_BYPASS_8B10B_ENABLE 0x00A8 +#define RX_TERMINATION_FORCE_ENABLE0x0089 + +#define is_mphy_tx_attr(attr) (attr RX_MODE) +/* * PHY Adpater attributes */ #define PA_ACTIVETXDATALANES 0x1560 @@ -87,6 +125,24 @@ enum { PA_HS_MODE_B= 2, }; +enum ufs_pwm_gear_tag { + UFS_PWM_DONT_CHANGE,/* Don't change Gear */ + UFS_PWM_G1, /* PWM Gear 1 (default for reset) */ + UFS_PWM_G2, /* PWM Gear 2 */ + UFS_PWM_G3, /* PWM Gear 3 */ + UFS_PWM_G4, /* PWM Gear 4 */ + UFS_PWM_G5, /* PWM Gear 5 */ + UFS_PWM_G6, /* PWM Gear 6 */ + UFS_PWM_G7, /* PWM Gear 7 */ +}; + +enum ufs_hs_gear_tag { + UFS_HS_DONT_CHANGE, /* Don't change Gear */ + UFS_HS_G1, /* HS Gear 1 (default for reset) */ + UFS_HS_G2, /* HS Gear 2 */ + UFS_HS_G3, /* HS Gear 3 */ +}; + /* * Data Link Layer Attributes */ -- 1.8.5.2 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org
[PATCH/RFC V2 15/16] scsi: ufs: add capability to control the auto bkops during suspend
From: Subhash Jadavani subha...@codeaurora.org If host explicitly enables the auto bkops (background operation) on device then only device would perform the bkops on its own. If auto bkops is not enabled explicitly and if the device reaches to state where it must do background operation, device would raise the urgent bkops exception event to host and then host will enable the auto bkops on device. This patch adds the option to choose whether auto bkops should be enabled during runtime suspend or not. Signed-off-by: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 6b769d0..d9eb2da 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4704,13 +4704,18 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) } if (ufshcd_is_runtime_pm(pm_op)) { - /* -* The device is idle with no requests in the queue, -* allow background operations if needed. -*/ - ret = ufshcd_bkops_ctrl(hba, BKOPS_STATUS_NON_CRITICAL); - if (ret) - goto enable_gating; + if (ufshcd_can_autobkops_during_suspend(hba)) { + /* +* The device is idle with no requests in the queue, +* allow background operations if needed. +*/ + ret = ufshcd_bkops_ctrl(hba, BKOPS_STATUS_NON_CRITICAL); + if (ret) + goto enable_gating; + } else { + /* make sure that auto bkops is disabled */ + ufshcd_disable_auto_bkops(hba); + } } if ((req_dev_pwr_mode != hba-curr_dev_pwr_mode) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index d5699d0..b94b835 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -466,6 +466,8 @@ struct ufs_hba { #define UFSHCD_CAP_HIBERN8_WITH_CLK_GATING (1 1) /* Allow dynamic clk scaling */ #define UFSHCD_CAP_CLK_SCALING (1 2) + /* Allow auto bkops to enabled during runtime suspend */ +#define UFSHCD_CAP_AUTO_BKOPS_SUSPEND (1 3) struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; @@ -484,6 +486,11 @@ static inline int ufshcd_is_clkscaling_enabled(struct ufs_hba *hba) { return hba-caps UFSHCD_CAP_CLK_SCALING; } +static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba) +{ + return hba-caps UFSHCD_CAP_AUTO_BKOPS_SUSPEND; +} + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)-mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ -- 1.8.5.2 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC V2 14/16] scsi: ufs: Add support for clock scaling using devfreq framework
From: Sahitya Tummala stumm...@codeaurora.org The clocks for UFS device will be managed by generic DVFS (Dynamic Voltage and Frequency Scaling) framework within kernel. This devfreq framework works with different governors to scale the clocks. By default, UFS devices uses simple_ondemand governor which scales the clocks up if the load is more than upthreshold and scales down if the load is less than downthreshold. Signed-off-by: Sahitya Tummala stumm...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index f07f901..6e07b2a 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -35,6 +35,8 @@ config SCSI_UFSHCD tristate Universal Flash Storage Controller Driver Core depends on SCSI SCSI_DMA + select PM_DEVFREQ + select DEVFREQ_GOV_SIMPLE_ONDEMAND ---help--- This selects the support for UFS devices in Linux, say Y and make sure that you know the name of your UFS host adapter (the card diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 1e5219c..6b769d0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -38,6 +38,7 @@ */ #include linux/async.h +#include linux/devfreq.h #include ufshcd.h #include unipro.h @@ -536,6 +537,8 @@ static void ufshcd_ungate_work(struct work_struct *work) hba-clk_gating.is_suspended = false; } unblock_reqs: + if (ufshcd_is_clkscaling_enabled(hba)) + devfreq_resume_device(hba-devfreq); scsi_unblock_requests(hba-host); } @@ -552,10 +555,10 @@ int ufshcd_hold(struct ufs_hba *hba, bool async) if (!ufshcd_is_clkgating_allowed(hba)) goto out; -start: spin_lock_irqsave(hba-host-host_lock, flags); hba-clk_gating.active_reqs++; +start: switch (hba-clk_gating.state) { case CLKS_ON: break; @@ -586,6 +589,7 @@ start: spin_unlock_irqrestore(hba-host-host_lock, flags); flush_work(hba-clk_gating.ungate_work); /* Make sure state is CLKS_ON before returning */ + spin_lock_irqsave(hba-host-host_lock, flags); goto start; } default: @@ -627,6 +631,11 @@ static void ufshcd_gate_work(struct work_struct *work) ufshcd_set_link_hibern8(hba); } + if (ufshcd_is_clkscaling_enabled(hba)) { + devfreq_suspend_device(hba-devfreq); + hba-clk_scaling.window_start_t = 0; + } + if (!ufshcd_is_link_active(hba)) ufshcd_setup_clocks(hba, false); else @@ -728,6 +737,32 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) device_remove_file(hba-dev, hba-clk_gating.delay_attr); } +/* Must be called with host lock acquired */ +static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) +{ + if (!ufshcd_is_clkscaling_enabled(hba)) + return; + + if (!hba-clk_scaling.is_busy_started) { + hba-clk_scaling.busy_start_t = ktime_get(); + hba-clk_scaling.is_busy_started = true; + } +} + +static void ufshcd_clk_scaling_update_busy(struct ufs_hba *hba) +{ + struct ufs_clk_scaling *scaling = hba-clk_scaling; + + if (!ufshcd_is_clkscaling_enabled(hba)) + return; + + if (!hba-outstanding_reqs scaling-is_busy_started) { + scaling-tot_busy_t += ktime_to_us(ktime_sub(ktime_get(), + scaling-busy_start_t)); + scaling-busy_start_t = ktime_set(0, 0); + scaling-is_busy_started = false; + } +} /** * ufshcd_send_command - Send SCSI or device management commands * @hba: per adapter instance @@ -736,6 +771,7 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { + ufshcd_clk_scaling_start_busy(hba); __set_bit(task_tag, hba-outstanding_reqs); ufshcd_writel(hba, 1 task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); } @@ -2990,6 +3026,8 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) /* clear corresponding bits of completed commands */ hba-outstanding_reqs ^= completed_reqs; + ufshcd_clk_scaling_update_busy(hba); + /* we might have free'd some tags above */ wake_up(hba-dev_cmd.tag_wq); } @@ -4021,6 +4059,10 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) if (!hba-is_init_prefetch) hba-is_init_prefetch = true; + /* Resume devfreq after UFS device is detected */ + if (ufshcd_is_clkscaling_enabled(hba)) + devfreq_resume_device(hba-devfreq); + out: /* * If we failed to initialize the device or the device is not @@ -4322,6 +4364,7 @@ static int
[PATCH/RFC V2 08/16] scsi: ufs: introduce well known logical unit in ufs
From: Subhash Jadavani subha...@codeaurora.org UFS device may have standard LUs and LUN id could be from 0x00 to 0x7F. UFS device specification use Peripheral Device Addressing Format (SCSI SAM-5) for standard LUs. UFS device may also have the Well Known LUs (also referred as W-LU) which again could be from 0x00 to 0x7F. For W-LUs, UFS device specification only allows the Extended Addressing Format (SCSI SAM-5) which means the W-LUNs would start from 0xC100 onwards. This means max. LUN number reported from UFS device could be 0xC17F hence this patch advertise the max_lun as 0xC17F which will allow SCSI mid layer to detect the W-LUs as well. But once the W-LUs are detected, UFSHCD driver may get the commands with SCSI LUN id upto 0xC17F but UPIU LUN id field is only 8-bit wide so it requires the mapping of SCSI LUN id to UPIU LUN id. This patch also add support for this mapping. Signed-off-by: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index b0e1f62..bcc3a7f 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -49,9 +49,28 @@ #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ cpu_to_be32((byte3 24) | (byte2 16) |\ (byte1 8) | (byte0)) - +/* + * UFS device may have standard LUs and LUN id could be from 0x00 to + * 0x7F. Standard LUs use Peripheral Device Addressing Format. + * UFS device may also have the Well Known LUs (also referred as W-LU) + * which again could be from 0x00 to 0x7F. For W-LUs, device only use + * the Extended Addressing Format which means the W-LUNs would be + * from 0xc100 (SCSI_W_LUN_BASE) onwards. + * This means max. LUN number reported from UFS device could be 0xC17F. + */ +#define UFS_UPIU_MAX_UNIT_NUM_ID 0x7F +#define UFS_MAX_LUNS (SCSI_W_LUN_BASE + UFS_UPIU_MAX_UNIT_NUM_ID) +#define UFS_UPIU_WLUN_ID (1 7) #define UFS_UPIU_MAX_GENERAL_LUN 8 +/* Well known logical unit id in LUN field of UPIU */ +enum { + UFS_UPIU_REPORT_LUNS_WLUN = 0x81, + UFS_UPIU_UFS_DEVICE_WLUN= 0xD0, + UFS_UPIU_BOOT_WLUN = 0xB0, + UFS_UPIU_RPMB_WLUN = 0xC4, +}; + /* * UFS Protocol Information Unit related definitions */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a851323..876d210 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -100,7 +100,6 @@ static u32 ufs_query_desc_max_size[] = { enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, - UFSHCD_MAX_LUNS = 8, UFSHCD_CMD_PER_LUN = 32, UFSHCD_CAN_QUEUE= 32, }; @@ -902,6 +901,21 @@ static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } /** + * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN + * @scsi_lun: scsi LUN id + * + * Returns UPIU LUN id + */ +static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) +{ + if (scsi_is_wlun(scsi_lun)) + return (scsi_lun UFS_UPIU_MAX_UNIT_NUM_ID) + | UFS_UPIU_WLUN_ID; + else + return scsi_lun UFS_UPIU_MAX_UNIT_NUM_ID; +} + +/** * ufshcd_queuecommand - main entry point for SCSI requests * @cmd: command from SCSI Midlayer * @done: call back function @@ -959,7 +973,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp-sense_bufflen = SCSI_SENSE_BUFFERSIZE; lrbp-sense_buffer = cmd-sense_buffer; lrbp-task_tag = tag; - lrbp-lun = cmd-device-lun; + lrbp-lun = ufshcd_scsi_to_upiu_lun(cmd-device-lun); lrbp-intr_cmd = false; lrbp-command_type = UTP_CMD_TYPE_SCSI; @@ -1513,7 +1527,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba, * Unit descriptors are only available for general purpose LUs (LUN id * from 0 to 7) and RPMB Well known LU. */ - if (lun = UFS_UPIU_MAX_GENERAL_LUN) + if (lun != UFS_UPIU_RPMB_WLUN (lun = UFS_UPIU_MAX_GENERAL_LUN)) return -EOPNOTSUPP; return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun, @@ -2144,6 +2158,44 @@ static int ufshcd_verify_dev_init(struct ufs_hba *hba) } /** + * ufshcd_set_queue_depth - set lun queue depth + * @sdev: pointer to SCSI device + * + * Read bLUQueueDepth value and activate scsi tagged command + * queueing. For WLUN, queue depth is set to 1. For best-effort + * cases (bLUQueueDepth = 0) the queue depth is set to a maximum + * value that host can queue. + */ +static void ufshcd_set_queue_depth(struct scsi_device *sdev) +{ + int ret = 0; + u8 lun_qdepth; + struct ufs_hba *hba; + + hba = shost_priv(sdev-host); + + lun_qdepth = hba-nutrs; + ret = ufshcd_read_unit_desc_param(hba, +
[PATCH/RFC V2 13/16] scsi: ufs: Add freq-table-hz property for UFS device
From: Sahitya Tummala stumm...@codeaurora.org Add freq-table-hz propery for UFS device to keep track of min max frequencies supported by UFS clocks. Signed-off-by: Sahitya Tummala stumm...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index b0f791a..e73a619 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -24,11 +24,11 @@ Optional properties: - 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. -- max-clock-frequency-hz : List of maximum operating frequency 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. +- freq-table-hz: Array of min max 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. Note: If above properties are not defined it can be assumed that the supply regulators or clocks are always on. @@ -49,5 +49,5 @@ Example: clocks = core 0, ref 0, iface 0; clock-names = core_clk, ref_clk, iface_clk; - max-clock-frequency-hz = 1 1920 0; + freq-table-hz = 1 2, 0 0, 0 0; }; diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index edaccd0..551be95 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -63,6 +63,8 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) char *name; u32 *clkfreq = NULL; struct ufs_clk_info *clki; + int len = 0; + size_t sz = 0; if (!np) goto out; @@ -82,39 +84,59 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) if (cnt = 0) goto out; - clkfreq = kzalloc(cnt * sizeof(*clkfreq), GFP_KERNEL); + if (!of_get_property(np, freq-table-hz, len)) { + dev_info(dev, freq-table-hz property not specified\n); + goto out; + } + + if (len = 0) + goto out; + + sz = len / sizeof(*clkfreq); + if (sz != 2 * cnt) { + dev_err(dev, %s len mismatch\n, freq-table-hz); + ret = -EINVAL; + goto out; + } + + clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq), + GFP_KERNEL); if (!clkfreq) { + dev_err(dev, %s: no memory\n, freq-table-hz); ret = -ENOMEM; - dev_err(dev, %s: memory alloc failed\n, __func__); goto out; } - ret = of_property_read_u32_array(np, - max-clock-frequency-hz, clkfreq, cnt); + ret = of_property_read_u32_array(np, freq-table-hz, + clkfreq, sz); if (ret (ret != -EINVAL)) { - dev_err(dev, %s: invalid max-clock-frequency-hz property, %d\n, - __func__, ret); - goto out; + dev_err(dev, %s: error reading array %d\n, + freq-table-hz, ret); + goto free_clkfreq; } - for (i = 0; i cnt; i++) { + for (i = 0; i sz; i += 2) { ret = of_property_read_string_index(np, - clock-names, i, (const char **)name); + clock-names, i/2, (const char **)name); if (ret) - goto out; + goto free_clkfreq; clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); if (!clki) { ret = -ENOMEM; - goto out; + goto free_clkfreq; } - clki-max_freq = clkfreq[i]; + clki-min_freq = clkfreq[i]; + clki-max_freq = clkfreq[i+1]; clki-name = kstrdup(name, GFP_KERNEL); + dev_dbg(dev, %s: min %u max %u name %s\n, freq-table-hz, + clki-min_freq, clki-max_freq, clki-name); list_add_tail(clki-list, hba-clk_list_head); } -out: +free_clkfreq: kfree(clkfreq); +out: return ret; } diff --git a/drivers/scsi/ufs/ufshcd.h
[PATCH/RFC V2 04/16] scsi: ufs: refactor query descriptor API support
From: Subhash Jadavani subha...@codeaurora.org Currently reading query descriptor is more tightened to each descriptor type. This patch generalize the approach and allows reading any parameter from any query descriptor. Signed-off-by: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 729ce7d..7ea8e71 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -50,6 +50,8 @@ cpu_to_be32((byte3 24) | (byte2 16) |\ (byte1 8) | (byte0)) +#define UFS_UPIU_MAX_GENERAL_LUN 8 + /* * UFS Protocol Information Unit related definitions */ @@ -129,10 +131,29 @@ enum desc_idn { QUERY_DESC_IDN_RFU_1= 0x6, QUERY_DESC_IDN_GEOMETRY = 0x7, QUERY_DESC_IDN_POWER= 0x8, - QUERY_DESC_IDN_RFU_2= 0x9, + QUERY_DESC_IDN_MAX, +}; + +enum desc_header_offset { + QUERY_DESC_LENGTH_OFFSET= 0x00, + QUERY_DESC_DESC_TYPE_OFFSET = 0x01, +}; + +enum ufs_desc_max_size { + QUERY_DESC_DEVICE_MAX_SIZE = 0x1F, + QUERY_DESC_CONFIGURAION_MAX_SIZE= 0x90, + QUERY_DESC_UNIT_MAX_SIZE= 0x23, + QUERY_DESC_INTERCONNECT_MAX_SIZE= 0x06, + /* +* Max. 126 UNICODE characters (2 bytes per character) plus 2 bytes +* of descriptor header. +*/ + QUERY_DESC_STRING_MAX_SIZE = 0xFE, + QUERY_DESC_GEOMETRY_MAZ_SIZE= 0x44, + QUERY_DESC_POWER_MAX_SIZE = 0x62, + QUERY_DESC_RFU_MAX_SIZE = 0x00, }; -#define UNIT_DESC_MAX_SIZE 0x22 /* Unit descriptor parameters offsets in bytes*/ enum unit_desc_param { UNIT_DESC_PARAM_LEN = 0x0, diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b033702..57a8dbb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -78,6 +78,19 @@ _ret; \ }) +static u32 ufs_query_desc_max_size[] = { + QUERY_DESC_DEVICE_MAX_SIZE, + QUERY_DESC_CONFIGURAION_MAX_SIZE, + QUERY_DESC_UNIT_MAX_SIZE, + QUERY_DESC_RFU_MAX_SIZE, + QUERY_DESC_INTERCONNECT_MAX_SIZE, + QUERY_DESC_STRING_MAX_SIZE, + QUERY_DESC_RFU_MAX_SIZE, + QUERY_DESC_GEOMETRY_MAZ_SIZE, + QUERY_DESC_POWER_MAX_SIZE, + QUERY_DESC_RFU_MAX_SIZE, +}; + enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, @@ -124,8 +137,6 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba); static void ufshcd_async_scan(void *data, async_cookie_t cookie); static int ufshcd_reset_and_restore(struct ufs_hba *hba); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); -static int ufshcd_read_sdev_qdepth(struct ufs_hba *hba, - struct scsi_device *sdev); /* * ufshcd_wait_for_register - wait for register value to change @@ -1393,6 +1404,115 @@ out: } /** + * ufshcd_read_desc_param - read the specified descriptor parameter + * @hba: Pointer to adapter instance + * @desc_id: descriptor idn value + * @desc_index: descriptor index + * @param_offset: offset of the parameter to read + * @param_read_buf: pointer to buffer where parameter would be read + * @param_size: sizeof(param_read_buf) + * + * Return 0 in case of success, non-zero otherwise + */ +static int ufshcd_read_desc_param(struct ufs_hba *hba, + enum desc_idn desc_id, + int desc_index, + u32 param_offset, + u8 *param_read_buf, + u32 param_size) +{ + int ret; + u8 *desc_buf; + u32 buff_len; + bool is_kmalloc = true; + + /* safety checks */ + if (desc_id = QUERY_DESC_IDN_MAX) + return -EINVAL; + + buff_len = ufs_query_desc_max_size[desc_id]; + if ((param_offset + param_size) buff_len) + return -EINVAL; + + if (!param_offset (param_size == buff_len)) { + /* memory space already available to hold full descriptor */ + desc_buf = param_read_buf; + is_kmalloc = false; + } else { + /* allocate memory to hold full descriptor */ + desc_buf = kmalloc(buff_len, GFP_KERNEL); + if (!desc_buf) + return -ENOMEM; + } + + ret = ufshcd_query_descriptor(hba, UPIU_QUERY_OPCODE_READ_DESC, + desc_id, desc_index, 0, desc_buf, + buff_len); + + if (ret || (buff_len ufs_query_desc_max_size[desc_id]) || + (desc_buf[QUERY_DESC_LENGTH_OFFSET] != +ufs_query_desc_max_size[desc_id]) +
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On Wednesday 13 August 2014 01:13 AM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/msm-pm.c | 219 ++ include/soc/qcom/pm.h | 39 + snip +{ + u32 cache_id = 0; + +#if defined(CONFIG_CPU_V7) + u32 sel = 0; + + asm volatile (mcr p15, 2, %[ccselr], c0, c0, 0\n\t + isb\n\t + mrc p15, 1, %[ccsidr], c0, c0, 0\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) Space after ':' is what checkpatch asks. :) + ); + return cache_id BIT(30); +#elif defined(CONFIG_ARM64) + u32 sel = 0; new line missing after declaration. + asm volatile(msr csselr_el1, %[ccselr]\n\t + isb\n\t + mrs %[ccsidr],ccsidr_el1\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) Space after ':' is what checkpatch asks. :) + ); + return cache_id BIT(30); +#else +#error No valid CPU arch selected +#endif +} + -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/msm-pm.c | 219 ++ include/soc/qcom/pm.h | 39 + 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/qcom/msm-pm.c create mode 100644 include/soc/qcom/pm.h diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index d7ae93b..7925f83 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_QCOM_GSBI)+=qcom_gsbi.o -obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o +obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o msm-pm.o CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/msm-pm.c b/drivers/soc/qcom/msm-pm.c new file mode 100644 index 000..f2f15b8 --- /dev/null +++ b/drivers/soc/qcom/msm-pm.c @@ -0,0 +1,219 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/init.h +#include linux/io.h +#include linux/smp.h +#include linux/tick.h +#include linux/platform_device.h +#include linux/cpu_pm.h +#include linux/uaccess.h + +#include soc/qcom/spm.h +#include soc/qcom/pm.h +#include soc/qcom/scm.h +#include soc/qcom/scm-boot.h + +#include asm/suspend.h +#include asm/cacheflush.h +#include asm/cputype.h +#include asm/system_misc.h + +#define SCM_CMD_TERMINATE_PC(0x2) +#define SCM_CMD_CORE_HOTPLUGGED (0x10) +#define SCM_FLUSH_FLAG_MASK(0x3) + +static bool msm_pm_is_L1_writeback(void) +{ +u32 cache_id = 0; + +#if defined(CONFIG_CPU_V7) +u32 sel = 0; + +asm volatile (mcr p15, 2, %[ccselr], c0, c0, 0\n\t + isb\n\t + mrc p15, 1, %[ccsidr], c0, c0, 0\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) + ); +return cache_id BIT(30); +#elif defined(CONFIG_ARM64) +u32 sel = 0; +asm volatile(msr csselr_el1, %[ccselr]\n\t + isb\n\t + mrs %[ccsidr],ccsidr_el1\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) +); +return cache_id BIT(30); +#else +#error No valid CPU arch selected +#endif +} + +static inline void msm_arch_idle(void) +{ +/* Flush and clock-gate */ +mb(); Why is needed this memory barrier ? Some QCOM SoCs needed this. I am not sure which one anymore. :( +wfi(); +} + +static bool msm_pm_swfi(bool from_idle) +{ +msm_arch_idle(); +return true; +} + +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Can you elaborate ? Or may be just describe what is the doing the function because I don't get the connection between your explanation and the code. +return true; +} + +static int msm_pm_collapse(unsigned long from_idle) +{ +enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON; + +/** + * Single core processors need to have L2 + * flushed when powering down the core. + * Notify SCM to flush secure L2 lines. + */ +if (num_possible_cpus() == 1) +flag = MSM_SCM_L2_OFF; I am wondering if this shouldn't be handle by a mcpm driver. Cc nico. Well, possibly, sorry, not sure what features of the mcpm driver you think I need here? Please correct me if I am wrong. IIUC, this function is checking the number of the cpus of the cluster in order to flush the L2 cache because the SCM will power down the cluster if it is the last one, right ? -- http://www.linaro.org/ Linaro.org │ Open source software for
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On Thu, Aug 14, 2014 at 04:24:10PM +0200, Daniel Lezcano wrote: On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Can you elaborate ? Or may be just describe what is the doing the function because I don't get the connection between your explanation and the code. Retention still has an higher latency than clock gating. Retention gets triggered with the core executes wfi() instruction. The entry into a steady state retention mode is higher than just gating clocks, which may be bad for power, if we do not stay in the low power modes for a minimum of the residency period. If the current idle state was retention and SPM was configured to do retention and we came out the retention state and the next idle, we decided to do clockgating we should configure the SPM to do clock gating. Since we want to speed up clockgating as its one of the state most commonly entered, we set the configuration of SPM as soon as we come out any low power mode back to WFI. +return true; +} + +static int msm_pm_collapse(unsigned long from_idle) +{ +enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON; + +/** + * Single core processors need to have L2 + * flushed when powering down the core. + * Notify SCM to flush secure L2 lines. + */ +if (num_possible_cpus() == 1) +flag = MSM_SCM_L2_OFF; I am wondering if this shouldn't be handle by a mcpm driver. Cc nico. Well, possibly, sorry, not sure what features of the mcpm driver you think I need here? Please correct me if I am wrong. IIUC, this function is checking the number of the cpus of the cluster in order to flush the L2 cache because the SCM will power down the cluster if it is the last one, right ? -- http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs Follow Linaro: http://www.facebook.com/pages/Linaro Facebook | http://twitter.com/#!/linaroorg Twitter | http://www.linaro.org/linaro-blog/ Blog -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] scsi: ufs-msm: add UFS controller support for Qualcomm MSM chips
On Aug 14, 2014, at 9:22 AM, Yaniv Gardi yga...@codeaurora.org wrote: The files in this change implement the UFS HW (controller PHY) specific behavior in Qualcomm MSM chips. Signed-off-by: Yaniv Gardi yga...@codeaurora.org --- Documentation/devicetree/bindings/ufs/ufs-msm.txt | 37 + .../devicetree/bindings/ufs/ufshcd-pltfrm.txt |4 + drivers/scsi/ufs/Kconfig | 12 + drivers/scsi/ufs/Makefile |4 + drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.c| 254 + drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.h| 216 drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.c| 368 +++ drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.h| 735 + drivers/scsi/ufs/ufs-msm-phy.c | 646 drivers/scsi/ufs/ufs-msm-phy.h | 193 Any reason not to put the phy driver in drivers/phy ? drivers/scsi/ufs/ufs-msm.c | 1105 drivers/scsi/ufs/ufs-msm.h | 158 +++ 12 files changed, 3732 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-msm.txt create mode 100644 drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.c create mode 100644 drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.h create mode 100644 drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.c create mode 100644 drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.h create mode 100644 drivers/scsi/ufs/ufs-msm-phy.c create mode 100644 drivers/scsi/ufs/ufs-msm-phy.h create mode 100644 drivers/scsi/ufs/ufs-msm.c create mode 100644 drivers/scsi/ufs/ufs-msm.h Seems like we should spit this into two patches, one for the phy and one for the UFS driver itself. Maybe even three, one for the 20nm phy, one for the 28nm phy, and one for ufs-msm.c,h. diff --git a/Documentation/devicetree/bindings/ufs/ufs-msm.txt b/Documentation/devicetree/bindings/ufs/ufs-msm.txt new file mode 100644 index 000..b5caace --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-msm.txt This should probably be bindings/phy/qcom-ufs-phy.txt @@ -0,0 +1,37 @@ +* MSM Universal Flash Storage (UFS) PHY + +UFSPHY nodes are defined to describe on-chip UFS PHY hardware macro. +Each UFS PHY node should have its own node. + +To bind UFS PHY with UFS host controller, the controller node should +contain a phandle reference to UFS PHY node. + +Required properties: +- compatible: compatible list, contains qcom,ufs-msm-phy-qmp-28nm + or qcom,ufs-msm-phy-qmp-20nm according to the relevant + phy in use Do we really need ‘-msm’ in the compat name? +- reg : registers mapping +- #phy-cells : This property shall be set to 0 +- vdda-phy-supply : phandle to main PHY supply for analog domain +- vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply + +Optional properties: +- vdda-phy-max-microamp : specifies max. load that can be drawn from phy supply +- vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply + +Example: + + ufsphy1: ufsphy@0xfc597000 { + compatible = qcom,ufs-msm-phy-qmp-28nm; + reg = 0xfc597000 0x800; + #phy-cells = 0; + vdda-phy-supply = pma8084_l4; + vdda-pll-supply = pma8084_l12; + vdda-phy-max-microamp = 5; + vdda-pll-max-microamp = 1000; + }; + + ufshc@0xfc598000 { + ... + phys = ufsphy1; + }; diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index e73a619..378585c 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -9,6 +9,9 @@ Required properties: - reg : registers mapping Optional properties: +- phys : phandle to UFS PHY node +- phy-names : the string ufs_msm_phy when is found in a node, along + with phys attribute, provides phandle to UFS PHY node seems like the phy-names should be more generic like “ufsphy - vcc-supply: phandle to VCC supply regulator node - vccq-supply : phandle to VCCQ supply regulator node - vccq2-supply : phandle to VCCQ2 supply regulator node @@ -39,6 +42,7 @@ Example: reg = 0xfc598000 0x800; interrupts = 0 28 0; + ufs-phy = ufsphy; vcc-supply = xxx_reg1; vcc-supply-1p8; vccq-supply = xxx_reg2; diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 6e07b2a..a8259e0 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -70,3 +70,15 @@ config SCSI_UFSHCD_PLATFORM If you have a controller with this interface, say Y or M here. If unsure, say
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: Qualcomm chipsets use an separate h/w block to control the logic around the processor cores (cpu and L2). The SPM h/w block regulates power to the cores and controls the power when the core enter low power modes. Each core has its own instance of SPM. The SPM has the following key functions - Configure the h/w dependencies when entering low power modes - Wait for interrupt and wake up on interrupt - Ensure the dependencies are ready before bringing the core out of sleep - Regulating voltage to the core, interfacing with the PMIC. - Optimize power based on runtime recommendations. The driver identifies and configures the SPMs, by reading the nodes and the register values from the devicetree. The SPMs need to be configured to allow the processor to be idled in a low power state. Signed-off-by: Praveen Chidamabram pchid...@codeaurora.org Signed-off-by: Murali Nalajala mnala...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- .../devicetree/bindings/arm/msm/spm-v2.txt | 62 ++ drivers/soc/qcom/Makefile | 2 + drivers/soc/qcom/spm-devices.c | 703 + drivers/soc/qcom/spm.c | 482 ++ drivers/soc/qcom/spm_driver.h | 116 include/soc/qcom/spm.h | 70 ++ 6 files changed, 1435 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/spm-v2.txt create mode 100644 drivers/soc/qcom/spm-devices.c create mode 100644 drivers/soc/qcom/spm.c create mode 100644 drivers/soc/qcom/spm_driver.h create mode 100644 include/soc/qcom/spm.h diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register +- qcom,name: The name with which a SPM device is identified by the power + management code. Still not sure about this, wondering why we can’t use the node name. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92 + a0 b0 03 68 70 3b 92 a0 b0 + 82 2b 50 10 30 02 22 30 0f]; + }; diff
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Thu, Aug 14, 2014 at 06:31:09PM +0530, Pramod Gurav wrote: On Wednesday 13 August 2014 01:13 AM, Lina Iyer wrote: Qualcomm chipsets use an separate h/w block to control the logic around the processor cores (cpu and L2). The SPM h/w block regulates power to the cores and controls the power when the core enter low power modes. Each core has its own instance of SPM. The SPM has the following key functions - Configure the h/w dependencies when entering low power modes - Wait for interrupt and wake up on interrupt - Ensure the dependencies are ready before bringing the core out of sleep - Regulating voltage to the core, interfacing with the PMIC. - Optimize power based on runtime recommendations. The driver identifies and configures the SPMs, by reading the nodes and the register values from the devicetree. The SPMs need to be configured to allow the processor to be idled in a low power state. Signed-off-by: Praveen Chidamabram pchid...@codeaurora.org Signed-off-by: Murali Nalajala mnala...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- + snip CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/spm-devices.c b/drivers/soc/qcom/spm-devices.c new file mode 100644 index 000..567e9f9 --- /dev/null +++ b/drivers/soc/qcom/spm-devices.c snip + if (ret) + return ret; + + return dev-cpu_vdd; +} +EXPORT_SYMBOL(msm_spm_get_vdd); + +static void msm_spm_config_q2s(struct msm_spm_device *dev, unsigned int mode) +{ + uint32_t spm_legacy_mode = 0; + uint32_t qchannel_ignore = 0; + uint32_t val = 0; Initialization not needed for val. + + if (!dev-q2s_reg) + return; + + switch (mode) { + case MSM_SPM_MODE_DISABLED: + case MSM_SPM_MODE_CLOCK_GATING: + qchannel_ignore = 1; + spm_legacy_mode = 0; + break; + case MSM_SPM_MODE_RETENTION: + qchannel_ignore = 0; + spm_legacy_mode = 0; + break; + case MSM_SPM_MODE_GDHS: + case MSM_SPM_MODE_POWER_COLLAPSE: + qchannel_ignore = 0; + spm_legacy_mode = 1; + break; + default: + break; + } + + val = spm_legacy_mode 2 | qchannel_ignore 1; + __raw_writel(val, dev-q2s_reg); + mb(); This may need a comment around it. Sorry, my bad. I picked up the latest driver and this came with it. In my next version I pruned this code. +} + +static int msm_spm_dev_set_low_power_mode(struct msm_spm_device *dev, + unsigned int mode, bool notify_rpm) +{ + uint32_t i; + uint32_t start_addr = 0; + int ret = -EINVAL; + bool pc_mode = false; + + if (!dev-initialized) + return -ENXIO; + + if ((mode == MSM_SPM_MODE_POWER_COLLAPSE) + || (mode == MSM_SPM_MODE_GDHS)) + pc_mode = true; + + if (mode == MSM_SPM_MODE_DISABLED) { + ret = msm_spm_drv_set_spm_enable(dev-reg_data, false); + } else if (!msm_spm_drv_set_spm_enable(dev-reg_data, true)) { + for (i = 0; i dev-num_modes; i++) { + if ((dev-modes[i].mode == mode) + (dev-modes[i].notify_rpm == notify_rpm)) { + start_addr = dev-modes[i].start_addr; + break; + } + } + ret = msm_spm_drv_set_low_power_mode(dev-reg_data, + start_addr, pc_mode); + } + + msm_spm_config_q2s(dev, mode); + + return ret; +} + +static int msm_spm_dev_init(struct msm_spm_device *dev, + struct msm_spm_platform_data *data) +{ + int i, ret = -ENOMEM; + uint32_t offset = 0; + + dev-cpu_vdd = VDD_DEFAULT; + dev-num_modes = data-num_modes; + dev-modes = kmalloc( + sizeof(struct msm_spm_power_modes) * dev-num_modes, + GFP_KERNEL); + + if (!dev-modes) + goto spm_failed_malloc; + + dev-reg_data.major = data-major; + dev-reg_data.minor = data-minor; + ret = msm_spm_drv_init(dev-reg_data, data); + Please remove extra line. + if (ret) + goto spm_failed_init; + + for (i = 0; i dev-num_modes; i++) { + + /* Default offset is 0 and gets updated as we write more +* sequences into SPM +*/ + dev-modes[i].start_addr = offset; + ret = msm_spm_drv_write_seq_data(dev-reg_data, + data-modes[i].cmd, offset); + if (ret 0) + goto spm_failed_init; + + dev-modes[i].mode = data-modes[i].mode; +
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Thu, Aug 14, 2014 at 10:16:15AM -0500, Kumar Gala wrote: On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: Qualcomm chipsets use an separate h/w block to control the logic around the processor cores (cpu and L2). The SPM h/w block regulates power to the cores and controls the power when the core enter low power modes. Each core has its own instance of SPM. The SPM has the following key functions - Configure the h/w dependencies when entering low power modes - Wait for interrupt and wake up on interrupt - Ensure the dependencies are ready before bringing the core out of sleep - Regulating voltage to the core, interfacing with the PMIC. - Optimize power based on runtime recommendations. The driver identifies and configures the SPMs, by reading the nodes and the register values from the devicetree. The SPMs need to be configured to allow the processor to be idled in a low power state. Signed-off-by: Praveen Chidamabram pchid...@codeaurora.org Signed-off-by: Murali Nalajala mnala...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- .../devicetree/bindings/arm/msm/spm-v2.txt | 62 ++ drivers/soc/qcom/Makefile | 2 + drivers/soc/qcom/spm-devices.c | 703 + drivers/soc/qcom/spm.c | 482 ++ drivers/soc/qcom/spm_driver.h | 116 include/soc/qcom/spm.h | 70 ++ 6 files changed, 1435 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/spm-v2.txt create mode 100644 drivers/soc/qcom/spm-devices.c create mode 100644 drivers/soc/qcom/spm.c create mode 100644 drivers/soc/qcom/spm_driver.h create mode 100644 include/soc/qcom/spm.h diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register +- qcom,name: The name with which a SPM device is identified by the power + management code. Still not sure about this, wondering why we can’t use the node name. At this point, without the SoC Idle frameworks code, we dont need this. I will prune this off from the next version. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c new file mode 100644 index 000..7dbdb64 --- /dev/null +++ b/drivers/soc/qcom/spm.c @@ -0,0 +1,482 @@ +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/init.h +#include linux/io.h +#include linux/slab.h + +#include spm_driver.h + +#define MSM_SPM_PMIC_STATE_IDLE 0 + +enum { + MSM_SPM_DEBUG_SHADOW = 1U 0, + MSM_SPM_DEBUG_VCTL = 1U 1, +}; + +static int msm_spm_debug_mask; +module_param_named( + debug_mask, msm_spm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP +); + +struct saw2_data { + const char *ver_name; + uint32_t major; + uint32_t minor; + uint32_t *spm_reg_offset_ptr; +}; + +static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = { + [MSM_SPM_REG_SAW2_SECURE] = 0x00, + [MSM_SPM_REG_SAW2_ID] = 0x04, + [MSM_SPM_REG_SAW2_CFG] = 0x08, + [MSM_SPM_REG_SAW2_SPM_STS] = 0x0C, + [MSM_SPM_REG_SAW2_AVS_STS] = 0x10, + [MSM_SPM_REG_SAW2_PMIC_STS] = 0x14, + [MSM_SPM_REG_SAW2_RST] = 0x18, + [MSM_SPM_REG_SAW2_VCTL] = 0x1C, + [MSM_SPM_REG_SAW2_AVS_CTL] = 0x20, + [MSM_SPM_REG_SAW2_AVS_LIMIT]= 0x24, + [MSM_SPM_REG_SAW2_AVS_DLY] = 0x28, + [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, + [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, + [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, + [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, + [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, + [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, + [MSM_SPM_REG_SAW2_PMIC_DATA_3] = 0x4C, + [MSM_SPM_REG_SAW2_PMIC_DATA_4] = 0x50, + [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, + [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, + [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, + [MSM_SPM_REG_SAW2_SEQ_ENTRY]= 0x80, + [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, +}; + +static uint32_t msm_spm_reg_offsets_saw2_v3_0[MSM_SPM_REG_NR] = { + [MSM_SPM_REG_SAW2_SECURE] = 0x00, + [MSM_SPM_REG_SAW2_ID] = 0x04, + [MSM_SPM_REG_SAW2_CFG] = 0x08, + [MSM_SPM_REG_SAW2_SPM_STS] = 0x0C, + [MSM_SPM_REG_SAW2_AVS_STS] = 0x10, + [MSM_SPM_REG_SAW2_PMIC_STS] = 0x14, + [MSM_SPM_REG_SAW2_RST] = 0x18, + [MSM_SPM_REG_SAW2_VCTL] = 0x1C, + [MSM_SPM_REG_SAW2_AVS_CTL] = 0x20, + [MSM_SPM_REG_SAW2_AVS_LIMIT]= 0x24, + [MSM_SPM_REG_SAW2_AVS_DLY] = 0x28, + [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, + [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, + [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, + [MSM_SPM_REG_SAW2_STS2] = 0x38, + [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, + [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, + [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, + [MSM_SPM_REG_SAW2_PMIC_DATA_3] = 0x4C, + [MSM_SPM_REG_SAW2_PMIC_DATA_4] = 0x50, + [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, + [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, + [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, + [MSM_SPM_REG_SAW2_SEQ_ENTRY]= 0x400, + [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, +}; I don’t see what having these arrays provides as the only differences are that v3.0 has MSM_SPM_REG_SAW2_STS2 and the offset of MSM_SPM_REG_SAW2_SEQ_ENTRY. If so we can remove all this extra code and just add a simple check in msm_spm_drv_flush_seq_entry that looks at the compatible and picks the proper offset when updating MSM_SPM_REG_SAW2_SEQ_ENTRY. Isnt that an hack ? Why would it be a hack, if the only difference in the driver can be reduced down to 5 lines of code, versus what is currently there I don’t see that as a hack at all. [ snip ] diff --git a/include/soc/qcom/spm.h b/include/soc/qcom/spm.h new file mode 100644 index 000..f39e0c4 --- /dev/null +++ b/include/soc/qcom/spm.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register Can we change this to qcom,saw2-clk-div as that is what is really getting set, I know there are a few other fields in the saw2-cfg register, but I’m pretty sure we arent ever really setting those from DT. +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register Can we describe this as “spm-enable”, “spm-inhibit-start-address”, “spm-wakeup-cfg”? Also, I’m unclear why would we have a case that spm would be disabled? +- qcom,name: The name with which a SPM device is identified by the power + management code. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92 + a0 b0 03 68 70 3b 92 a0 b0 + 82 2b 50 10 30 02 22 30 0f]; + }; -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/msm-pm.c | 219 ++ include/soc/qcom/pm.h | 39 + 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/qcom/msm-pm.c create mode 100644 include/soc/qcom/pm.h diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index d7ae93b..7925f83 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_QCOM_GSBI)+=qcom_gsbi.o -obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o +obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o msm-pm.o CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/msm-pm.c b/drivers/soc/qcom/msm-pm.c new file mode 100644 index 000..f2f15b8 --- /dev/null +++ b/drivers/soc/qcom/msm-pm.c @@ -0,0 +1,219 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/init.h +#include linux/io.h +#include linux/smp.h +#include linux/tick.h +#include linux/platform_device.h +#include linux/cpu_pm.h +#include linux/uaccess.h + +#include soc/qcom/spm.h +#include soc/qcom/pm.h +#include soc/qcom/scm.h +#include soc/qcom/scm-boot.h + +#include asm/suspend.h +#include asm/cacheflush.h +#include asm/cputype.h +#include asm/system_misc.h + +#define SCM_CMD_TERMINATE_PC(0x2) +#define SCM_CMD_CORE_HOTPLUGGED (0x10) +#define SCM_FLUSH_FLAG_MASK(0x3) + +static bool msm_pm_is_L1_writeback(void) +{ +u32 cache_id = 0; + +#if defined(CONFIG_CPU_V7) +u32 sel = 0; + +asm volatile (mcr p15, 2, %[ccselr], c0, c0, 0\n\t + isb\n\t + mrc p15, 1, %[ccsidr], c0, c0, 0\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) + ); +return cache_id BIT(30); +#elif defined(CONFIG_ARM64) +u32 sel = 0; +asm volatile(msr csselr_el1, %[ccselr]\n\t + isb\n\t + mrs %[ccsidr],ccsidr_el1\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) +); +return cache_id BIT(30); +#else +#error No valid CPU arch selected +#endif +} + +static inline void msm_arch_idle(void) +{ +/* Flush and clock-gate */ +mb(); Why is needed this memory barrier ? Some QCOM SoCs needed this. I am not sure which one anymore. :( I guess this is to flush the L1 cache when the core is going down. Regarding the kernel option, it seems mb() is as dsb(), so I am wondering if this function could be simply replaced by cpu_do_idle(). +wfi(); +} + +static bool msm_pm_swfi(bool from_idle) +{ +msm_arch_idle(); +return true; +} Same here, could be replaced by cpu_do_idle(), I think. +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Thanks for the explanation in the other email. So IIUC, the SCM keeps the last state configuration and we have to set it back to clock gating, right ? I don't think it is up to this function to do this but the clock gating function. Also, this function prototype looks a bit weird. Just for the sake of using callbacks. And finally, the WARN_ON is not desirable here, except if the goal is to flood the terminal :) What not using first simple functions ? void qcom_do_idle(void) { myfirmware_call(MSM_SPM_MODE_CLOCK_GATING); wfi(); } void qcom_cpu_retention(void) { myfirmware_call(MSM_SPM_MODE_RETENTION); dsb(); wfi(); } void
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Thu, Aug 14, 2014 at 11:09:48AM -0500, Kumar Gala wrote: On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register Can we change this to qcom,saw2-clk-div as that is what is really getting set, I know there are a few other fields in the saw2-cfg register, but I’m pretty sure we arent ever really setting those from DT. I am pruning them off in the next revision of the patch. +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register Can we describe this as “spm-enable”, “spm-inhibit-start-address”, “spm-wakeup-cfg”? Also, I’m unclear why would we have a case that spm would be disabled? Much of these registers names make it easier for developers and debuggers to relate it to the hardware spec. Choosing different names here though might make it readable would convolute their efforts. +- qcom,name: The name with which a SPM device is identified by the power + management code. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92 + a0 b0 03 68 70 3b 92 a0 b0 + 82 2b 50 10 30 02 22 30 0f]; + }; -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Aug 14, 2014, at 11:18 AM, Lina Iyer lina.i...@linaro.org wrote: On Thu, Aug 14, 2014 at 11:09:48AM -0500, Kumar Gala wrote: On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register Can we change this to qcom,saw2-clk-div as that is what is really getting set, I know there are a few other fields in the saw2-cfg register, but I’m pretty sure we arent ever really setting those from DT. I am pruning them off in the next revision of the patch. +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register Can we describe this as “spm-enable”, “spm-inhibit-start-address”, “spm-wakeup-cfg”? Also, I’m unclear why would we have a case that spm would be disabled? Much of these registers names make it easier for developers and debuggers to relate it to the hardware spec. Choosing different names here though might make it readable would convolute their efforts. The point is to move away from just dumping a register value directly from DT into the device. This is pretty bad form. The names can relate to the register, etc, its just the fields that are really being used/set was the direction I was suggesting we go. +- qcom,name: The name with which a SPM device is identified by the power + management code. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92 + a0 b0 03 68 70 3b 92 a0 b0 + 82 2b 50 10 30 02 22 30 0f]; + }; -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation - k -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Fwd: Status of chipidea msm USB reset patch
Ping. Anybody know the status of this patch? Is it queued in someone's tree? Without it the USB driver for the Qualcomm 8974 (hsusb phy) doesn't work (at least for me). It looks like it got dropped from Ivan's original patch series, back in May. -- Forwarded message -- From: Tim Bird tbird...@gmail.com Date: Fri, Jul 25, 2014 at 2:38 PM Subject: Status of chipidea msm USB reset patch To: linux-arm-msm@vger.kernel.org, ba...@ti.com, Ivan T. Ivanov iiva...@mm-sol.com Ivan and Felipe, Do you know the status of the patch below? It was part of Ivan's USB patch set, which got mainlined recently. However, this patch did not show up in Linus' tree. Is it in another tree on it's way, or does it need a re-submission? I was recently testing the MSM USB gadget driver on the Dragonboard 800 (with a Qualcomm 8974 processor), and without this patch the USB hardware does not come up properly. Thanks, -- Tim Subject: [PATCH] usb: chipidea: msm: Use USB PHY API to control PHY state PHY drivers keep track of the current state of the hardware, so don't change PHY settings under it. Signed-off-by: Ivan T. Ivanov iiva...@mm-sol.com --- drivers/usb/chipidea/ci_hdrc_msm.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index d72b9d2..81de834 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -20,13 +20,11 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) { struct device *dev = ci-gadget.dev.parent; - int val; switch (event) { case CI_HDRC_CONTROLLER_RESET_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_RESET_EVENT received\n); - writel(0, USB_AHBBURST); - writel(0, USB_AHBMODE); + usb_phy_init(ci-transceiver); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_STOPPED_EVENT received\n); @@ -34,10 +32,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) * Put the transceiver in non-driving mode. Otherwise host * may not detect soft-disconnection. */ - val = usb_phy_io_read(ci-transceiver, ULPI_FUNC_CTRL); - val = ~ULPI_FUNC_CTRL_OPMODE_MASK; - val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - usb_phy_io_write(ci-transceiver, val, ULPI_FUNC_CTRL); + usb_phy_notify_disconnect(ci-transceiver, USB_SPEED_UNKNOWN); break; default: dev_dbg(dev, unknown ci_hdrc event\n); -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Fwd: Status of chipidea msm USB reset patch
Hi, On Thu, Aug 14, 2014 at 09:53:10AM -0700, Tim Bird wrote: Ping. Anybody know the status of this patch? Is it queued in someone's tree? Without it the USB driver for the Qualcomm 8974 (hsusb phy) doesn't work (at least for me). It looks like it got dropped from Ivan's original patch series, back in May. I don't maintain chipidea, Peter's the guy you want -- Forwarded message -- From: Tim Bird tbird...@gmail.com Date: Fri, Jul 25, 2014 at 2:38 PM Subject: Status of chipidea msm USB reset patch To: linux-arm-msm@vger.kernel.org, ba...@ti.com, Ivan T. Ivanov iiva...@mm-sol.com Ivan and Felipe, Do you know the status of the patch below? It was part of Ivan's USB patch set, which got mainlined recently. However, this patch did not show up in Linus' tree. Is it in another tree on it's way, or does it need a re-submission? I was recently testing the MSM USB gadget driver on the Dragonboard 800 (with a Qualcomm 8974 processor), and without this patch the USB hardware does not come up properly. Thanks, -- Tim Subject: [PATCH] usb: chipidea: msm: Use USB PHY API to control PHY state PHY drivers keep track of the current state of the hardware, so don't change PHY settings under it. Signed-off-by: Ivan T. Ivanov iiva...@mm-sol.com --- drivers/usb/chipidea/ci_hdrc_msm.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index d72b9d2..81de834 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -20,13 +20,11 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) { struct device *dev = ci-gadget.dev.parent; - int val; switch (event) { case CI_HDRC_CONTROLLER_RESET_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_RESET_EVENT received\n); - writel(0, USB_AHBBURST); - writel(0, USB_AHBMODE); + usb_phy_init(ci-transceiver); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_STOPPED_EVENT received\n); @@ -34,10 +32,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) * Put the transceiver in non-driving mode. Otherwise host * may not detect soft-disconnection. */ - val = usb_phy_io_read(ci-transceiver, ULPI_FUNC_CTRL); - val = ~ULPI_FUNC_CTRL_OPMODE_MASK; - val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - usb_phy_io_write(ci-transceiver, val, ULPI_FUNC_CTRL); + usb_phy_notify_disconnect(ci-transceiver, USB_SPEED_UNKNOWN); break; default: dev_dbg(dev, unknown ci_hdrc event\n); -- 1.8.2.2 -- balbi signature.asc Description: Digital signature
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On Thu, Aug 14, 2014 at 06:11:43PM +0200, Daniel Lezcano wrote: On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/msm-pm.c | 219 ++ include/soc/qcom/pm.h | 39 + 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/qcom/msm-pm.c create mode 100644 include/soc/qcom/pm.h diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index d7ae93b..7925f83 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_QCOM_GSBI)+=qcom_gsbi.o -obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o +obj-$(CONFIG_QCOM_PM) +=spm-devices.o spm.o msm-pm.o CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/msm-pm.c b/drivers/soc/qcom/msm-pm.c new file mode 100644 index 000..f2f15b8 --- /dev/null +++ b/drivers/soc/qcom/msm-pm.c @@ -0,0 +1,219 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/init.h +#include linux/io.h +#include linux/smp.h +#include linux/tick.h +#include linux/platform_device.h +#include linux/cpu_pm.h +#include linux/uaccess.h + +#include soc/qcom/spm.h +#include soc/qcom/pm.h +#include soc/qcom/scm.h +#include soc/qcom/scm-boot.h + +#include asm/suspend.h +#include asm/cacheflush.h +#include asm/cputype.h +#include asm/system_misc.h + +#define SCM_CMD_TERMINATE_PC(0x2) +#define SCM_CMD_CORE_HOTPLUGGED (0x10) +#define SCM_FLUSH_FLAG_MASK(0x3) + +static bool msm_pm_is_L1_writeback(void) +{ +u32 cache_id = 0; + +#if defined(CONFIG_CPU_V7) +u32 sel = 0; + +asm volatile (mcr p15, 2, %[ccselr], c0, c0, 0\n\t + isb\n\t + mrc p15, 1, %[ccsidr], c0, c0, 0\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) + ); +return cache_id BIT(30); +#elif defined(CONFIG_ARM64) +u32 sel = 0; +asm volatile(msr csselr_el1, %[ccselr]\n\t + isb\n\t + mrs %[ccsidr],ccsidr_el1\n\t + :[ccsidr]=r (cache_id) + :[ccselr]r (sel) +); +return cache_id BIT(30); +#else +#error No valid CPU arch selected +#endif +} + +static inline void msm_arch_idle(void) +{ +/* Flush and clock-gate */ +mb(); Why is needed this memory barrier ? Some QCOM SoCs needed this. I am not sure which one anymore. :( I guess this is to flush the L1 cache when the core is going down. Regarding the kernel option, it seems mb() is as dsb(), so I am wondering if this function could be simply replaced by cpu_do_idle(). Possibly could. I will do that. +wfi(); +} + +static bool msm_pm_swfi(bool from_idle) +{ +msm_arch_idle(); +return true; +} Same here, could be replaced by cpu_do_idle(), I think. +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Thanks for the explanation in the other email. So IIUC, the SCM keeps the last state configuration and we have to set it back to clock gating, right ? Correct. I don't think it is up to this function to do this but the clock gating function. Also, this function prototype looks a bit weird. Just for the sake of using callbacks. And finally, the WARN_ON is not desirable here, except if the goal is to flood the terminal :) Was debating the use of it myself. Will remove it. What not using first simple functions ? void qcom_do_idle(void) {
Re: [PATCH] ARM: apq8064: Add pinmux and i2c pinctrl nodes
On Thu, Aug 14, 2014 at 12:20 AM, Kiran Padwal kiran.pad...@smartplayin.com wrote: diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 92bf793..fbebf5c 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -70,6 +70,17 @@ ranges; compatible = simple-bus; + qcom_pinmux: pinmux@80 { There are (at least) three different pinmuxes in these platforms: TLMM, PMIC GPIO, PMIC MPP. Also this is the phandle that is used to reference the gpio chip throughout the board. So I would like to suggest that we name it tlmm or like in the downstream kernel msmgpio. + compatible = qcom,apq8064-pinctrl; + reg = 0x80 0x4000; + + gpio-controller; + #gpio-cells = 2; + interrupt-controller; + #interrupt-cells = 2; + interrupts = 0 32 0x4; I must have gotten this wrong in the dt binding example, sorry about that. interrupts should be 0 16 0x4. + }; Regards, Bjorn -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Quick question to join in development
I am a recent member of the linux-arm-msm mailing list. I'd like to know where the source of this project is located, and what branch, so I can clone and contribute. Thanks. I hope this is the correct email to post to the list, not the majordomo one. You may respond to personal, below, just please not on the list. Thank you again! Sincerely, Christopher Latham sudosuroot...@gmail.com https://github.com/sudosurootdev PERSONAL, without 1,000's in inbox: SS ROOT DEV 'AT' GMAIL 'DOT' 'COM' ... WITH NO SPACES -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] pinctrl: qcom: apq8064: Correct interrupts in example
The example in the binding document indicates that interrupt 32 is used for the TLMM summary IRQ. Correct this to reduce the confusion. Signed-off-by: Bjorn Andersson bjorn.anders...@sonymobile.com --- .../bindings/pinctrl/qcom,apq8064-pinctrl.txt |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt index 0211c6d..92fae82 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt @@ -62,7 +62,7 @@ Example: #gpio-cells = 2; interrupt-controller; #interrupt-cells = 2; - interrupts = 0 32 0x4; + interrupts = 0 16 0x4; pinctrl-names = default; pinctrl-0 = gsbi5_uart_default; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On 08/14/2014 09:22 PM, Lina Iyer wrote: On Thu, Aug 14, 2014 at 06:11:43PM +0200, Daniel Lezcano wrote: On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- [ ... ] +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Thanks for the explanation in the other email. So IIUC, the SCM keeps the last state configuration and we have to set it back to clock gating, right ? Correct. I don't think it is up to this function to do this but the clock gating function. Also, this function prototype looks a bit weird. Just for the sake of using callbacks. And finally, the WARN_ON is not desirable here, except if the goal is to flood the terminal :) Was debating the use of it myself. Will remove it. What not using first simple functions ? void qcom_do_idle(void) { myfirmware_call(MSM_SPM_MODE_CLOCK_GATING); wfi(); } void qcom_cpu_retention(void) { myfirmware_call(MSM_SPM_MODE_RETENTION); dsb(); wfi(); } void qcom_cpu_powerdown(int flags) { scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC, flag); } and then you build on top of that the cpuidle driver. Okay. Will do this The patchset adds all the features in one shot and for someone not used with the platform it is really hard to follow all the code. I suggest you write a simple cpuidle driver based on the DT Lorenzo patches bringing the clock gating, then another patchset with the retention mode, etc ... Do you agree with this approach ? +return true; +} + +static int msm_pm_collapse(unsigned long from_idle) +{ +enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON; + +/** + * Single core processors need to have L2 + * flushed when powering down the core. + * Notify SCM to flush secure L2 lines. + */ +if (num_possible_cpus() == 1) +flag = MSM_SCM_L2_OFF; I am wondering if this shouldn't be handle by a mcpm driver. Cc nico. Well, possibly, sorry, not sure what features of the mcpm driver you think I need here? Please correct me if I am wrong. IIUC, this function is checking the number of the cpus of the cluster in order to flush the L2 cache because the SCM will power down the cluster if it is the last one, right ? Nope. Some QCOM variants which have a single CPU, cannot be powered down without flushing the caches. Warm boot of the cpu resets the L2 logic as well. The cluster core is lot more complex than this :) Ok, probably we can discuss this later when we reach this state in the incremental implementation. Thanks -- Daniel -- http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs Follow Linaro: http://www.facebook.com/pages/Linaro Facebook | http://twitter.com/#!/linaroorg Twitter | http://www.linaro.org/linaro-blog/ Blog -- http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs Follow Linaro: http://www.facebook.com/pages/Linaro Facebook | http://twitter.com/#!/linaroorg Twitter | http://www.linaro.org/linaro-blog/ Blog -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 1/3] mfd: devicetree: bindings: Add Qualcomm RPM DT binding
On Tue 12 Aug 10:43 PDT 2014, Kumar Gala wrote: On Aug 11, 2014, at 5:43 PM, Bjorn Andersson bjorn.anders...@sonymobile.com wrote: [...] diff --git a/Documentation/devicetree/bindings/mfd/qcom,rpm.txt b/Documentation/devicetree/bindings/mfd/qcom,rpm.txt [...] +- reg: + Usage: required + Value type: prop-encoded-array + Definition: two entries specifying the physical address and size of the + RPM's message ram I’m a little confused here, by ‘two entries’ do you mean two values or really two regions? A B or A B C D ? Hmm, I agree with you, but I'm not sure what the definition of an entry is in this context and looking around at other bindings makes me wonder even more. How about we reduce the confusion by dropping the beginning and letting it be the physical address and size of...? + [...] + +- qcom,ipc: + Usage: required + Value type: prop-encoded-array + Definition: three entries specifying: + - phandle to a syscon node representing the apcs registers + - u32 representing offset to the register within the syscon + - u32 representing the ipc bit within the register Can we clarify that this is ipc from Apps (or ARM processors to RPM) Makes sense + + += SUBDEVICES These should not be children of RPM, but in an RPM container outside of the SoC node with some phandle reference (if needed) to the RPM. The reason is there isn’t really a technical means to translate from the SoC / MMIO bus address space to the RPM address space that these nodes live in. I don't agree with this; the regulators, clocks and bus-scalers aren't components on their own but just parts of the RPM. Your argument indicates that every pmic, i2c, spi... block got this wrong, I think we should better follow the pattern defined by the rest of these. One thing that I think should be fixed though is to rename SUBDEVICES to SUBNODES as devices is an implementation detail in my solution. Also, the binding specs should be split out into their own files. Not according to Rob Herring: https://lkml.org/lkml/2014/3/10/567 + +The RPM exposes resources to its subnodes. The below bindings specify the set +of valid subnodes that can operate on these resources. + +== Switch-mode Power Supply regulator + [...] +- reg: + Usage: required + Value type: u32 + Definition: resource as defined in dt-bindings/mfd/qcom,rpm.h + Can we spec what subset of values in qcom,rpm.h are actually valid? Yes, sorry about not improving this part. [...] +- qcom,switch-mode-frequency: + Usage: required + Value type: u32 + Definition: Frequency (Hz) of the switch-mode power supply; + must be one of: + 1920, 960, 640, 480, 384, 320, + 274, 240, 213, 192, 175, 160, + 148, 137, 128, 120 + +- qcom,force-mode-none: I think I asked this last time I took a look at this, but can we have multiple force-mode’s set? If no, maybe this should be an enum instead. No, they are mutually exclusive. I just like the boolean representation instead, but I can change it to an enum and provide some constants in the header file. Looking through msm-3.4 almost everything seems to be using force mode none, with a few uses of auto. So if we turn it into an enum then we could specify none in the platform dtsi (or don't specifying anything?) and only have to override it in the very few places it needs to be anything else. + Usage: optional (default if no other qcom,force-mode is specified) + Value type: empty + Defintion: indicates that the regulator should not be forced to any +particular mode + +- qcom,force-mode-lpm: + Usage: optional + Value type: empty + Definition: indicates that the regulator should be forced to operate in + low-power-mode + +- qcom,force-mode-auto: + Usage: optional (only available for 8960/8064) can we say only available for qcom,rpm-msm8960”, qcom,rpm-apq8064 Indeed. + Value type: empty + Definition: indicates that the regulator should be automatically pick + operating mode + +- qcom,force-mode-hpm: + Usage: optional (only available for 8960/8064) can we say only available for qcom,rpm-msm8960”, qcom,rpm-apq8064 Indeed. + Value type: empty + Definition: indicates that the regulator should be forced to operate in + high-power-mode + +- qcom,force-mode-bypass: (only for 8960/8064) + Usage: optional (only available for 8960/8064) can we say only available for qcom,rpm-msm8960”, qcom,rpm-apq8064 Indeed. + Value type: empty + Definition: indicates that the regulator should be forced to operate
Re: Fwd: Status of chipidea msm USB reset patch
On Thu, Aug 14, 2014 at 11:54:02AM -0500, Felipe Balbi wrote: Hi, On Thu, Aug 14, 2014 at 09:53:10AM -0700, Tim Bird wrote: Ping. Anybody know the status of this patch? Is it queued in someone's tree? Without it the USB driver for the Qualcomm 8974 (hsusb phy) doesn't work (at least for me). It looks like it got dropped from Ivan's original patch series, back in May. I don't maintain chipidea, Peter's the guy you want Below patch was not at msm chipidea patchset Ivan sent me. http://markmail.org/search/?q=%5BPATCH+v4+0%2F3%5D+usb%3A+chipidea%3A+msm%3A+Clean+and+fix+#query:%5BPATCH%20v4%200%2F3%5D%20usb%3A%20chipidea%3A%20msm%3A%20Clean%20and%20fix%20from%3A%22Ivan%20T.%20Ivanov%22+page:1+mid:mt7hgr7yamyzegg3+state:results Peter -- Forwarded message -- From: Tim Bird tbird...@gmail.com Date: Fri, Jul 25, 2014 at 2:38 PM Subject: Status of chipidea msm USB reset patch To: linux-arm-msm@vger.kernel.org, ba...@ti.com, Ivan T. Ivanov iiva...@mm-sol.com Ivan and Felipe, Do you know the status of the patch below? It was part of Ivan's USB patch set, which got mainlined recently. However, this patch did not show up in Linus' tree. Is it in another tree on it's way, or does it need a re-submission? I was recently testing the MSM USB gadget driver on the Dragonboard 800 (with a Qualcomm 8974 processor), and without this patch the USB hardware does not come up properly. Thanks, -- Tim Subject: [PATCH] usb: chipidea: msm: Use USB PHY API to control PHY state PHY drivers keep track of the current state of the hardware, so don't change PHY settings under it. Signed-off-by: Ivan T. Ivanov iiva...@mm-sol.com --- drivers/usb/chipidea/ci_hdrc_msm.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index d72b9d2..81de834 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -20,13 +20,11 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) { struct device *dev = ci-gadget.dev.parent; - int val; switch (event) { case CI_HDRC_CONTROLLER_RESET_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_RESET_EVENT received\n); - writel(0, USB_AHBBURST); - writel(0, USB_AHBMODE); + usb_phy_init(ci-transceiver); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, CI_HDRC_CONTROLLER_STOPPED_EVENT received\n); @@ -34,10 +32,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) * Put the transceiver in non-driving mode. Otherwise host * may not detect soft-disconnection. */ - val = usb_phy_io_read(ci-transceiver, ULPI_FUNC_CTRL); - val = ~ULPI_FUNC_CTRL_OPMODE_MASK; - val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - usb_phy_io_write(ci-transceiver, val, ULPI_FUNC_CTRL); + usb_phy_notify_disconnect(ci-transceiver, USB_SPEED_UNKNOWN); break; default: dev_dbg(dev, unknown ci_hdrc event\n); -- 1.8.2.2 -- balbi -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: To otg-fsm or not to otg-fsm? That is the question.
On Tue, Aug 12, 2014 at 09:13:47AM -0700, Tim Bird wrote: On Mon, Aug 11, 2014 at 5:28 PM, Peter Chen peter.c...@freescale.com wrote: The OTG FSM at /usb/common/usb-otg-fsm.c is a software OTG FSM implementation which follows On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification (Revision 2.0 version 1.1a) Chapter 7 State Diagrams. If the platform doesn't support hardware otg fsm, it should follow above fsm implementation since it follows the newest OTG EH spec. Besides, as far as I know, the qualcomm uses chipidea core for its usb2, then it should be easy for qualcomm using this common otg fsm implementation. OK. sounds good. Yes, the qualcomm chips use a chipidea core for usb2. The main difficulty, IMHO, will be mapping the qcom charger state machine onto the generic OTG state machine implementation in usb-otg-fsm. I'm not sure if I'll be able to embed the needed functionality into the existing functions called by the generic state machine, or if I'll need to add some new entries to the function table to handle this extra logic. I'll probably try to get the driver working without the charger stuff first, and then, once I have a better idea of how the state machines map, try adding the charger stuff. If I feel like I need to modify the generic state machine, I'll ask on list. I'm a newbie at USB stuff and I don't want to break anything. Thanks. One remind, you may need to know which role-switch function you need, if you only need role-switch based in ID pin, then no OTG FSM support is needed, this is current most of OTG device supports, it is not fully OTG compliance. -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
On Fri, Aug 15, 2014 at 02:01:47AM +0200, Daniel Lezcano wrote: On 08/14/2014 09:22 PM, Lina Iyer wrote: On Thu, Aug 14, 2014 at 06:11:43PM +0200, Daniel Lezcano wrote: On 08/13/2014 04:16 PM, Lina Iyer wrote: On Wed, Aug 13, 2014 at 01:18:01PM +0200, Daniel Lezcano wrote: On 08/12/2014 09:43 PM, Lina Iyer wrote: Add interface layer to abstract and handle hardware specific functionality for executing various cpu low power modes in QCOM chipsets. Signed-off-by: Venkat Devarasetty vdeva...@codeaurora.org Signed-off-by: Mahesh Sivasubramanian msiva...@codeaurora.org Signed-off-by: Lina Iyer lina.i...@linaro.org --- [ ... ] +static bool msm_pm_retention(bool from_idle) +{ +int ret = 0; + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false); +WARN_ON(ret); + +msm_arch_idle(); + +ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); +WARN_ON(ret); Why do you need to set the clock gating mode each time you exit the retention mode ? So if the SPM did not reset to clockgating, we would not do retention when we intended to do clockgating. Btw, we dont set clockgating everytime we do clockgating, helps reduce the latency in doing WFI. Thanks for the explanation in the other email. So IIUC, the SCM keeps the last state configuration and we have to set it back to clock gating, right ? Correct. I don't think it is up to this function to do this but the clock gating function. Also, this function prototype looks a bit weird. Just for the sake of using callbacks. And finally, the WARN_ON is not desirable here, except if the goal is to flood the terminal :) Was debating the use of it myself. Will remove it. What not using first simple functions ? void qcom_do_idle(void) { myfirmware_call(MSM_SPM_MODE_CLOCK_GATING); wfi(); } void qcom_cpu_retention(void) { myfirmware_call(MSM_SPM_MODE_RETENTION); dsb(); wfi(); } void qcom_cpu_powerdown(int flags) { scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC, flag); } and then you build on top of that the cpuidle driver. Okay. Will do this The patchset adds all the features in one shot and for someone not used with the platform it is really hard to follow all the code. I suggest you write a simple cpuidle driver based on the DT Lorenzo patches bringing the clock gating, then another patchset with the retention mode, etc ... Do you agree with this approach ? Yes, have a working patch with the code cleaned out as you suggested. Looking at Lorenzo's DT changes and a few SPM driver clean ups. Will submit a patch revision soon. +return true; +} + +static int msm_pm_collapse(unsigned long from_idle) +{ +enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON; + +/** + * Single core processors need to have L2 + * flushed when powering down the core. + * Notify SCM to flush secure L2 lines. + */ +if (num_possible_cpus() == 1) +flag = MSM_SCM_L2_OFF; I am wondering if this shouldn't be handle by a mcpm driver. Cc nico. Well, possibly, sorry, not sure what features of the mcpm driver you think I need here? Please correct me if I am wrong. IIUC, this function is checking the number of the cpus of the cluster in order to flush the L2 cache because the SCM will power down the cluster if it is the last one, right ? Nope. Some QCOM variants which have a single CPU, cannot be powered down without flushing the caches. Warm boot of the cpu resets the L2 logic as well. The cluster core is lot more complex than this :) Ok, probably we can discuss this later when we reach this state in the incremental implementation. Hmm, yeah. Thanks -- Daniel -- http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs Follow Linaro: http://www.facebook.com/pages/Linaro Facebook | http://twitter.com/#!/linaroorg Twitter | http://www.linaro.org/linaro-blog/ Blog -- http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs Follow Linaro: http://www.facebook.com/pages/Linaro Facebook | http://twitter.com/#!/linaroorg Twitter | http://www.linaro.org/linaro-blog/ Blog -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets
On Thu, Aug 14, 2014 at 11:41:39AM -0500, Kumar Gala wrote: On Aug 14, 2014, at 11:18 AM, Lina Iyer lina.i...@linaro.org wrote: On Thu, Aug 14, 2014 at 11:09:48AM -0500, Kumar Gala wrote: On Aug 12, 2014, at 2:43 PM, Lina Iyer lina.i...@linaro.org wrote: diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt new file mode 100644 index 000..3130f4b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt @@ -0,0 +1,62 @@ +* MSM Subsystem Power Manager (spm-v2) + +S4 generation of MSMs have SPM hardware blocks to control the Application +Processor Sub-System power. These SPM blocks run individual state machine +to determine what the core (L2 or Krait/Scorpion) would do when the WFI +instruction is executed by the core. + +The devicetree representation of the SPM block should be: + +Required properties + +- compatible: Could be one of - + qcom,spm-v2.1 + qcom,spm-v3.0 +- reg: The physical address and the size of the SPM's memory mapped registers +- qcom,cpu: phandle for the CPU that the SPM block is attached to. On targets + that dont support CPU phandles the driver would support qcom,core-id. + This field is required on only for SPMs that control the CPU. +- qcom,saw2-cfg: SAW2 configuration register Can we change this to qcom,saw2-clk-div as that is what is really getting set, I know there are a few other fields in the saw2-cfg register, but I’m pretty sure we arent ever really setting those from DT. I am pruning them off in the next revision of the patch. +- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM + sequence +- qcom,saw2-spm-ctl: The SPM control register Can we describe this as “spm-enable”, “spm-inhibit-start-address”, “spm-wakeup-cfg”? Also, I’m unclear why would we have a case that spm would be disabled? SPM would mostly be disabled for debug reasons or if there was a version of the hardware tht needed hardware to be disabled. In general, it wouldnt be. Much of these registers names make it easier for developers and debuggers to relate it to the hardware spec. Choosing different names here though might make it readable would convolute their efforts. The point is to move away from just dumping a register value directly from DT into the device. This is pretty bad form. The names can relate to the register, etc, its just the fields that are really being used/set was the direction I was suggesting we go. Hmm. I see. Let me if I can address that.. There may be some registers where I may not have such a luxury, will give it a try. +- qcom,name: The name with which a SPM device is identified by the power + management code. + +Optional properties + +- qcom,saw2-pmic-data0..7: Specify the pmic data value and the associated FTS + (Fast Transient Switch) index to send the PMIC data to +- qcom,vctl-port: The PVC (PMIC Virtual Channel) port used for changing + voltage +- qcom,phase-port: The PVC port used for changing the number of phases +- qcom,pfm-port: The PVC port used for enabling PWM/PFM modes +- qcom,saw2-spm-cmd-wfi: The WFI command sequence +- qcom,saw2-spm-cmd-ret: The Retention command sequence +- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence +- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS + proc won't inform the RPM. +- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may + turn off other SoC components. +- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command + sequence. This sequence will retain the memory but turn off the logic. +- qcom,cpu-vctl-list: List of cpu node phandles, whose voltage the spm device + can control. +- qcom,vctl-timeout-us: The timeout value in microseconds to wait for voltage to + change after sending the voltage command to the PMIC. +- +Example: + qcom,spm@f9089000 { + compatible = qcom,spm-v2; + #address-cells = 1; + #size-cells = 1; + reg = 0xf9089000 0x1000; + qcom,cpu = CPU0; + qcom,saw2-cfg = 0x1; + qcom,saw2-spm-dly= 0x2400; + qcom,saw2-spm-ctl = 0x1; + qcom,saw2-spm-cmd-wfi = [03 0b 0f]; + qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92 + a0 b0 03 68 70 3b 92 a0 b0 + 82 2b 50 10 30 02 22 30 0f]; + }; -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation - k -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to