[PATCH v2] mfd: qcom-rpm: Add apq8064 QDSS clock resource
Qualcomm Debug Subsystem clock is used by CoreSight components. Add required definitions for it. qcom_rpm_resource::status_id is not used by driver, so just mark it as ~0. Signed-off-by: Ivan T. Ivanov ivan.iva...@linaro.org --- Changes since first version: * Use ~0 initializer for status_id, this field is not used by driver. drivers/mfd/qcom_rpm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c index 12e3243..6afc9fa 100644 --- a/drivers/mfd/qcom_rpm.c +++ b/drivers/mfd/qcom_rpm.c @@ -149,6 +149,7 @@ static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = { [QCOM_RPM_USB_OTG_SWITCH] = { 210, 125, 82, 1 }, [QCOM_RPM_HDMI_SWITCH] ={ 211, 126, 83, 1 }, [QCOM_RPM_DDR_DMM] ={ 212, 127, 84, 2 }, + [QCOM_RPM_QDSS_CLK] = { 214, ~0, 7, 1 }, [QCOM_RPM_VDDMIN_GPIO] ={ 215, 131, 89, 1 }, }; -- 1.9.1 -- 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] usb: phy: msm: Add D+/D- lines route control
apq8016-sbc board is using Dual SPDT USB Switch (TC7USB40MU), witch is controlled by GPIO to de/multiplex D+/D- USB lines to USB2513B Hub and uB connector. Add support for this. Signed-off-by: Ivan T. Ivanov ivan.iva...@linaro.org --- .../devicetree/bindings/usb/msm-hsusb.txt | 4 ++ drivers/usb/phy/phy-msm-usb.c | 47 ++ include/linux/usb/msm_hsusb.h | 7 3 files changed, 58 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index bd8d9e7..8654a3e 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt @@ -52,6 +52,10 @@ Required properties: Optional properties: - dr_mode: One of host, peripheral or otg. Defaults to otg +- switch-gpio: A phandle + gpio-specifier pair. Some boards are using Dual +SPDT USB Switch, witch is cotrolled by GPIO to de/multiplex +D+/D- USB lines between connectors. + - qcom,phy-init-sequence: PHY configuration sequence values. This is related to Device Mode Eye Diagram test. Start address at which these values will be written is ULPI_EXT_VENDOR_SPECIFIC. Value of -1 is reserved as diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 00c49bb..57c75fb 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -18,6 +18,7 @@ #include linux/module.h #include linux/device.h +#include linux/gpio/consumer.h #include linux/platform_device.h #include linux/clk.h #include linux/slab.h @@ -32,6 +33,7 @@ #include linux/pm_runtime.h #include linux/of.h #include linux/of_device.h +#include linux/reboot.h #include linux/reset.h #include linux/usb.h @@ -1471,6 +1473,14 @@ static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event, else clear_bit(B_SESS_VLD, motg-inputs); + if (test_bit(B_SESS_VLD, motg-inputs)) { + /* Switch D+/D- lines to Device connector */ + gpiod_set_value_cansleep(motg-switch_gpio, 0); + } else { + /* Switch D+/D- lines to Hub */ + gpiod_set_value_cansleep(motg-switch_gpio, 1); + } + schedule_work(motg-sm_work); return NOTIFY_DONE; @@ -1546,6 +1556,11 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) motg-manual_pullup = of_property_read_bool(node, qcom,manual-pullup); + motg-switch_gpio = devm_gpiod_get_optional(pdev-dev, switch, + GPIOD_OUT_LOW); + if (IS_ERR(motg-switch_gpio)) + return PTR_ERR(motg-switch_gpio); + ext_id = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV); if (of_property_read_bool(node, extcon)) { @@ -1615,6 +1630,19 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) return 0; } +static int msm_otg_reboot_notify(struct notifier_block *this, +unsigned long code, void *unused) +{ + struct msm_otg *motg = container_of(this, struct msm_otg, reboot); + + /* +* Ensure that D+/D- lines are routed to uB connector, so +* we could load bootloader/kernel at next reboot +*/ + gpiod_set_value_cansleep(motg-switch_gpio, 0); + return NOTIFY_DONE; +} + static int msm_otg_probe(struct platform_device *pdev) { struct regulator_bulk_data regs[3]; @@ -1779,6 +1807,17 @@ static int msm_otg_probe(struct platform_device *pdev) dev_dbg(pdev-dev, Can not create mode change file\n); } + if (test_bit(B_SESS_VLD, motg-inputs)) { + /* Switch D+/D- lines to Device connector */ + gpiod_set_value_cansleep(motg-switch_gpio, 0); + } else { + /* Switch D+/D- lines to Hub */ + gpiod_set_value_cansleep(motg-switch_gpio, 1); + } + + motg-reboot.notifier_call = msm_otg_reboot_notify; + register_reboot_notifier(motg-reboot); + pm_runtime_set_active(pdev-dev); pm_runtime_enable(pdev-dev); @@ -1805,11 +1844,19 @@ static int msm_otg_remove(struct platform_device *pdev) if (phy-otg-host || phy-otg-gadget) return -EBUSY; + unregister_reboot_notifier(motg-reboot); + if (motg-id.conn.edev) extcon_unregister_interest(motg-id.conn); if (motg-vbus.conn.edev) extcon_unregister_interest(motg-vbus.conn); + /* +* Ensure that D+/D- lines are routed to uB connector, so +* we could load bootloader/kernel at next reboot +*/ + gpiod_set_value_cansleep(motg-switch_gpio, 0); + msm_otg_debugfs_cleanup(); cancel_delayed_work_sync(motg-chg_work); cancel_work_sync(motg-sm_work);
[PATCH 7/9] arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes
Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- arch/arm/boot/dts/qcom-apq8064.dtsi | 108 1 file changed, 108 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index df2061e..c06e59f 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -76,6 +76,88 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 7; + + trips { + cpu_alert0: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit0: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 8; + + trips { + cpu_alert1: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit1: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal2 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 9; + + trips { + cpu_alert2: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit2: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal3 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 10; + + trips { + cpu_alert3: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit3: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + }; + cpu-pmu { compatible = qcom,krait-pmu; interrupts = 1 10 0x304; @@ -289,11 +371,37 @@ qcom,controller-type = pmic-arbiter; }; + qfprom: qfprom@0070 { + compatible = qcom,qfprom; + reg = 0x0070 0x1000; + #address-cells = 1; + #size-cells = 1; + ranges; + tsens_calib: calib { + reg = 0x404 0x10; + }; + tsens_backup: backup_calib { + reg = 0x414 0x10; + }; + }; + gcc: clock-controller@90 { compatible = qcom,gcc-apq8064; reg = 0x0090 0x4000; #clock-cells = 1; #reset-cells = 1; + #address-cells = 1; + #size-cells = 1; + ranges; + + tsens: thermal-sensor@90 { + compatible = qcom,msm8960-tsens; + nvmem-cell = tsens_calib, tsens_backup; +
[PATCH 2/9] thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
Add support to calibrate sensors on 8916 family and also add common functions to read temperature from sensors (This can be reused on other SoCs having similar TSENS device) The calibration data is read from eeprom using the generic eeprom framework apis. Based on the original code by Siddartha Mohanadoss and Stephen Boyd. Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- drivers/thermal/qcom/Makefile | 2 +- drivers/thermal/qcom/tsens-8916.c | 107 ++ drivers/thermal/qcom/tsens-common.c | 128 drivers/thermal/qcom/tsens.h| 11 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 drivers/thermal/qcom/tsens-8916.c create mode 100644 drivers/thermal/qcom/tsens-common.c diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index 401069b..05c98e4 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o -qcom_tsens-y += tsens.o +qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c new file mode 100644 index 000..a69aea3 --- /dev/null +++ b/drivers/thermal/qcom/tsens-8916.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, 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/platform_device.h +#include tsens.h + +/* eeprom layout data for 8916 */ +#define BASE0_MASK 0x007f +#define BASE1_MASK 0xfe00 +#define BASE0_SHIFT0 +#define BASE1_SHIFT25 + +#define S0_P1_MASK 0x0f80 +#define S1_P1_MASK 0x003e +#define S2_P1_MASK 0xf800 +#define S3_P1_MASK 0x03e0 +#define S4_P1_MASK 0x000f8000 + +#define S0_P2_MASK 0x0001f000 +#define S1_P2_MASK 0x07c0 +#define S2_P2_MASK 0x001f +#define S3_P2_MASK 0x7c00 +#define S4_P2_MASK 0x01f0 + +#define S0_P1_SHIFT7 +#define S1_P1_SHIFT17 +#define S2_P1_SHIFT27 +#define S3_P1_SHIFT5 +#define S4_P1_SHIFT15 + +#define S0_P2_SHIFT12 +#define S1_P2_SHIFT22 +#define S2_P2_SHIFT0 +#define S3_P2_SHIFT10 +#define S4_P2_SHIFT20 + +#define CAL_SEL_MASK 0xe000 +#define CAL_SEL_SHIFT 29 + +static int calibrate_8916(struct tsens_device *tmdev) +{ + int base0 = 0, base1 = 0, i; + u32 p1[5], p2[5]; + int mode = 0; + u32 *qfprom_cdata, *qfprom_csel; + + qfprom_cdata = (u32 *)qfprom_read(tmdev-dev, calib); + if (IS_ERR(qfprom_cdata)) + return PTR_ERR(qfprom_cdata); + + qfprom_csel = (u32 *)qfprom_read(tmdev-dev, calib_sel); + if (IS_ERR(qfprom_csel)) + return PTR_ERR(qfprom_csel); + + mode = (qfprom_csel[0] CAL_SEL_MASK) CAL_SEL_SHIFT; + dev_dbg(tmdev-dev, calibration mode is %d\n, mode); + + switch (mode) { + case TWO_PT_CALIB: + base1 = (qfprom_cdata[1] BASE1_MASK) BASE1_SHIFT; + p2[0] = (qfprom_cdata[0] S0_P2_MASK) S0_P2_SHIFT; + p2[1] = (qfprom_cdata[0] S1_P2_MASK) S1_P2_SHIFT; + p2[2] = (qfprom_cdata[1] S2_P2_MASK) S2_P2_SHIFT; + p2[3] = (qfprom_cdata[1] S3_P2_MASK) S3_P2_SHIFT; + p2[4] = (qfprom_cdata[1] S4_P2_MASK) S4_P2_SHIFT; + for (i = 0; i tmdev-num_sensors; i++) + p2[i] = ((base1 + p2[i]) 3); + /* Fall through */ + case ONE_PT_CALIB2: + base0 = (qfprom_cdata[0] BASE0_MASK); + p1[0] = (qfprom_cdata[0] S0_P1_MASK) S0_P1_SHIFT; + p1[1] = (qfprom_cdata[0] S1_P1_MASK) S1_P1_SHIFT; + p1[2] = (qfprom_cdata[0] S2_P1_MASK) S2_P1_SHIFT; + p1[3] = (qfprom_cdata[1] S3_P1_MASK) S3_P1_SHIFT; + p1[4] = (qfprom_cdata[1] S4_P1_MASK) S4_P1_SHIFT; + for (i = 0; i tmdev-num_sensors; i++) + p1[i] = (((base0) + p1[i]) 3); + break; + default: + for (i = 0; i tmdev-num_sensors; i++) { + p1[i] = 500; + p2[i] = 780; + } + break; + } + + compute_intercept_slope(tmdev, p1, p2, mode); + + return 0; +} + +const struct tsens_ops ops_8916 = { + .init = init_common, + .calibrate = calibrate_8916, + .get_temp = get_temp_common,
[PATCH 4/9] thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
8960 family of SoCs have the TSENS device as part of a domain thats not always ON. Hence add .suspend and .resume hooks to save and restore some of the inited register context. 8960 family has TSENS as part of GCC, hence reuse the GCC regmap. Also 8960 family had some of the TSENS init sequence thats required to be done by the HLOS driver (some later versions of TSENS do not export these registers to non-secure world, and hence need these initializations to be done by secure bootloaders) 8660 from the same family has just one sensor and hence some register offset/layout differences which need special handling in the driver. Based on the original code from Siddartha Mohanadoss, Stephen Boyd and Narendran Rajan. Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- drivers/thermal/qcom/Makefile | 2 +- drivers/thermal/qcom/tsens-8960.c | 291 ++ drivers/thermal/qcom/tsens.c | 1 + drivers/thermal/qcom/tsens.h | 2 +- 4 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 drivers/thermal/qcom/tsens-8960.c diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index a471100..f3cefd1 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o -qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o +qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c new file mode 100644 index 000..1b98e22 --- /dev/null +++ b/drivers/thermal/qcom/tsens-8960.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2015, 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/platform_device.h +#include linux/delay.h +#include linux/bitops.h +#include linux/regmap.h +#include tsens.h + +#define CAL_MDEGC 3 + +#define CONFIG_ADDR0x3640 +#define CONFIG_ADDR_8660 0x3620 +/* CONFIG_ADDR bitmasks */ +#define CONFIG 0x9b +#define CONFIG_MASK0xf +#define CONFIG_86601 +#define CONFIG_SHIFT_8660 28 +#define CONFIG_MASK_8660 (3 CONFIG_SHIFT_8660) + +#define STATUS_CNTL_ADDR_8064 0x3660 +#define CNTL_ADDR 0x3620 +/* CNTL_ADDR bitmasks */ +#define EN BIT(0) +#define SW_RST BIT(1) +#define SENSOR0_EN BIT(3) +#define SLP_CLK_ENABIT(26) +#define SLP_CLK_ENA_8660 BIT(24) +#define MEASURE_PERIOD 1 +#define SENSOR0_SHIFT 3 + +/* INT_STATUS_ADDR bitmasks */ +#define MIN_STATUS_MASKBIT(0) +#define LOWER_STATUS_CLR BIT(1) +#define UPPER_STATUS_CLR BIT(2) +#define MAX_STATUS_MASKBIT(3) + +#define THRESHOLD_ADDR 0x3624 +/* THRESHOLD_ADDR bitmasks */ +#define THRESHOLD_MAX_LIMIT_SHIFT 24 +#define THRESHOLD_MIN_LIMIT_SHIFT 16 +#define THRESHOLD_UPPER_LIMIT_SHIFT8 +#define THRESHOLD_LOWER_LIMIT_SHIFT0 + +/* Initial temperature threshold values */ +#define LOWER_LIMIT_TH 0x50 +#define UPPER_LIMIT_TH 0xdf +#define MIN_LIMIT_TH 0x0 +#define MAX_LIMIT_TH 0xff + +#define S0_STATUS_ADDR 0x3628 +#define INT_STATUS_ADDR0x363c +#define TRDY_MASK BIT(7) + +static int suspend_8960(struct tsens_device *tmdev) +{ + int ret; + unsigned int mask; + struct regmap *map = tmdev-map; + + ret = regmap_read(map, THRESHOLD_ADDR, tmdev-ctx.threshold); + if (ret) + return ret; + + ret = regmap_read(map, CNTL_ADDR, tmdev-ctx.control); + if (ret) + return ret; + + if (tmdev-num_sensors 1) + mask = SLP_CLK_ENA | EN; + else + mask = SLP_CLK_ENA_8660 | EN; + + ret = regmap_update_bits(map, CNTL_ADDR, mask, 0); + if (ret) + return ret; + + tmdev-trdy = false; + + return 0; +} + +static int resume_8960(struct tsens_device *tmdev) +{ + int ret; + unsigned long reg_cntl; + struct regmap *map = tmdev-map; + + ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST); + if (ret) + return ret; + + /* +* Separate CONFIG restore is not needed only for 8660 as +* config is part of CTRL Addr and its restored as such +*/ + if (tmdev-num_sensors 1) { +
[PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers
TSENS is Qualcomms' thermal temperature sensor device. It supports reading temperatures from multiple thermal sensors present on various QCOM SoCs. Calibration data is generally read from a eeprom device. Add a skeleton driver with all the necessary abstractions so a variety of qcom device families which support TSENS can add driver extensions. Also add the required device tree bindings which can be used to descibe the TSENS device in DT. Signed-off-by: Rajendra Nayak rna...@codeaurora.org Reviewed-by: Lina Iyer lina.i...@linaro.org --- .../devicetree/bindings/thermal/qcom-tsens.txt | 37 drivers/thermal/Kconfig| 5 + drivers/thermal/Makefile | 1 + drivers/thermal/qcom/Kconfig | 10 + drivers/thermal/qcom/Makefile | 2 + drivers/thermal/qcom/tsens.c | 207 + drivers/thermal/qcom/tsens.h | 58 ++ 7 files changed, 320 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt create mode 100644 drivers/thermal/qcom/Kconfig create mode 100644 drivers/thermal/qcom/Makefile create mode 100644 drivers/thermal/qcom/tsens.c create mode 100644 drivers/thermal/qcom/tsens.h diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt new file mode 100644 index 000..cfb79fc --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt @@ -0,0 +1,37 @@ +* QCOM SoC Temperature Sensor (TSENS) + +Required properties: +- compatible : + - qcom,msm8916-tsens : For 8916 Family of SoCs + - qcom,msm8974-tsens : For 8974 Family of SoCs + - qcom,msm8960-tsens : For 8960 Family of SoCs + +- reg: Address range of the thermal registers +- qcom,tsens-slopes : Must contain slope value for each of the sensors controlled + by this device +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. +- Refer to Documentation/devicetree/bindings/eeprom/eeprom.txt to know how to specify +an eeprom cell + +Optional properties: +- qcom,sensor-id: List of sensor instances used in a given SoC. A TSENS IP can + have a fixed number of sensors (like 11) but a given SoC can + use only 5 of these and they might not always the first 5. They + could be sensors 0, 1, 4, 8 and 9. This property is used to + describe the subset of the sensors used. If this property is + missing they are assumed to be the first 'n' sensors numbered + sequentially in which case the number of sensors defaults to + the number of slope values. + +Example: +tsens: thermal-sensor@90 { + compatible = qcom,msm8916-tsens; + qcom,tsens-slopes = 1176 1176 1154 1176 + 1132 1132 1199 1132 1199 + 1132; + calib_data = tsens_caldata; + calib_sel = tsens_calsel; + qcom,tsens-slopes = 3200 3200 3200 3200 3200; + qcom,sensor-id = 0 1 2 4 5; + #thermal-sensor-cells = 1; + }; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 118938e..8f47021 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -365,4 +365,9 @@ config QCOM_SPMI_TEMP_ALARM real time die temperature if an ADC is present or an estimate of the temperature based upon the over temperature stage value. +menu Qualcomm thermal drivers +depends on ARCH_QCOM OF +source drivers/thermal/qcom/Kconfig +endmenu + endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 535dfee..011fa57 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_ST_THERMAL) += st/ +obj-$(CONFIG_QCOM_TSENS) += qcom/ obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig new file mode 100644 index 000..9bfde94e --- /dev/null +++ b/drivers/thermal/qcom/Kconfig @@ -0,0 +1,10 @@ +config QCOM_TSENS + tristate Qualcomm TSENS Temperature Alarm + depends on THERMAL + depends on QCOM_QFPROM + help + This enables the thermal sysfs driver for the Tsens device. It shows + up in Sysfs as a thermal zone with multiple trip points. Disabling the + thermal zone device via the mode file results in disabling the sensor. + Also able to set threshold temperature for both hot and cold and update + when a threshold is reached. diff --git a/drivers/thermal/qcom/Makefile
[PATCH 0/9] qcom: Add support for TSENS driver
Changes since RFC: * Added support for 8916 and 8084 * Based off the latest nvmem framework patches [1] * Minor review fixes for comments mostly from Lina ** I have also added irq support using the hardware trip point support series [2]. Will post that out seperately. This is an attempt to have a single TSENS driver for the different versions of the TSENS IP that exist, on different qcom msm/apq SoCs' Support is added for msm8916, msm8960 and msm8974 families. Based on top of the latest nvmem framework patches [2] A lot of the work is based of original code from Stephen Boyd and Siddartha Mohanadoss. I have also picked some of what Narendran Rajan did in his attempt to upstream the support for 8960 family. I could not keep the original authorship on any of the patches because I ended up moving the code around quite a bit in an effort to have a single driver for the various devices. I would be glad to change the authorship for any of the patches if needed. [1] https://lkml.org/lkml/2015/6/22/609 [2] https://lkml.org/lkml/2015/5/20/472 Rajendra Nayak (8): thermal: qcom: tsens: Add a skeletal TSENS drivers thermal: qcom: tsens-8916: Add support for 8916 family of SoCs thermal: qcom: tsens-8974: Add support for 8974 family of SoCs thermal: qcom: tsens-8960: Add support for 8960 family of SoCs arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes Srinivas Kandagatla (1): clk: qcom: gcc-msm8960: add child devices support. .../devicetree/bindings/thermal/qcom-tsens.txt | 37 +++ arch/arm/boot/dts/qcom-apq8064.dtsi| 108 arch/arm/boot/dts/qcom-apq8084.dtsi| 105 arch/arm/boot/dts/qcom-msm8974.dtsi| 105 arch/arm64/boot/dts/qcom/msm8916.dtsi | 66 + drivers/clk/qcom/gcc-msm8960.c | 4 +- drivers/thermal/Kconfig| 5 + drivers/thermal/Makefile | 1 + drivers/thermal/qcom/Kconfig | 10 + drivers/thermal/qcom/Makefile | 2 + drivers/thermal/qcom/tsens-8916.c | 107 drivers/thermal/qcom/tsens-8960.c | 291 + drivers/thermal/qcom/tsens-8974.c | 239 + drivers/thermal/qcom/tsens-common.c| 128 + drivers/thermal/qcom/tsens.c | 209 +++ drivers/thermal/qcom/tsens.h | 69 + 16 files changed, 1485 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt create mode 100644 drivers/thermal/qcom/Kconfig create mode 100644 drivers/thermal/qcom/Makefile create mode 100644 drivers/thermal/qcom/tsens-8916.c create mode 100644 drivers/thermal/qcom/tsens-8960.c create mode 100644 drivers/thermal/qcom/tsens-8974.c create mode 100644 drivers/thermal/qcom/tsens-common.c create mode 100644 drivers/thermal/qcom/tsens.c create mode 100644 drivers/thermal/qcom/tsens.h -- QUALCOMM INDIA, 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 3/9] thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
Add .calibrate support for 8974 family as part of tsens_ops. Based on the original code by Siddartha Mohanadoss and Stephen Boyd. Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- drivers/thermal/qcom/Makefile | 2 +- drivers/thermal/qcom/tsens-8974.c | 239 ++ drivers/thermal/qcom/tsens.c | 1 + drivers/thermal/qcom/tsens.h | 2 +- 4 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 drivers/thermal/qcom/tsens-8974.c diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index 05c98e4..a471100 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o -qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o +qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c new file mode 100644 index 000..19d9258 --- /dev/null +++ b/drivers/thermal/qcom/tsens-8974.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2015, 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/platform_device.h +#include tsens.h + +/* eeprom layout data for 8974 */ +#define BASE1_MASK 0xff +#define S0_P1_MASK 0x3f00 +#define S1_P1_MASK 0xfc000 +#define S2_P1_MASK 0x3f0 +#define S3_P1_MASK 0xfc00 +#define S4_P1_MASK 0x3f +#define S5_P1_MASK 0xfc0 +#define S6_P1_MASK 0x3f000 +#define S7_P1_MASK 0xfc +#define S8_P1_MASK 0x3f00 +#define S8_P1_MASK_BKP 0x3f +#define S9_P1_MASK 0x3f +#define S9_P1_MASK_BKP 0xfc0 +#define S10_P1_MASK0xfc0 +#define S10_P1_MASK_BKP0x3f000 +#define CAL_SEL_0_10xc000 +#define CAL_SEL_2 0x4000 +#define CAL_SEL_SHIFT 30 +#define CAL_SEL_SHIFT_228 + +#define S0_P1_SHIFT8 +#define S1_P1_SHIFT14 +#define S2_P1_SHIFT20 +#define S3_P1_SHIFT26 +#define S5_P1_SHIFT6 +#define S6_P1_SHIFT12 +#define S7_P1_SHIFT18 +#define S8_P1_SHIFT24 +#define S9_P1_BKP_SHIFT6 +#define S10_P1_SHIFT 6 +#define S10_P1_BKP_SHIFT 12 + +#define BASE2_SHIFT12 +#define BASE2_BKP_SHIFT18 +#define S0_P2_SHIFT20 +#define S0_P2_BKP_SHIFT26 +#define S1_P2_SHIFT26 +#define S2_P2_BKP_SHIFT6 +#define S3_P2_SHIFT6 +#define S3_P2_BKP_SHIFT12 +#define S4_P2_SHIFT12 +#define S4_P2_BKP_SHIFT18 +#define S5_P2_SHIFT18 +#define S5_P2_BKP_SHIFT24 +#define S6_P2_SHIFT24 +#define S7_P2_BKP_SHIFT6 +#define S8_P2_SHIFT6 +#define S8_P2_BKP_SHIFT12 +#define S9_P2_SHIFT12 +#define S9_P2_BKP_SHIFT18 +#define S10_P2_SHIFT 18 +#define S10_P2_BKP_SHIFT 24 + +#define BASE2_MASK 0xff000 +#define BASE2_BKP_MASK 0xfc +#define S0_P2_MASK 0x3f0 +#define S0_P2_BKP_MASK 0xfc00 +#define S1_P2_MASK 0xfc00 +#define S1_P2_BKP_MASK 0x3f +#define S2_P2_MASK 0x3f +#define S2_P2_BKP_MASK 0xfc0 +#define S3_P2_MASK 0xfc0 +#define S3_P2_BKP_MASK 0x3f000 +#define S4_P2_MASK 0x3f000 +#define S4_P2_BKP_MASK 0xfc +#define S5_P2_MASK 0xfc +#define S5_P2_BKP_MASK 0x3f00 +#define S6_P2_MASK 0x3f00 +#define S6_P2_BKP_MASK 0x3f +#define S7_P2_MASK 0x3f +#define S7_P2_BKP_MASK 0xfc0 +#define S8_P2_MASK 0xfc0 +#define S8_P2_BKP_MASK 0x3f000 +#define S9_P2_MASK 0x3f000 +#define S9_P2_BKP_MASK 0xfc +#define S10_P2_MASK0xfc +#define S10_P2_BKP_MASK0x3f00 + +#define BKP_SEL0x3 +#define BKP_REDUN_SEL 0xe000 +#define BKP_REDUN_SHIFT29 + +#define BIT_APPEND 0x3 + +static int calibrate_8974(struct tsens_device *tmdev) +{ + int base1 = 0, base2 = 0, i; + u32 p1[11], p2[11]; + int mode = 0; + u32 *calib, *bkp; + u32
[PATCH 8/9] arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes
Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- arch/arm/boot/dts/qcom-apq8084.dtsi | 105 1 file changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 7084010..05e83ea 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -75,6 +75,88 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 5; + + trips { + cpu_alert0: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit0: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 6; + + trips { + cpu_alert1: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit1: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal2 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 7; + + trips { + cpu_alert2: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit2: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal3 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 8; + + trips { + cpu_alert3: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit3: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + }; + cpu-pmu { compatible = qcom,krait-pmu; interrupts = 1 7 0xf04; @@ -103,6 +185,29 @@ 0xf9002000 0x1000; }; + qfprom: qfprom@fc4bc000 { + #address-cells = 1; + #size-cells = 1; + compatible = qcom,qfprom; + reg = 0xfc4bc000 0x1000; + tsens_calib: calib@d0 { + reg = 0xd0 0x18; + }; + tsens_backup: backup@440 { + reg = 0x440 0x10; + }; + }; + + tsens: thermal-sensor@fc4a8000 { + compatible = qcom,msm8974-tsens; + reg = 0xfc4a8000 0x2000; + nvmem-cell = tsens_calib, tsens_backup; + nvmem-cell-names = calib, calib_backup; + qcom,tsens-slopes = 3200 3200 3200 3200 3200 3200 + 3200 3200 3200 3200 3200; + #thermal-sensor-cells = 1; + }; + timer@f902 { #address-cells = 1; #size-cells = 1; -- QUALCOMM INDIA, on
[PATCH 6/9] arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes
Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 105 1 file changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 37b47b5..30f3246 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -75,6 +75,88 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 5; + + trips { + cpu_alert0: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit0: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 6; + + trips { + cpu_alert1: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit1: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal2 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 7; + + trips { + cpu_alert2: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit2: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal3 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 8; + + trips { + cpu_alert3: trip@0 { + temperature = 75000; + hysteresis = 2000; + type = passive; + }; + cpu_crit3: trip@1 { + temperature = 95000; + hysteresis = 2000; + type = critical; + }; + }; + }; + }; + cpu-pmu { compatible = qcom,krait-pmu; interrupts = 1 7 0xf04; @@ -103,6 +185,29 @@ 0xf9002000 0x1000; }; + qfprom: qfprom@fc4bc000 { + #address-cells = 1; + #size-cells = 1; + compatible = qcom,qfprom; + reg = 0xfc4bc000 0x1000; + tsens_calib: calib@d0 { + reg = 0xd0 0x18; + }; + tsens_backup: backup@440 { + reg = 0x440 0x10; + }; + }; + + tsens: thermal-sensor@fc4a8000 { + compatible = qcom,msm8974-tsens; + reg = 0xfc4a8000 0x2000; + nvmem-cell = tsens_calib, tsens_backup; + nvmem-cell-names = calib, calib_backup; + qcom,tsens-slopes = 3200 3200 3200 3200 3200 3200 + 3200 3200 3200 3200 3200; + #thermal-sensor-cells = 1; + }; + timer@f902 { #address-cells = 1; #size-cells = 1; -- QUALCOMM INDIA, on
[PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds support to add child devices to gcc as some of the registers mapped by gcc are used by things like thermal sensors. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/clk/qcom/gcc-msm8960.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index eb6a4f9..2c80d03 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -15,6 +15,7 @@ #include linux/bitops.h #include linux/err.h #include linux/platform_device.h +#include linux/of_platform.h #include linux/module.h #include linux/of.h #include linux/of_device.h @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk); - return qcom_cc_probe(pdev, match-data); + qcom_cc_probe(pdev, match-data); + return of_platform_populate(pdev-dev.of_node, NULL, NULL, pdev-dev); } static int gcc_msm8960_remove(struct platform_device *pdev) -- QUALCOMM INDIA, 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 9/9] arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes
Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak rna...@codeaurora.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 66 +++ 1 file changed, 66 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 0f49ebd..9ff9979 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -63,6 +63,49 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 4; + + trips { + cpu_alert0: trip@0 { + temperature = 10; + hysteresis = 2000; + type = passive; + }; + cpu_crit0: trip@1 { + temperature = 125000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = 250; + polling-delay = 1000; + + thermal-sensors = tsens 3; + + trips { + cpu_alert1: trip@0 { + temperature = 10; + hysteresis = 2000; + type = passive; + }; + cpu_crit1: trip@1 { + temperature = 125000; + hysteresis = 2000; + type = critical; + }; + }; + }; + + }; + timer { compatible = arm,armv8-timer; interrupts = GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW), @@ -215,5 +258,28 @@ interrupt-controller; #interrupt-cells = 4; }; + + qfprom: qfprom@5c000 { + compatible = qcom,qfprom; + reg = 0x5c000 0x1000; + #address-cells = 1; + #size-cells = 1; + tsens_caldata: caldata@d0 { + reg = 0xd0 0x8; + }; + tsens_calsel: calsel@ec { + reg = 0xec 0x4; + }; + }; + + tsens: thermal-sensor@4a8000 { + compatible = qcom,msm8916-tsens; + reg = 0x4a8000 0x2000; + nvmem-cell = tsens_caldata, tsens_calsel; + nvmem-cell-names = calib, calib_sel; + qcom,tsens-slopes = 3200 3200 3200 3200 3200; + qcom,sensor-id = 0 1 2 4 5; + #thermal-sensor-cells = 1; + }; }; }; -- QUALCOMM INDIA, 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] drm/msm/mdp: Add capabilities to MDP planes(V2)
MDP planes can be implemented using different type of HW pipes, RGB/VIG/DMA pipes for MDP5 and RGB/VG/DMA pipes for MDP4. Each type of pipe has different HW capabilities such as scaling, color space conversion, decimation... Add a variable in plane data structure to specify the difference of each plane which comes from mdp5_cfg data and use it to differenciate the plane operation. V1: Initial change V2: Fix a typo in mdp4_kms.h Signed-off-by: Jilai Wang jil...@codeaurora.org --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 19 drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 7 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 26 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 11 +++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 24 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 73 ++- drivers/gpu/drm/msm/mdp/mdp_kms.h | 13 ++ 8 files changed, 114 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index c1ecb9d..1aaedad 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -175,27 +175,24 @@ irqreturn_t mdp4_irq(struct msm_kms *kms); int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); -static inline bool pipe_supports_yuv(enum mdp4_pipe pipe) +static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe) { switch (pipe) { case VG1: case VG2: case VG3: case VG4: - return true; + return MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC; + case RGB1: + case RGB2: + case RGB3: + return MDP_PIPE_CAP_SCALE; default: - return false; + return 0; } } -static inline -uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats, - uint32_t max_formats) -{ - return mdp_get_formats(pixel_formats, max_formats, - !pipe_supports_yuv(pipe_id)); -} - void mdp4_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 0d1dbb7..c749489 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -26,6 +26,7 @@ struct mdp4_plane { enum mdp4_pipe pipe; + uint32_t caps; uint32_t nformats; uint32_t formats[32]; @@ -380,9 +381,11 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, mdp4_plane-pipe = pipe_id; mdp4_plane-name = pipe_names[pipe_id]; + mdp4_plane-caps = mdp4_pipe_caps(pipe_id); - mdp4_plane-nformats = mdp4_get_formats(pipe_id, mdp4_plane-formats, - ARRAY_SIZE(mdp4_plane-formats)); + mdp4_plane-nformats = mdp_get_formats(mdp4_plane-formats, + ARRAY_SIZE(mdp4_plane-formats), + !pipe_supports_yuv(mdp4_plane-caps)); type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(dev, plane, 0xff, mdp4_plane_funcs, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index 789b02f..ac1d58f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -45,14 +45,20 @@ const struct mdp5_cfg_hw msm8x74_config = { .pipe_vig = { .count = 3, .base = { 0x01200, 0x01600, 0x01a00 }, + .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | + MDP_PIPE_CAP_DECIMATION, }, .pipe_rgb = { .count = 3, .base = { 0x01e00, 0x02200, 0x02600 }, + .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, }, .pipe_dma = { .count = 2, .base = { 0x02a00, 0x02e00 }, + .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP, }, .lm = { .count = 5, @@ -113,14 +119,20 @@ const struct mdp5_cfg_hw apq8084_config = { .pipe_vig = { .count = 4, .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 }, + .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | + MDP_PIPE_CAP_DECIMATION, }, .pipe_rgb = { .count = 4,
[PATCH V4 5/7] i2c: qup: Add bam dma capabilities
QUP cores can be attached to a BAM module, which acts as a dma engine for the QUP core. When DMA with BAM is enabled, the BAM consumer pipe transmitted data is written to the output FIFO and the BAM producer pipe received data is read from the input FIFO. With BAM capabilities, qup-i2c core can transfer more than 256 bytes, without a 'stop' which is not possible otherwise. Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/i2c/busses/i2c-qup.c | 431 +-- 1 file changed, 415 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index c0757d9..810b021 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -24,6 +24,11 @@ #include linux/of.h #include linux/platform_device.h #include linux/pm_runtime.h +#include linux/dma-mapping.h +#include linux/scatterlist.h +#include linux/atomic.h +#include linux/dmaengine.h +#include linux/dmapool.h /* QUP Registers */ #define QUP_CONFIG 0x000 @@ -33,6 +38,7 @@ #define QUP_OPERATIONAL0x018 #define QUP_ERROR_FLAGS0x01c #define QUP_ERROR_FLAGS_EN 0x020 +#define QUP_OPERATIONAL_MASK 0x028 #define QUP_HW_VERSION 0x030 #define QUP_MX_OUTPUT_CNT 0x100 #define QUP_OUT_FIFO_BASE 0x110 @@ -53,6 +59,7 @@ #define QUP_STATE_VALIDBIT(2) #define QUP_I2C_MAST_GEN BIT(4) +#define QUP_I2C_FLUSH BIT(6) #define QUP_OPERATIONAL_RESET 0x000ff0 #define QUP_I2C_STATUS_RESET 0xfc @@ -78,7 +85,10 @@ /* Packing/Unpacking words in FIFOs, and IO modes */ #define QUP_OUTPUT_BLK_MODE(1 10) +#define QUP_OUTPUT_BAM_MODE(3 10) #define QUP_INPUT_BLK_MODE (1 12) +#define QUP_INPUT_BAM_MODE (3 12) +#define QUP_BAM_MODE (QUP_OUTPUT_BAM_MODE | QUP_INPUT_BAM_MODE) #define QUP_UNPACK_EN BIT(14) #define QUP_PACK_ENBIT(15) @@ -95,6 +105,8 @@ #define QUP_TAG_DATA (2 8) #define QUP_TAG_STOP (3 8) #define QUP_TAG_REC(4 8) +#define QUP_BAM_INPUT_EOT 0x93 +#define QUP_BAM_FLUSH_STOP 0x96 /* QUP v2 tags */ #define QUP_TAG_V2_START 0x81 @@ -115,6 +127,12 @@ #define ONE_BYTE 0x1 #define QUP_I2C_MX_CONFIG_DURING_RUN BIT(31) +#define MX_TX_RX_LEN SZ_64K +#define MX_BLOCKS (MX_TX_RX_LEN / QUP_READ_LIMIT) + +/* Max timeout in ms for 32k bytes */ +#define TOUT_MAX 300 + struct qup_i2c_block { int count; int pos; @@ -125,6 +143,23 @@ struct qup_i2c_block { int config_run; }; +struct qup_i2c_tag { + u8 *start; + dma_addr_t addr; +}; + +struct qup_i2c_bam_rx { + struct qup_i2c_tag scratch_tag; + struct dma_chan *dma_rx; + struct scatterlist *sg_rx; +}; + +struct qup_i2c_bam_tx { + struct qup_i2c_tag footer_tag; + struct dma_chan *dma_tx; + struct scatterlist *sg_tx; +}; + struct qup_i2c_dev { struct device *dev; void __iomem*base; @@ -154,14 +189,20 @@ struct qup_i2c_dev { int (*qup_i2c_write_one)(struct qup_i2c_dev *qup, struct i2c_msg *msg); + int (*qup_i2c_read_one)(struct qup_i2c_dev *qup, + struct i2c_msg *msg); + /* Current i2c_msg in i2c_msgs */ int cmsg; /* total num of i2c_msgs */ int num; - int (*qup_i2c_read_one)(struct qup_i2c_dev *qup, - struct i2c_msg *msg); - + /* dma parameters */ + boolis_dma; + struct dma_pool *dpool; + struct qup_i2c_tag start_tag; + struct qup_i2c_bam_rx brx; + struct qup_i2c_bam_tx btx; struct completion xfer; }; @@ -238,6 +279,14 @@ static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 req_state) return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK); } +static void qup_i2c_flush(struct qup_i2c_dev *qup) +{ + u32 val = readl(qup-base + QUP_STATE); + + val |= QUP_I2C_FLUSH; + writel(val, qup-base + QUP_STATE); +} + static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup) { return qup_i2c_poll_state_mask(qup, 0, 0); @@ -437,12 +486,15 @@ static int qup_i2c_get_data_len(struct qup_i2c_dev *qup) } static int qup_i2c_get_tags(u8 *tags, struct qup_i2c_dev *qup, - struct i2c_msg *msg) + struct i2c_msg *msg, int is_dma) { u16 addr = (msg-addr 1) | ((msg-flags I2C_M_RD) == I2C_M_RD); int len = 0; int data_len; + int last = (qup-blk.pos == (qup-blk.count - 1)) + (qup-cmsg == (qup-num - 1)); +
[PATCH V4 0/7] i2c: qup: Add support for v2 tags and bam dma
QUP from version 2.1.1 onwards, supports a new format of i2c command tags. Tag codes instructs the controller to perform a operation like read/write. This new tagging version supports and is required for adding bam dma capabilities. V2 tags supports transfer of more than 256 bytes in a single i2c transaction. Also adding bam dma support facilitates transferring each i2c_msg in i2c_msgs without a 'stop' bit in between which is required for some of the clients. Tested this series on apq8074 dragon board eeprom client on i2c bus1 [V4] Added a patch to factor out some common code. Removed support for freq 400KHZ as per comments. Addressed comments from Ivan T. Ivanov to keep the code for V2 support in a separate path. Changed the authorship of V2 tags support patch. [V3] Added support to coalesce each i2c_msg in i2c_msgs for fifo and block mode in Patch 2. Also addressed further code comments. http://comments.gmane.org/gmane.linux.drivers.i2c/22497 [V2] Addressed comments from Ivan T. Ivanov, Andy Gross [v1] Initial Version Sricharan R (7): i2c: qup: Change qup_wait_writeready function to use for all timeouts qup: i2c: factor out common code for reuse i2c: qup: Add V2 tags support i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit i2c: qup: Add bam dma capabilities dts: msm8974: Add blsp2_bam dma node dts: msm8974: Add dma channels for blsp2_i2c1 node arch/arm/boot/dts/qcom-msm8974.dtsi | 14 +- drivers/i2c/busses/i2c-qup.c| 943 +--- 2 files changed, 880 insertions(+), 77 deletions(-) -- QUALCOMM INDIA, 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 V4 4/7] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
The definition of i2c_msg says that If this is the last message in a group, it is followed by a STOP. Otherwise it is followed by the next @i2c_msg transaction segment, beginning with a (repeated) START So the expectation is that there is no 'STOP' bit inbetween individual i2c_msg segments with repeated 'START'. The QUP i2c hardware has no way to inform that there should not be a 'STOP' at the end of transaction. The only way to implement this is to coalesce all the i2c_msg in i2c_msgs in to one transaction and transfer them. Adding the support for the same. This is required for some clients like touchscreen which keeps incrementing counts across individual transfers and 'STOP' bit inbetween resets the counter, which is not required. This patch adds the support in non-dma mode. Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/i2c/busses/i2c-qup.c | 40 ++-- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index a4e20d9..c0757d9 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -113,6 +113,7 @@ #define SET_BIT0x1 #define RESET_BIT 0x0 #define ONE_BYTE 0x1 +#define QUP_I2C_MX_CONFIG_DURING_RUN BIT(31) struct qup_i2c_block { int count; @@ -121,6 +122,7 @@ struct qup_i2c_block { int rx_tag_len; int data_len; u8 tags[6]; + int config_run; }; struct qup_i2c_dev { @@ -152,6 +154,10 @@ struct qup_i2c_dev { int (*qup_i2c_write_one)(struct qup_i2c_dev *qup, struct i2c_msg *msg); + /* Current i2c_msg in i2c_msgs */ + int cmsg; + /* total num of i2c_msgs */ + int num; int (*qup_i2c_read_one)(struct qup_i2c_dev *qup, struct i2c_msg *msg); @@ -278,7 +284,8 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val, status = readl(qup-base + QUP_I2C_STATUS); if (((opflags op) shift) == val) { - if (op == QUP_OUT_NOT_EMPTY) { + if ((op == QUP_OUT_NOT_EMPTY) + (qup-cmsg == (qup-num - 1))) { if (!(status I2C_STATUS_BUS_ACTIVE)) return 0; } else { @@ -301,12 +308,14 @@ static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg) if (total qup-out_fifo_sz) { /* FIFO mode */ writel(QUP_REPACK_EN, qup-base + QUP_IO_MODE); - writel(total, qup-base + QUP_MX_WRITE_CNT); + writel(total | qup-blk.config_run, + qup-base + QUP_MX_WRITE_CNT); } else { /* BLOCK mode (transfer data on chunks) */ writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN, qup-base + QUP_IO_MODE); - writel(total, qup-base + QUP_MX_OUTPUT_CNT); + writel(total | qup-blk.config_run, + qup-base + QUP_MX_OUTPUT_CNT); } } @@ -374,6 +383,9 @@ static void qup_i2c_get_blk_data(struct qup_i2c_dev *qup, /* There are 2 tag bytes that are read in to fifo for every block */ if (msg-flags I2C_M_RD) qup-blk.rx_tag_len = qup-blk.count * 2; + + if (qup-cmsg) + qup-blk.config_run = QUP_I2C_MX_CONFIG_DURING_RUN; } static int qup_i2c_send_data(struct qup_i2c_dev *qup, int tlen, u8 *tbuf, @@ -440,7 +452,8 @@ static int qup_i2c_get_tags(u8 *tags, struct qup_i2c_dev *qup, } /* Send _STOP commands for the last block */ - if (qup-blk.pos == (qup-blk.count - 1)) { + if (qup-blk.pos == (qup-blk.count - 1) +(qup-cmsg == (qup-num - 1))) { if (msg-flags I2C_M_RD) tags[len++] = QUP_TAG_V2_DATARD_STOP; else @@ -571,7 +584,6 @@ static int qup_i2c_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) goto err; ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE); - err: disable_irq(qup-irq); qup-msg = NULL; @@ -584,18 +596,19 @@ static void qup_i2c_set_read_mode(struct qup_i2c_dev *qup, int len) int tx_len = qup-blk.tx_tag_len; len += qup-blk.rx_tag_len; + tx_len |= qup-blk.config_run; if (len qup-in_fifo_sz) { /* FIFO mode */ writel(QUP_REPACK_EN, qup-base + QUP_IO_MODE); - writel(len, qup-base + QUP_MX_READ_CNT); writel(tx_len, qup-base + QUP_MX_WRITE_CNT); + writel(len | qup-blk.config_run, qup-base + QUP_MX_READ_CNT); } else { /* BLOCK mode (transfer data on
[PATCH V4 7/7] dts: msm8974: Add dma channels for blsp2_i2c1 node
Signed-off-by: Sricharan R sricha...@codeaurora.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index f138202..17dcda3 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -284,6 +284,8 @@ clock-names = core, iface; #address-cells = 1; #size-cells = 0; + dmas = blsp2_dma 20, blsp2_dma 21; + dma-names = tx, rx; }; spmi_bus: spmi@fc4cf000 { -- QUALCOMM INDIA, 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 V4 3/7] i2c: qup: Add V2 tags support
QUP from version 2.1.1 onwards, supports a new format of i2c command tags. Tag codes instructs the controller to perform a operation like read/write. This new tagging version supports bam dma and transfers of more than 256 bytes without 'stop' in between. Adding the support for the same. For each block a data_write/read tag and data_len tag is added to the output fifo. For the final block of data write_stop/read_stop tag is used. Signed-off-by: Andy Gross agr...@codeaurora.org Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/i2c/busses/i2c-qup.c | 330 ++- 1 file changed, 323 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 131dc28..a4e20d9 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -43,6 +43,8 @@ #define QUP_I2C_CLK_CTL0x400 #define QUP_I2C_STATUS 0x404 +#define QUP_I2C_MASTER_GEN 0x408 + /* QUP States and reset values */ #define QUP_RESET_STATE0 #define QUP_RUN_STATE 1 @@ -69,6 +71,8 @@ #define QUP_CLOCK_AUTO_GATEBIT(13) #define I2C_MINI_CORE (2 8) #define I2C_N_VAL 15 +#define I2C_N_VAL_V2 7 + /* Most significant word offset in FIFO port */ #define QUP_MSW_SHIFT (I2C_N_VAL + 1) @@ -79,6 +83,7 @@ #define QUP_PACK_ENBIT(15) #define QUP_REPACK_EN (QUP_UNPACK_EN | QUP_PACK_EN) +#define QUP_V2_TAGS_EN 1 #define QUP_OUTPUT_BLOCK_SIZE(x)(((x) 0) 0x03) #define QUP_OUTPUT_FIFO_SIZE(x)(((x) 2) 0x07) @@ -91,6 +96,13 @@ #define QUP_TAG_STOP (3 8) #define QUP_TAG_REC(4 8) +/* QUP v2 tags */ +#define QUP_TAG_V2_START 0x81 +#define QUP_TAG_V2_DATAWR 0x82 +#define QUP_TAG_V2_DATAWR_STOP 0x83 +#define QUP_TAG_V2_DATARD 0x85 +#define QUP_TAG_V2_DATARD_STOP 0x87 + /* Status, Error flags */ #define I2C_STATUS_WR_BUFFER_FULL BIT(0) #define I2C_STATUS_BUS_ACTIVE BIT(8) @@ -102,6 +114,15 @@ #define RESET_BIT 0x0 #define ONE_BYTE 0x1 +struct qup_i2c_block { + int count; + int pos; + int tx_tag_len; + int rx_tag_len; + int data_len; + u8 tags[6]; +}; + struct qup_i2c_dev { struct device *dev; void __iomem*base; @@ -117,6 +138,7 @@ struct qup_i2c_dev { int in_blk_sz; unsigned long one_byte_t; + struct qup_i2c_blockblk; struct i2c_msg *msg; /* Current posion in user message buffer */ @@ -126,6 +148,14 @@ struct qup_i2c_dev { /* QUP core errors */ u32 qup_err; + int use_v2_tags; + + int (*qup_i2c_write_one)(struct qup_i2c_dev *qup, +struct i2c_msg *msg); + + int (*qup_i2c_read_one)(struct qup_i2c_dev *qup, + struct i2c_msg *msg); + struct completion xfer; }; @@ -266,7 +296,7 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val, static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg) { /* Number of entries to shift out, including the start */ - int total = msg-len + 1; + int total = msg-len + qup-blk.tx_tag_len; if (total qup-out_fifo_sz) { /* FIFO mode */ @@ -324,6 +354,134 @@ static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) return ret; } +static void qup_i2c_get_blk_data(struct qup_i2c_dev *qup, +struct i2c_msg *msg) +{ + memset(qup-blk, 0, sizeof(qup-blk)); + + if (!qup-use_v2_tags) { + if (!(msg-flags I2C_M_RD)) + qup-blk.tx_tag_len = 1; + return; + } + + qup-blk.data_len = msg-len; + qup-blk.count = (msg-len + QUP_READ_LIMIT - 1) / QUP_READ_LIMIT; + + /* 4 bytes for first block and 2 writes for rest */ + qup-blk.tx_tag_len = 4 + (qup-blk.count - 1) * 2; + + /* There are 2 tag bytes that are read in to fifo for every block */ + if (msg-flags I2C_M_RD) + qup-blk.rx_tag_len = qup-blk.count * 2; +} + +static int qup_i2c_send_data(struct qup_i2c_dev *qup, int tlen, u8 *tbuf, +int dlen, u8 *dbuf) +{ + u32 val = 0, idx = 0, pos = 0, i = 0, t; + int len = tlen + dlen; + u8 *buf = tbuf; + int ret = 0; + + while (len 0) { + ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL, +RESET_BIT, 4 * ONE_BYTE); + if (ret) { + dev_err(qup-dev, timeout for fifo out full); + return ret; + } + +
[PATCH V4 6/7] dts: msm8974: Add blsp2_bam dma node
Signed-off-by: Sricharan R sricha...@codeaurora.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 37b47b5..f138202 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1,6 +1,6 @@ /dts-v1/; -#include dt-bindings/interrupt-controller/irq.h +#include dt-bindings/interrupt-controller/arm-gic.h #include dt-bindings/clock/qcom,gcc-msm8974.h #include skeleton.dtsi @@ -301,5 +301,15 @@ interrupt-controller; #interrupt-cells = 4; }; + + blsp2_dma: dma-controller@f9944000 { + compatible = qcom,bam-v1.4.0; + reg = 0xf9944000 0x19000; + interrupts = GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH; + clocks = gcc GCC_BLSP2_AHB_CLK; + clock-names = bam_clk; + #dma-cells = 1; + qcom,ee = 0; + }; }; }; -- QUALCOMM INDIA, 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 V4 2/7] qup: i2c: factor out common code for reuse
The qup_i2c_write/read_one functions can be split to have the common initialization code and function to loop around the data bytes separately. This way the initialization code can be reused while adding v2 tags functionality. Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/i2c/busses/i2c-qup.c | 147 +-- 1 file changed, 87 insertions(+), 60 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 81ed120..131dc28 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -324,53 +324,72 @@ static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) return ret; } -static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) +static int qup_i2c_wait_for_complete(struct qup_i2c_dev *qup, +struct i2c_msg *msg) { unsigned long left; - int ret; - - qup-msg = msg; - qup-pos = 0; + int ret = 0; - enable_irq(qup-irq); + left = wait_for_completion_timeout(qup-xfer, HZ); + if (!left) { + writel(1, qup-base + QUP_SW_RESET); + ret = -ETIMEDOUT; + } - qup_i2c_set_write_mode(qup, msg); + if (qup-bus_err || qup-qup_err) { + if (qup-bus_err QUP_I2C_NACK_FLAG) { + dev_err(qup-dev, NACK from %x\n, msg-addr); + ret = -EIO; + } + } - ret = qup_i2c_change_state(qup, QUP_RUN_STATE); - if (ret) - goto err; + return ret; +} - writel(qup-clk_ctl, qup-base + QUP_I2C_CLK_CTL); +static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ + int ret = 0; do { ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE); if (ret) - goto err; + return ret; ret = qup_i2c_issue_write(qup, msg); if (ret) - goto err; + return ret; ret = qup_i2c_change_state(qup, QUP_RUN_STATE); if (ret) - goto err; - - left = wait_for_completion_timeout(qup-xfer, HZ); - if (!left) { - writel(1, qup-base + QUP_SW_RESET); - ret = -ETIMEDOUT; - goto err; - } + return ret; - if (qup-bus_err || qup-qup_err) { - if (qup-bus_err QUP_I2C_NACK_FLAG) - dev_err(qup-dev, NACK from %x\n, msg-addr); - ret = -EIO; - goto err; - } + ret = qup_i2c_wait_for_complete(qup, msg); + if (ret) + return ret; } while (qup-pos msg-len); - /* Wait for the outstanding data in the fifo to drain */ + return ret; +} + +static int qup_i2c_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ + int ret; + + qup-msg = msg; + qup-pos = 0; + enable_irq(qup-irq); + qup_i2c_set_write_mode(qup, msg); + + ret = qup_i2c_change_state(qup, QUP_RUN_STATE); + if (ret) + goto err; + + writel(qup-clk_ctl, qup-base + QUP_I2C_CLK_CTL); + + ret = qup_i2c_write_one(qup, msg); + if (ret) + goto err; + ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE); err: @@ -436,51 +455,59 @@ static int qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg) static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) { - unsigned long left; - int ret; + int ret = 0; - qup-msg = msg; - qup-pos = 0; + /* +* The QUP block will issue a NACK and STOP on the bus when reaching +* the end of the read, the length of the read is specified as one byte +* which limits the possible read to 256 (QUP_READ_LIMIT) bytes. +*/ + if (msg-len QUP_READ_LIMIT) { + dev_err(qup-dev, HW not capable of reads over %d bytes\n, + QUP_READ_LIMIT); + return -EINVAL; + } - enable_irq(qup-irq); + ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE); + if (ret) + return ret; - qup_i2c_set_read_mode(qup, msg-len); + qup_i2c_issue_read(qup, msg); ret = qup_i2c_change_state(qup, QUP_RUN_STATE); if (ret) - goto err; + return ret; - writel(qup-clk_ctl, qup-base + QUP_I2C_CLK_CTL); + do { + ret = qup_i2c_wait_for_complete(qup, msg); + if (ret) + return ret; + ret = qup_i2c_read_fifo(qup, msg); + if (ret) + return ret; + }
Re: [PATCH v2 01/11] soc: qcom: Add device tree binding for SMEM
On Wed, Jul 08, 2015 at 04:56:34PM -0700, Stephen Boyd wrote: On 06/26/2015 02:50 PM, bj...@kryo.se wrote: += EXAMPLE +The following example shows the SMEM setup for MSM8974, with a main SMEM region +at 0xfa0 and an auxiliary region at 0xfc428000: + + reserved-memory { + #address-cells = 1; + #size-cells = 1; + ranges; + + smem_region: smem@fa0 { + reg = 0xfa0 0x20; + no-map; + }; + }; + + smem@fa0 { This should be smem@fc428000 matching the first reg property. It's weird though, because if smem is using a secondary region it will be under the SoC node and have a reg property. Otherwise it would be directly under the root node and only have a memory-region. It would be nice if we could somehow move the rpm message ram (0xfc428000) into the reserved-memory node so that we could use memory-region for both regions. The memory-region is just used to describe 'real' memory. The RPM message is IO memory and part of the SOC. Thats my take at least. + compatible = qcom,smem; + + memory-region = smem_region; + reg = 0xfc428000 0x4000; + + hwlocks = tcsr_mutex 3; + }; -- Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- 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 V4 1/7] i2c: qup: Change qup_wait_writeready function to use for all timeouts
qup_wait_writeready waits only on a output fifo empty event. Change the same function to accept the event and data length to wait as parameters. This way the same function can be used for timeouts in otherplaces as well. Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/i2c/busses/i2c-qup.c | 67 +++- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index fdcbdab..81ed120 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -98,6 +98,9 @@ #define QUP_STATUS_ERROR_FLAGS 0x7c #define QUP_READ_LIMIT 256 +#define SET_BIT0x1 +#define RESET_BIT 0x0 +#define ONE_BYTE 0x1 struct qup_i2c_dev { struct device *dev; @@ -221,26 +224,42 @@ static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state) return 0; } -static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup) +/** + * qup_i2c_wait_ready - wait for a give number of bytes in tx/rx path + * @qup: The qup_i2c_dev device + * @op: The bit/event to wait on + * @val: value of the bit to wait on, 0 or 1 + * @len: The length the bytes to be transferred + */ +static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val, + int len) { unsigned long timeout; u32 opflags; u32 status; + u32 shift = __ffs(op); - timeout = jiffies + HZ; + len *= qup-one_byte_t; + /* timeout after a wait of twice the max time */ + timeout = jiffies + len * 4; for (;;) { opflags = readl(qup-base + QUP_OPERATIONAL); status = readl(qup-base + QUP_I2C_STATUS); - if (!(opflags QUP_OUT_NOT_EMPTY) - !(status I2C_STATUS_BUS_ACTIVE)) - return 0; + if (((opflags op) shift) == val) { + if (op == QUP_OUT_NOT_EMPTY) { + if (!(status I2C_STATUS_BUS_ACTIVE)) + return 0; + } else { + return 0; + } + } if (time_after(jiffies, timeout)) return -ETIMEDOUT; - usleep_range(qup-one_byte_t, qup-one_byte_t * 2); + usleep_range(len, len * 2); } } @@ -261,13 +280,13 @@ static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg) } } -static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) +static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) { u32 addr = msg-addr 1; u32 qup_tag; - u32 opflags; int idx; u32 val; + int ret = 0; if (qup-pos == 0) { val = QUP_TAG_START | addr; @@ -279,9 +298,10 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) while (qup-pos msg-len) { /* Check that there's space in the FIFO for our pair */ - opflags = readl(qup-base + QUP_OPERATIONAL); - if (opflags QUP_OUT_FULL) - break; + ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL, RESET_BIT, +4 * ONE_BYTE); + if (ret) + return ret; if (qup-pos == msg-len - 1) qup_tag = QUP_TAG_STOP; @@ -300,6 +320,8 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) qup-pos++; idx++; } + + return ret; } static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) @@ -325,7 +347,9 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) if (ret) goto err; - qup_i2c_issue_write(qup, msg); + ret = qup_i2c_issue_write(qup, msg); + if (ret) + goto err; ret = qup_i2c_change_state(qup, QUP_RUN_STATE); if (ret) @@ -347,7 +371,7 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) } while (qup-pos msg-len); /* Wait for the outstanding data in the fifo to drain */ - ret = qup_i2c_wait_writeready(qup); + ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE); err: disable_irq(qup-irq); @@ -384,18 +408,19 @@ static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg) } -static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg) +static int qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg) { - u32 opflags; u32 val = 0; int
[RFC] drivers: dma-coherent: Change order of allocation to PAGE_SIZE
dma_alloc_from_coherent uses get_order(size) which makes carve-out allocations not aligned on order boundaries to fail even though they are page aligned. So wanted to know why is it required to have the size aligned on order boundary. Changing it to get_order(PAGE_SIZE) makes the non aligned carve-out allocations to go through. Signed-off-by: Sricharan R sricha...@codeaurora.org --- drivers/base/dma-coherent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 55b8398..72bdc6f 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -156,7 +156,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, dma_addr_t *dma_handle, void **ret) { struct dma_coherent_mem *mem; - int order = get_order(size); + int order = get_order(PAGE_SIZE); unsigned long flags; int pageno; -- QUALCOMM INDIA, 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
Re: [PATCH v2 01/11] soc: qcom: Add device tree binding for SMEM
On 06/26/2015 02:50 PM, bj...@kryo.se wrote: += EXAMPLE +The following example shows the SMEM setup for MSM8974, with a main SMEM region +at 0xfa0 and an auxiliary region at 0xfc428000: + + reserved-memory { + #address-cells = 1; + #size-cells = 1; + ranges; + + smem_region: smem@fa0 { + reg = 0xfa0 0x20; + no-map; + }; + }; + + smem@fa0 { This should be smem@fc428000 matching the first reg property. It's weird though, because if smem is using a secondary region it will be under the SoC node and have a reg property. Otherwise it would be directly under the root node and only have a memory-region. It would be nice if we could somehow move the rpm message ram (0xfc428000) into the reserved-memory node so that we could use memory-region for both regions. + compatible = qcom,smem; + + memory-region = smem_region; + reg = 0xfc428000 0x4000; + + hwlocks = tcsr_mutex 3; + }; -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- 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 V4] trace/events: add chip name and hwirq to irq entry tracepoint
Add chip name and hw-irq number to the trace_irq_handler_entry() tracepoint. When tracing interrupt events the chip-name and hw-irq numbers are stable and known in advance. This makes them a better choice as a filtering criteria for the trace buffer dump. On the flipside, the os-irq numbers are dynamically allocated which makes them difficult to use for the same purpose. Dump messages will look like: ...irq_handler_entry: irq=22 name=msm_serial0 chip_name=GIC hwirq=140 Suggested-by: Stephen Boyd sb...@codeaurora.org Reviewed-by: Andy Gross agr...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since V3: - use field variable in trace structure to assign value for chip name and hwirq rather than printing directly to the trace buffer. --- Changes since V2: - fixed dump message in commit text to reflect Chip name instead of domain. --- Changes since V1: - added reviewed by Andy Gross --- include/trace/events/irq.h | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 3608beb..0898506 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -23,6 +23,17 @@ struct softirq_action; softirq_name(HRTIMER), \ softirq_name(RCU)) + +#define show_chip_name(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-chip-name\ +: NULL) + +#define show_hwirq(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-hwirq \ +: -ENODEV) + /** * irq_handler_entry - called immediately before the irq action handler * @irq: irq number @@ -41,16 +52,21 @@ TRACE_EVENT(irq_handler_entry, TP_ARGS(irq, action), TP_STRUCT__entry( - __field(int,irq ) - __string( name, action-name) + __field( int, irq ) + __field( unsigned long, hwirq) + __string( name, action-name ) + __string( chip, show_chip_name(irq) ) ), TP_fast_assign( __entry-irq = irq; + __entry-hwirq = show_hwirq(irq); __assign_str(name, action-name); + __assign_str(chip, show_chip_name(irq)); ), - TP_printk(irq=%d name=%s, __entry-irq, __get_str(name)) + TP_printk(irq=%d name=%s chip=%s hwirq=%ld, __entry-irq, + __get_str(name), __get_str(chip), __entry-hwirq) ); /** -- 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
Re: [PATCH] drm/msm/mdp5:Add DMA pipe planes for MDP5
On Tue, Jul 7, 2015 at 5:17 PM, Jilai Wang jil...@codeaurora.org wrote: This change is to add planes which use DMA pipes for MDP5. are DMA pipes only supporting memory-memory operation, or am I reading too much into the name DMA? I'm wondering if we need to fix the possible_crtcs param that mdp5_plane_init passes to drm_universal_plane_init()? BR, -R Signed-off-by: Jilai Wang jil...@codeaurora.org --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index cbda41d..f40896d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -316,9 +316,12 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) static const enum mdp5_pipe crtcs[] = { SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3, }; - static const enum mdp5_pipe pub_planes[] = { + static const enum mdp5_pipe vig_planes[] = { SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3, }; + static const enum mdp5_pipe dma_planes[] = { + SSPP_DMA0, SSPP_DMA1, + }; struct drm_device *dev = mdp5_kms-dev; struct msm_drm_private *priv = dev-dev_private; const struct mdp5_cfg_hw *hw_cfg; @@ -361,12 +364,26 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) for (i = 0; i hw_cfg-pipe_vig.count; i++) { struct drm_plane *plane; - plane = mdp5_plane_init(dev, pub_planes[i], false, + plane = mdp5_plane_init(dev, vig_planes[i], false, hw_cfg-pipe_vig.base[i], hw_cfg-pipe_vig.caps); if (IS_ERR(plane)) { ret = PTR_ERR(plane); dev_err(dev-dev, failed to construct %s plane: %d\n, - pipe2name(pub_planes[i]), ret); + pipe2name(vig_planes[i]), ret); + goto fail; + } + } + + /* DMA planes */ + for (i = 0; i hw_cfg-pipe_dma.count; i++) { + struct drm_plane *plane; + + plane = mdp5_plane_init(dev, dma_planes[i], false, + hw_cfg-pipe_dma.base[i], hw_cfg-pipe_dma.caps); + if (IS_ERR(plane)) { + ret = PTR_ERR(plane); + dev_err(dev-dev, failed to construct %s plane: %d\n, + pipe2name(dma_planes[i]), ret); goto fail; } } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- 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