[PATCH v3 1/2] media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This is a custom multi-aspect 25MegaPixels sensor from Sony, found in many Sony Xperia smartphones from various eras. The camera assembly for this sensor usually (at least in Xperia phones) has a lens that does not cover the entire sensor area, which means that the real corners are blind and that, in many lighting conditions, some more pixels in the corners are very getting obscured (as no decent amount of light can get in)... so, the maximum resolution that can produce a good image is: - In 4:3 aspect ratio, 5520x4160 (23.0MP) - In 16:9 aspect ratio, 5984x3392 (20.3MP). This sensor supports high frame rates (>=60FPS) when in binning mode and both RAW8 and RAW10 output modes. In this version of the driver, support has been provided for the following resolutions: W x H SZ MAX_FPS BINNING - 5520x4160 23.0MP 23 No - 5984x3392 20.3MP 26 No - 2992x1696 3.8MP 60 Yes - 1424x800 1.2MP 120 Yes Note 1: The "standard" camera assy for IMX300 also contains an actuator (to focus the image), but this driver only manages the actual image sensor. Note 2: The command tables for this sensor were reverse engineered from a downstream "userspace driver" that has been released in various versions on various Xperia smartphones. Register layout seems to be only vaguely similar to IMX219, which has a public datasheet from where some names for the figured out registers were taken and added to the driver: these names are probably not the right ones, but they surely represent the intended thing. Signed-off-by: AngeloGioacchino Del Regno --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/imx300.c | 3081 3 files changed, 3095 insertions(+) create mode 100644 drivers/media/i2c/imx300.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 878f66ef2719..032f45dfed16 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -801,6 +801,19 @@ config VIDEO_IMX290 To compile this driver as a module, choose M here: the module will be called imx290. +config VIDEO_IMX300 + tristate "Sony IMX300 Exmor RS sensor support" + depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the Sony + IMX300 Exmor RS multi-aspect sensor. + + To compile this driver as a module, choose M here: the + module will be called imx300. + config VIDEO_IMX319 tristate "Sony IMX319 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index f0a77473979d..8a3e003dea45 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_VIDEO_IMX219) += imx219.o obj-$(CONFIG_VIDEO_IMX258) += imx258.o obj-$(CONFIG_VIDEO_IMX274) += imx274.o obj-$(CONFIG_VIDEO_IMX290) += imx290.o +obj-$(CONFIG_VIDEO_IMX300) += imx300.o obj-$(CONFIG_VIDEO_IMX319) += imx319.o obj-$(CONFIG_VIDEO_IMX355) += imx355.o obj-$(CONFIG_VIDEO_MAX9286)+= max9286.o diff --git a/drivers/media/i2c/imx300.c b/drivers/media/i2c/imx300.c new file mode 100644 index ..ddf0540778ae --- /dev/null +++ b/drivers/media/i2c/imx300.c @@ -0,0 +1,3081 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A V4L2 driver for Sony IMX300 Exmor RS multi-aspect image sensors. + * Copyright (C) 2020, AngeloGioacchino Del Regno + * + * Based on Sony imx219 camera driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMX300_REG_VALUE_08BIT 1 +#define IMX300_REG_VALUE_16BIT 2 + +/* + * Supported external clock frequency is from (around) 6 to 26MHz + * but there is no information about how to configure this sensor + * for anything else but 24MHz, since there is no datasheet... + */ +#define IMX300_XCLK_FREQ_24M 2400 + +/* Delay after XCLK/RESET during power up for sensor boot/stabilization */ +#define IMX300_XCLK_STABLE_DELAY_US1 +#define IMX300_XCLK_DELAY_RANGE_US 1000 +#define IMX300_XCLR_MIN_DELAY_US 25000 +#define IMX300_XCLR_DELAY_RANGE_US 1000 + +/* + * Pixel rates: max resolution + max FPS uses high bw; low resolution + * can use low bw in order to save power and limit sensor heating + */ +#define IMX300_HIGH_BW_PIXEL_RATE 62400 +#define IMX300_LOW_BW_PIXEL_RATE 38400 +#define IMX300_HIGH_BW_LINK_FREQ 78000 +#define IMX300_LOW_BW_LINK_FREQ48000 + +/* + * About the Chip ID: + * + * IMX300 seems to be sort of flawed... scanning the registers reveals + * that there's no reg having the expected 0x300 ChipID, like literally + * all of the other Sony IMX sensors. + * There seem
[PATCH v3 2/2] media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding
From: AngeloGioacchino Del Regno Add YAML device tree binding for IMX300 CMOS image sensor, and the relevant MAINTAINERS entries. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/media/i2c/sony,imx300.yaml | 112 ++ MAINTAINERS | 7 ++ 2 files changed, 119 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml new file mode 100644 index ..388297fcc358 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/sony,imx300.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony 1/2.3-Inch 25Mpixel Stacked CMOS Digital Image Sensor + +maintainers: + - AngeloGioacchino Del Regno + +description: |- + The Sony IMX300 is a 1/2.3-inch Stacked CMOS (Exmor-RS) digital image + sensor with a pixel size of 1.08um and an active array size of + 5948H x 4140V. It is programmable through I2C interface at address 0x10. + Image data is sent through MIPI CSI-2, which is configured as either 2 or + 4 data lanes. + +properties: + compatible: +const: sony,imx300 + + reg: +maxItems: 1 + + clocks: +maxItems: 1 + + vdig-supply: +description: + Digital I/O voltage supply, 1.15-1.20 volts + + vana-supply: +description: + Analog voltage supply, 2.2 volts + + vddl-supply: +description: + Digital core voltage supply, 1.8 volts + + reset-gpios: +description: |- + Reference to the GPIO connected to the xclr pin, if any. + Must be released (set high) after all supplies are applied. + + # See ../video-interfaces.txt for more details + port: +type: object +properties: + endpoint: +type: object + +properties: + data-lanes: +description: |- + The driver only supports four-lane operation. +items: + - const: 0 + - const: 1 + - const: 2 + - const: 3 + + clock-noncontinuous: true + + link-frequencies: +$ref: /schemas/types.yaml#/definitions/uint64-array +description: + Allowed data bus frequencies. The driver currently needs + to switch between 78000 and 48000 Hz in order to + guarantee functionality of all modes. + +required: + - data-lanes + - link-frequencies + +required: + - compatible + - reg + - clocks + - vana-supply + - vdig-supply + - vddl-supply + - port + +additionalProperties: false + +examples: + - | +i2c0 { +#address-cells = <1>; +#size-cells = <0>; + +imx300: sensor@10 { +compatible = "sony,imx300"; +reg = <0x10>; +clocks = <_xclk>; +vana-supply = <_vana>; /* 2.2v */ +vdig-supply = <_vdig>; /* 1.2v */ +vddl-supply = <_vddl>; /* 1.8v */ + +port { +imx300_0: endpoint { +remote-endpoint = <_ep>; +data-lanes = <0 1 2 3>; +clock-noncontinuous; +link-frequencies = /bits/ 64 <78000 48000>; +}; +}; +}; +}; + +... diff --git a/MAINTAINERS b/MAINTAINERS index c66710dd7e0a..21ba41db0063 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16279,6 +16279,13 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx290.txt F: drivers/media/i2c/imx290.c +SONY IMX300 SENSOR DRIVER +M: AngeloGioacchino Del Regno +L: linux-me...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml +F: drivers/media/i2c/imx300.c + SONY IMX319 SENSOR DRIVER M: Bingbu Cao L: linux-me...@vger.kernel.org -- 2.29.2
[PATCH v3 0/2] Add support for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This patch series adds support for the IMX300 camera sensor, (one of the) first Exmor-RS Stacked CMOS sensor(s), with support for both of the supported aspect ratios (4:3 and 16:9). This driver came out from reverse engineering of so called "userspace drivers" from Sony Xperia smartphones. I tried to document all of my findings and giving a sense to the registers as much as possible, but that was only partially possible and resembles some names from the IMX219 public datasheet, even though the addresses are basically completely different. This camera sensor driver was tested with all the resolutions declared in it on two phones: Sony Xperia XA2 and XA2 Ultra, on a SDM630 SoC (camss patches for this SoC will come in a later series) and is working great. - Changes in v3: - Removed unneeded fallthrough statements - Fixed double mode initialization at probe time - Fixed typo in the dt-binding description (8->25MPixels) - Fixed dt-binding data-lanes description, added to required properties - Changes in v2: - Changed dt-binding name and fixed a misconception about lane operation (sensor supports 2/4-Lane, driver supports 4-Lane only) - Now using lowercase names for regulator supplies - Fixed redefinition of clock-noncontinuous property - Added informations about constraints on data bus frequencies - Fixed MAINTAINERS: removed git tree AngeloGioacchino Del Regno (2): media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding .../bindings/media/i2c/sony,imx300.yaml | 112 + MAINTAINERS |7 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile|1 + drivers/media/i2c/imx300.c| 3081 + 5 files changed, 3214 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml create mode 100644 drivers/media/i2c/imx300.c -- 2.29.2
[PATCH v2 2/2] media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding
From: AngeloGioacchino Del Regno Add YAML device tree binding for IMX300 CMOS image sensor, and the relevant MAINTAINERS entries. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/media/i2c/sony,imx300.yaml | 112 ++ MAINTAINERS | 7 ++ 2 files changed, 119 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml new file mode 100644 index ..8f1d795f8072 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/sony,imx300.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony 1/2.3-Inch 8Mpixel Stacked CMOS Digital Image Sensor + +maintainers: + - AngeloGioacchino Del Regno + +description: |- + The Sony IMX300 is a 1/2.3-inch Stacked CMOS (Exmor-RS) digital image + sensor with a pixel size of 1.08um and an active array size of + 5948H x 4140V. It is programmable through I2C interface at address 0x10. + Image data is sent through MIPI CSI-2, which is configured as either 2 or + 4 data lanes. + +properties: + compatible: +const: sony,imx300 + + reg: +maxItems: 1 + + clocks: +maxItems: 1 + + vdig-supply: +description: + Digital I/O voltage supply, 1.15-1.20 volts + + vana-supply: +description: + Analog voltage supply, 2.2 volts + + vddl-supply: +description: + Digital core voltage supply, 1.8 volts + + reset-gpios: +description: |- + Reference to the GPIO connected to the xclr pin, if any. + Must be released (set high) after all supplies are applied. + + # See ../video-interfaces.txt for more details + port: +type: object +properties: + endpoint: +type: object + +properties: + data-lanes: +description: |- + The sensor supports either two-lane, or four-lane operation, + but the driver currently supports only four-lane. +items: + - const: 0 + - const: 1 + - const: 2 + - const: 3 + + clock-noncontinuous: true + + link-frequencies: +$ref: /schemas/types.yaml#/definitions/uint64-array +description: + Allowed data bus frequencies. The driver currently needs + to switch between 78000 and 48000 Hz in order to + guarantee functionality of all modes. + +required: + - link-frequencies + +required: + - compatible + - reg + - clocks + - vana-supply + - vdig-supply + - vddl-supply + - port + +additionalProperties: false + +examples: + - | +i2c0 { +#address-cells = <1>; +#size-cells = <0>; + +imx300: sensor@10 { +compatible = "sony,imx300"; +reg = <0x10>; +clocks = <_xclk>; +vana-supply = <_vana>; /* 2.2v */ +vdig-supply = <_vdig>; /* 1.2v */ +vddl-supply = <_vddl>; /* 1.8v */ + +port { +imx300_0: endpoint { +remote-endpoint = <_ep>; +data-lanes = <0 1 2 3>; +clock-noncontinuous; +link-frequencies = /bits/ 64 <78000 48000>; +}; +}; +}; +}; + +... diff --git a/MAINTAINERS b/MAINTAINERS index c66710dd7e0a..21ba41db0063 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16279,6 +16279,13 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx290.txt F: drivers/media/i2c/imx290.c +SONY IMX300 SENSOR DRIVER +M: AngeloGioacchino Del Regno +L: linux-me...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml +F: drivers/media/i2c/imx300.c + SONY IMX319 SENSOR DRIVER M: Bingbu Cao L: linux-me...@vger.kernel.org -- 2.28.0
[PATCH v2 0/2] Add support for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This patch series adds support for the IMX300 camera sensor, (one of the) first Exmor-RS Stacked CMOS sensor(s), with support for both of the supported aspect ratios (4:3 and 16:9). This driver came out from reverse engineering of so called "userspace drivers" from Sony Xperia smartphones. I tried to document all of my findings and giving a sense to the registers as much as possible, but that was only partially possible and resembles some names from the IMX219 public datasheet, even though the addresses are basically completely different. This camera sensor driver was tested with all the resolutions declared in it on two phones: Sony Xperia XA2 and XA2 Ultra, on a SDM630 SoC (camss patches for this SoC will come in a later series) and is working great. - Changes in v2: - Changed dt-binding name and fixed a misconception about lane operation (sensor supports 2/4-Lane, driver supports 4-Lane only) - Now using lowercase names for regulator supplies - Fixed redefinition of clock-noncontinuous property - Added informations about constraints on data bus frequencies - Fixed MAINTAINERS: removed git tree AngeloGioacchino Del Regno (2): media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding .../bindings/media/i2c/sony,imx300.yaml | 112 + MAINTAINERS |7 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile|1 + drivers/media/i2c/imx300.c| 3089 + 5 files changed, 3222 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml create mode 100644 drivers/media/i2c/imx300.c -- 2.28.0
[PATCH v2 1/2] media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This is a custom multi-aspect 25MegaPixels sensor from Sony, found in many Sony Xperia smartphones from various eras. The camera assembly for this sensor usually (at least in Xperia phones) has a lens that does not cover the entire sensor area, which means that the real corners are blind and that, in many lighting conditions, some more pixels in the corners are very getting obscured (as no decent amount of light can get in)... so, the maximum resolution that can produce a good image is: - In 4:3 aspect ratio, 5520x4160 (23.0MP) - In 16:9 aspect ratio, 5984x3392 (20.3MP). This sensor supports high frame rates (>=60FPS) when in binning mode and both RAW8 and RAW10 output modes. In this version of the driver, support has been provided for the following resolutions: W x H SZ MAX_FPS BINNING - 5520x4160 23.0MP 23 No - 5984x3392 20.3MP 26 No - 2992x1696 3.8MP 60 Yes - 1424x800 1.2MP 120 Yes Note 1: The "standard" camera assy for IMX300 also contains an actuator (to focus the image), but this driver only manages the actual image sensor. Note 2: The command tables for this sensor were reverse engineered from a downstream "userspace driver" that has been released in various versions on various Xperia smartphones. Register layout seems to be only vaguely similar to IMX219, which has a public datasheet from where some names for the figured out registers were taken and added to the driver: these names are probably not the right ones, but they surely represent the intended thing. Signed-off-by: AngeloGioacchino Del Regno --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/imx300.c | 3089 3 files changed, 3103 insertions(+) create mode 100644 drivers/media/i2c/imx300.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 878f66ef2719..032f45dfed16 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -801,6 +801,19 @@ config VIDEO_IMX290 To compile this driver as a module, choose M here: the module will be called imx290. +config VIDEO_IMX300 + tristate "Sony IMX300 Exmor RS sensor support" + depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the Sony + IMX300 Exmor RS multi-aspect sensor. + + To compile this driver as a module, choose M here: the + module will be called imx300. + config VIDEO_IMX319 tristate "Sony IMX319 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index f0a77473979d..8a3e003dea45 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_VIDEO_IMX219) += imx219.o obj-$(CONFIG_VIDEO_IMX258) += imx258.o obj-$(CONFIG_VIDEO_IMX274) += imx274.o obj-$(CONFIG_VIDEO_IMX290) += imx290.o +obj-$(CONFIG_VIDEO_IMX300) += imx300.o obj-$(CONFIG_VIDEO_IMX319) += imx319.o obj-$(CONFIG_VIDEO_IMX355) += imx355.o obj-$(CONFIG_VIDEO_MAX9286)+= max9286.o diff --git a/drivers/media/i2c/imx300.c b/drivers/media/i2c/imx300.c new file mode 100644 index ..47de5fa3329c --- /dev/null +++ b/drivers/media/i2c/imx300.c @@ -0,0 +1,3089 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A V4L2 driver for Sony IMX300 Exmor RS multi-aspect image sensors. + * Copyright (C) 2020, AngeloGioacchino Del Regno + * + * Based on Sony imx219 camera driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMX300_REG_VALUE_08BIT 1 +#define IMX300_REG_VALUE_16BIT 2 + +/* + * Supported external clock frequency is from (around) 6 to 26MHz + * but there is no information about how to configure this sensor + * for anything else but 24MHz, since there is no datasheet... + */ +#define IMX300_XCLK_FREQ_24M 2400 + +/* Delay after XCLK/RESET during power up for sensor boot/stabilization */ +#define IMX300_XCLK_STABLE_DELAY_US1 +#define IMX300_XCLK_DELAY_RANGE_US 1000 +#define IMX300_XCLR_MIN_DELAY_US 25000 +#define IMX300_XCLR_DELAY_RANGE_US 1000 + +/* + * Pixel rates: max resolution + max FPS uses high bw; low resolution + * can use low bw in order to save power and limit sensor heating + */ +#define IMX300_HIGH_BW_PIXEL_RATE 62400 +#define IMX300_LOW_BW_PIXEL_RATE 38400 +#define IMX300_HIGH_BW_LINK_FREQ 78000 +#define IMX300_LOW_BW_LINK_FREQ48000 + +/* + * About the Chip ID: + * + * IMX300 seems to be sort of flawed... scanning the registers reveals + * that there's no reg having the expected 0x300 ChipID, like literally + * all of the other Sony IMX sensors. + * There seem
[PATCH v9 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v9 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski Changes in v5: - Replaced subsystem maintainer's name with .. mine, usage of additionalProperties to unevaluatedProperties and a typo fix for reset-gpios as per Rob Herring's review - Changed compatible string as per Krzysztof K. request - Renamed the novatek,nt36xxx.yaml file to just nt36xxx.yaml in order to now reflect the driver name instead of the DT compatible - Fixed blank line at EOF Changes in v6: - Removed include of_gpio.h, added mod_devicetable.h and gpio/consumer.h - Added kerneldoc to relevant functions/enum - Used traditional patterns for error checking where possible - Documented calls to usleep/msleep - Using be16_to_cpu / get_unaligned_be16 where possible - Added helper for CRC error check on retrieved buffer - Decreased indentation in the CRC reboot recovery function - Removed instances of error code sum - Dropped all likely/unlikely optimization as per request - Removed redundant reset_gpio checks - Dropped of_match_ptr and ifdefs for CONFIG_OF Changes in v7: - Fixed typo in nt36xxx.c Changes in v8: - Fixed typo reset-gpio -> reset-gpios in dt-bindings Changes in v9: - Includes are now sorted - Used proposed sizeof variable instead of sizeof type - Fixed a return value check for common pattern - Added NULL check to devm_kasprintf call - Returning ret on probe function to be consistent AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../bindings/input/touchscreen/nt36xxx.yaml | 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 894 ++ drivers/input/touchscreen/nt36xxx.h | 122 +++ 6 files changed, 1090 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c create mode 100644 drivers/input/touchscreen/nt36xxx.h -- 2.28.0
[PATCH v9 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 894 drivers/input/touchscreen/nt36xxx.h | 122 4 files changed, 1029 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c create mode 100644 drivers/input/touchscreen/nt36xxx.h diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..a572d2b87464 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,894 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Novatek NT36xxx series touchscreens + * + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips
[PATCH v9 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Krzysztof Kozlowski Reviewed-by: Rob Herring --- .../bindings/input/touchscreen/nt36xxx.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml new file mode 100644 index ..a360a9f5d43b --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - AngeloGioacchino Del Regno + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36525 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36525"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpios = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v8 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/input/touchscreen/nt36xxx.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml new file mode 100644 index ..1486b20d6c49 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - AngeloGioacchino Del Regno + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36525 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36525"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpios = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v8 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 895 3 files changed, 908 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..cd37b1ab1cf5 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Novatek NT36xxx series touchscreens + * + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, +
[PATCH v8 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski Changes in v5: - Replaced subsystem maintainer's name with .. mine, usage of additionalProperties to unevaluatedProperties and a typo fix for reset-gpios as per Rob Herring's review - Changed compatible string as per Krzysztof K. request - Renamed the novatek,nt36xxx.yaml file to just nt36xxx.yaml in order to now reflect the driver name instead of the DT compatible - Fixed blank line at EOF Changes in v6: - Removed include of_gpio.h, added mod_devicetable.h and gpio/consumer.h - Added kerneldoc to relevant functions/enum - Used traditional patterns for error checking where possible - Documented calls to usleep/msleep - Using be16_to_cpu / get_unaligned_be16 where possible - Added helper for CRC error check on retrieved buffer - Decreased indentation in the CRC reboot recovery function - Removed instances of error code sum - Dropped all likely/unlikely optimization as per request - Removed redundant reset_gpio checks - Dropped of_match_ptr and ifdefs for CONFIG_OF Changes in v7: - Fixed typo in nt36xxx.c Changes in v8: - Fixed typo reset-gpio -> reset-gpios in dt-bindings AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../bindings/input/touchscreen/nt36xxx.yaml | 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 895 ++ 5 files changed, 969 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v8 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v7 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 895 3 files changed, 908 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..cd37b1ab1cf5 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Novatek NT36xxx series touchscreens + * + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, +
[PATCH v7 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski Changes in v5: - Replaced subsystem maintainer's name with .. mine, usage of additionalProperties to unevaluatedProperties and a typo fix for reset-gpios as per Rob Herring's review - Changed compatible string as per Krzysztof K. request - Renamed the novatek,nt36xxx.yaml file to just nt36xxx.yaml in order to now reflect the driver name instead of the DT compatible - Fixed blank line at EOF Changes in v6: - Removed include of_gpio.h, added mod_devicetable.h and gpio/consumer.h - Added kerneldoc to relevant functions/enum - Used traditional patterns for error checking where possible - Documented calls to usleep/msleep - Using be16_to_cpu / get_unaligned_be16 where possible - Added helper for CRC error check on retrieved buffer - Decreased indentation in the CRC reboot recovery function - Removed instances of error code sum - Dropped all likely/unlikely optimization as per request - Removed redundant reset_gpio checks - Dropped of_match_ptr and ifdefs for CONFIG_OF Changes in v7: - Fixed typo in nt36xxx.c AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../bindings/input/touchscreen/nt36xxx.yaml | 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 895 ++ 5 files changed, 969 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v7 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v7 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/input/touchscreen/nt36xxx.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml new file mode 100644 index ..1486b20d6c49 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - AngeloGioacchino Del Regno + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36525 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36525"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v6 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v6 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski Changes in v5: - Replaced subsystem maintainer's name with .. mine, usage of additionalProperties to unevaluatedProperties and a typo fix for reset-gpios as per Rob Herring's review - Changed compatible string as per Krzysztof K. request - Renamed the novatek,nt36xxx.yaml file to just nt36xxx.yaml in order to now reflect the driver name instead of the DT compatible - Fixed blank line at EOF Changes in v6: - Removed include of_gpio.h, added mod_devicetable.h and gpio/consumer.h - Added kerneldoc to relevant functions/enum - Used traditional patterns for error checking where possible - Documented calls to usleep/msleep - Using be16_to_cpu / get_unaligned_be16 where possible - Added helper for CRC error check on retrieved buffer - Decreased indentation in the CRC reboot recovery function - Removed instances of error code sum - Dropped all likely/unlikely optimization as per request - Removed redundant reset_gpio checks - Dropped of_match_ptr and ifdefs for CONFIG_OF AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../bindings/input/touchscreen/nt36xxx.yaml | 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 895 ++ 5 files changed, 969 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v6 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/input/touchscreen/nt36xxx.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml new file mode 100644 index ..1486b20d6c49 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - AngeloGioacchino Del Regno + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36525 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36525"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v6 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 895 3 files changed, 908 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..cd37b1ab1cf5 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Novatek NT36xxx series touchscreens + * + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, +
[PATCH v2 3/7] media: camss: vfe: Add support for VFE 4.8
From: AngeloGioacchino Del Regno Add the support for VFE 4.8 in the camss-vfe-4-7 driver, as this one really is a minor revision, requiring the very same management and basically having the same register layout as VFE 4.7, but needing a different QoS and DS configuration, using a different register to enable the wm and habing the same UB size for both instances (instead of a different size between instance 0 and 1). Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-vfe-4-7.c | 115 ++ drivers/media/platform/qcom/camss/camss-vfe.h | 1 + 2 files changed, 116 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 6f380a450ca1..b5704a2f119b 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -133,6 +133,11 @@ #define VFE_0_BUS_BDG_QOS_CFG_70x420 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG0x0001aaa9 +#define VFE48_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 +#define VFE48_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5 +#define VFE48_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55 +#define VFE48_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55 + #define VFE_0_BUS_BDG_DS_CFG_0 0x424 #define VFE_0_BUS_BDG_DS_CFG_0_CFG 0x0011 #define VFE_0_BUS_BDG_DS_CFG_1 0x428 @@ -153,6 +158,9 @@ #define VFE_0_BUS_BDG_DS_CFG_160x464 #define VFE_0_BUS_BDG_DS_CFG_16_CFG0x4103 +#define VFE48_0_BUS_BDG_DS_CFG_0_CFG 0x +#define VFE48_0_BUS_BDG_DS_CFG_16_CFG 0x0110 + #define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x))) #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK(0xf << 28) @@ -231,6 +239,9 @@ #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) +#define VFE48_0_BUS_IMAGE_MASTER_CMD 0xcec +#define VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(x)(2 * (x)) + #define CAMIF_TIMEOUT_SLEEP_US 1000 #define CAMIF_TIMEOUT_ALL_US 100 @@ -1139,3 +1150,107 @@ const struct vfe_hw_ops vfe_ops_4_7 = { .violation_read = vfe_violation_read, .isr = vfe_isr, }; + +static u16 vfe48_get_ub_size(u8 vfe_id) +{ + /* On VFE4.8 the ub-size is the same on both instances */ + return MSM_VFE_VFE0_UB_SIZE_RDI; +} + +static void vfe48_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +{ + if (enable) + writel_relaxed(2 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm), + vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD); + else + writel_relaxed(1 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm), + vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD); + + /* The WM must be enabled before sending other commands */ + wmb(); +} + +static void vfe48_set_qos(struct vfe_device *vfe) +{ + u32 val = VFE48_0_BUS_BDG_QOS_CFG_0_CFG; + u32 val3 = VFE48_0_BUS_BDG_QOS_CFG_3_CFG; + u32 val4 = VFE48_0_BUS_BDG_QOS_CFG_4_CFG; + u32 val7 = VFE48_0_BUS_BDG_QOS_CFG_7_CFG; + + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); + writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); + writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); +} + +static void vfe48_set_ds(struct vfe_device *vfe) +{ + u32 val = VFE48_0_BUS_BDG_DS_CFG_0_CFG; + u32 val16 = VFE48_0_BUS_BDG_DS_CFG_16_CFG; + + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); + writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); +} + +const struct vfe_hw_ops vfe_ops_4_8 =
[PATCH v2 7/7] media: camss: csiphy: Set rate on csiX_phy clock on SDM630/660
From: AngeloGioacchino Del Regno The SDM630/660 SoCs (and variants) have another clock source for the PHY, which must be set to a rate that's equal or greater than the CSI PHY timer clock: failing to do this will produce PHY overflows when trying to get a stream from a very high bandwidth camera sensor and outputting no frame or a partial one. Since I haven't found any usecase in which the csiX_phy clock needs to be higher than the csiXphy_timer, let's just set the same rate on both, which seems to work just perfect. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Robert Foss --- .../media/platform/qcom/camss/camss-csiphy.c | 22 --- .../media/platform/qcom/camss/camss-csiphy.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index c00f25aac21b..a5d717d022a5 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -113,9 +113,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy) for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = >clock[i]; - if (!strcmp(clock->name, "csiphy0_timer") || - !strcmp(clock->name, "csiphy1_timer") || - !strcmp(clock->name, "csiphy2_timer")) { + if (csiphy->rate_set[i]) { u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats, csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); @@ -611,6 +609,13 @@ int msm_csiphy_subdev_init(struct camss *camss, if (!csiphy->clock) return -ENOMEM; + csiphy->rate_set = devm_kcalloc(dev, + csiphy->nclocks, + sizeof(*csiphy->rate_set), + GFP_KERNEL); + if (!csiphy->rate_set) + return -ENOMEM; + for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = >clock[i]; @@ -638,6 +643,17 @@ int msm_csiphy_subdev_init(struct camss *camss, for (j = 0; j < clock->nfreqs; j++) clock->freq[j] = res->clock_rate[i][j]; + + if (!strcmp(clock->name, "csiphy0_timer") || + !strcmp(clock->name, "csiphy1_timer") || + !strcmp(clock->name, "csiphy2_timer")) + csiphy->rate_set[i] = true; + + if (camss->version == CAMSS_660 && + (!strcmp(clock->name, "csi0_phy") || +!strcmp(clock->name, "csi1_phy") || +!strcmp(clock->name, "csi2_phy"))) + csiphy->rate_set[i] = true; } return 0; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 376f865ad383..f7967ef836dc 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -66,6 +66,7 @@ struct csiphy_device { u32 irq; char irq_name[30]; struct camss_clock *clock; + bool *rate_set; int nclocks; u32 timer_clk_rate; struct csiphy_config cfg; -- 2.28.0
[PATCH v2 1/7] media: camss: ispif: Correctly reset based on the VFE ID
From: AngeloGioacchino Del Regno Resetting the ISPIF VFE0 context is wrong if we are using the VFE1 for dual-camera or simply because a secondary camera is connected to it: in this case the reset will always happen on the VFE0 ctx of the ISPIF, which is .. useless. Fix this usecase by adding the ISPIF_RST_CMD_1 address and choose where to do the (or what to) reset based on the VFE line id. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Robert Foss --- .../media/platform/qcom/camss/camss-ispif.c | 85 --- .../media/platform/qcom/camss/camss-ispif.h | 2 +- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index db94cfd6c508..754f0d044c38 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -26,6 +26,7 @@ #define MSM_ISPIF_NAME "msm_ispif" #define ISPIF_RST_CMD_00x008 +#define ISPIF_RST_CMD_10x00c #define ISPIF_RST_CMD_0_STROBED_RST_EN (1 << 0) #define ISPIF_RST_CMD_0_MISC_LOGIC_RST (1 << 1) #define ISPIF_RST_CMD_0_SW_REG_RST (1 << 2) @@ -179,7 +180,10 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); if ((value0 >> 27) & 0x1) - complete(>reset_complete); + complete(>reset_complete[0]); + + if ((value3 >> 27) & 0x1) + complete(>reset_complete[1]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); @@ -237,7 +241,7 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); if ((value0 >> 27) & 0x1) - complete(>reset_complete); + complete(>reset_complete[0]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); @@ -257,33 +261,18 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) return IRQ_HANDLED; } -/* - * ispif_reset - Trigger reset on ISPIF module and wait to complete - * @ispif: ISPIF device - * - * Return 0 on success or a negative error code otherwise - */ -static int ispif_reset(struct ispif_device *ispif) +static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) { unsigned long time; u32 val; - int ret; - - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); - if (ret < 0) - return ret; - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); - if (ret < 0) - return ret; - - ret = camss_enable_clocks(ispif->nclocks_for_reset, - ispif->clock_for_reset, - to_device(ispif)); - if (ret < 0) - return ret; + if (vfe_id > (to_camss(ispif)->vfe_num - 1)) { + dev_err(to_device(ispif), + "Error: asked reset for invalid VFE%d\n", vfe_id); + return -ENOENT; + } - reinit_completion(>reset_complete); + reinit_completion(>reset_complete[vfe_id]); val = ISPIF_RST_CMD_0_STROBED_RST_EN | ISPIF_RST_CMD_0_MISC_LOGIC_RST | @@ -303,15 +292,50 @@ static int ispif_reset(struct ispif_device *ispif) ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST | ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST; - writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0); + if (vfe_id == 1) + writel_relaxed(val, ispif->base + ISPIF_RST_CMD_1); + else + writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0); - time = wait_for_completion_timeout(>reset_complete, + time = wait_for_completion_timeout(>reset_complete[vfe_id], msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS)); if (!time) { - dev_err(to_device(ispif), "ISPIF reset timeout\n"); - ret = -EIO; + dev_err(to_device(ispif), + "ISPIF for VFE%d reset timeout\n", vfe_id); + return -EIO; } + return 0; +} + +/* + * ispif_reset - Trigger reset on ISPIF module and wait to complete + * @ispif: ISPIF device + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_reset(struct ispif_device *ispif, u8 vfe_id) +{ + int ret; + + ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); + if (ret < 0) + return ret; + + ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); + if (ret < 0) + return ret; + + ret = camss_enable_clocks(ispif->nclocks_for_reset, + ispif->clock_for_reset, +
[PATCH v2 0/7] Add support for SDM630/660 Camera Subsystem
From: AngeloGioacchino Del Regno This patch series implements support for the entire camera subsystem found in SDM630/636/660 and SDA variants, including CSIPHY 3-Phase, CSID v5.0, ISPIF 3.0 (though it didn't need any adaptation) and VFE 4.8. One small note about VFE4.8, even if I wrote it in the commit that adds support for it: I know, the VFE support here is split in multiple files having the name of the actual VFE version that it is targeting... but it didn't feel right to commonize the VFE 4.7 file and make another one only for VFE4.8, when it's just about something like 3 small differences. That VFE 4.8 seems to be just a minor revision of VFE 4.7. While at it, also fix a small issue when using two VFEs: only one of them was being resetted (always VFE0) so, after the first usage of VFE1, in case we leave it in a bad state, it would not properly start again. Now... it's fine :))) P.S.: SDM630/660's camss seems to be *very* similar to MSM8998, so likely 90% of this series should be reusable on that one, too! Tested on: - Sony Xperia XA2 (IMX300 on CSI0/PHY0/VFE0, IMX219 on CSI2,PHY2,VFE1) * VFE0/1 RDI only, as the VIDEO one does not work with SRGGB Bayer formats yet. As far as I can see, that color format hasn't been implemented yet in the video interface. Changes in v2: - Splitted out VFE 4.7 functions rename from the VFE 4.8 support commit - Moved a commit so that sequentially picking patches from this series still results in buildable code (heh, oops! sorry!) - Fixed ispif reset commit (moved the fix for itfrom the wrong commit to the right one: that was a "funny" overlook). AngeloGioacchino Del Regno (7): media: camss: ispif: Correctly reset based on the VFE ID media: camss: vfe-4-7: Rename get_ub_size, set_qos, set_ds, wm_enable media: camss: vfe: Add support for VFE 4.8 media: camss: Add support for SDM630/636/660 camera subsystem media: camss: csiphy-3ph: Add support for SDM630/660 media: dt-bindings: media: qcom,camss: Add bindings for SDM660 camss media: camss: csiphy: Set rate on csiX_phy clock on SDM630/660 .../devicetree/bindings/media/qcom,camss.txt | 7 + .../media/platform/qcom/camss/camss-csid.c| 9 +- .../qcom/camss/camss-csiphy-3ph-1-0.c | 7 +- .../media/platform/qcom/camss/camss-csiphy.c | 25 ++- .../media/platform/qcom/camss/camss-csiphy.h | 1 + .../media/platform/qcom/camss/camss-ispif.c | 100 ++--- .../media/platform/qcom/camss/camss-ispif.h | 2 +- .../media/platform/qcom/camss/camss-vfe-4-7.c | 131 ++- drivers/media/platform/qcom/camss/camss-vfe.c | 19 +- drivers/media/platform/qcom/camss/camss-vfe.h | 1 + .../media/platform/qcom/camss/camss-video.c | 3 +- drivers/media/platform/qcom/camss/camss.c | 206 +- drivers/media/platform/qcom/camss/camss.h | 1 + 13 files changed, 450 insertions(+), 62 deletions(-) -- 2.28.0
[PATCH v2 2/7] media: camss: vfe-4-7: Rename get_ub_size, set_qos, set_ds, wm_enable
From: AngeloGioacchino Del Regno In preparation to add support for VFE 4.8, rename these functions by adding the vfe version that they are referred to (for example, vfe_get_ub_size -> vfe47_get_ub_size), as these are the only ones that will be different for the VFE version 4.8. Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-vfe-4-7.c| 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 0dca8bf9281e..6f380a450ca1 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -246,7 +246,7 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev) dev_err(dev, "VFE HW Version = 0x%08x\n", hw_version); } -static u16 vfe_get_ub_size(u8 vfe_id) +static u16 vfe47_get_ub_size(u8 vfe_id) { if (vfe_id == 0) return MSM_VFE_VFE0_UB_SIZE_RDI; @@ -299,7 +299,7 @@ static void vfe_halt_clear(struct vfe_device *vfe) writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); } -static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +static void vfe47_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) { if (enable) vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), @@ -883,7 +883,7 @@ static void vfe_set_clamp_cfg(struct vfe_device *vfe) writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); } -static void vfe_set_qos(struct vfe_device *vfe) +static void vfe47_set_qos(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; @@ -898,7 +898,7 @@ static void vfe_set_qos(struct vfe_device *vfe) writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); } -static void vfe_set_ds(struct vfe_device *vfe) +static void vfe47_set_ds(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; @@ -1098,11 +1098,11 @@ static irqreturn_t vfe_isr(int irq, void *dev) const struct vfe_hw_ops vfe_ops_4_7 = { .hw_version_read = vfe_hw_version_read, - .get_ub_size = vfe_get_ub_size, + .get_ub_size = vfe47_get_ub_size, .global_reset = vfe_global_reset, .halt_request = vfe_halt_request, .halt_clear = vfe_halt_clear, - .wm_enable = vfe_wm_enable, + .wm_enable = vfe47_wm_enable, .wm_frame_based = vfe_wm_frame_based, .wm_line_based = vfe_wm_line_based, .wm_set_framedrop_period = vfe_wm_set_framedrop_period, @@ -1128,8 +1128,8 @@ const struct vfe_hw_ops vfe_ops_4_7 = { .set_scale_cfg = vfe_set_scale_cfg, .set_crop_cfg = vfe_set_crop_cfg, .set_clamp_cfg = vfe_set_clamp_cfg, - .set_qos = vfe_set_qos, - .set_ds = vfe_set_ds, + .set_qos = vfe47_set_qos, + .set_ds = vfe47_set_ds, .set_cgc_override = vfe_set_cgc_override, .set_camif_cfg = vfe_set_camif_cfg, .set_camif_cmd = vfe_set_camif_cmd, -- 2.28.0
[PATCH v2 5/7] media: camss: csiphy-3ph: Add support for SDM630/660
From: AngeloGioacchino Del Regno The CSIPHY on SDM630/660 needs a slightly longer T_HS_CLK_MISS configuration on lanes CFG4. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Robert Foss --- drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 2e65caf1ecae..97cb9de85031 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -8,6 +8,7 @@ * Copyright (C) 2016-2018 Linaro Ltd. */ +#include "camss.h" #include "camss-csiphy.h" #include @@ -21,6 +22,7 @@ #define CSIPHY_3PH_LNn_CFG3(n) (0x008 + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG4(n) (0x00c + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS 0xa4 +#define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660 0xa5 #define CSIPHY_3PH_LNn_CFG5(n) (0x010 + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG5_T_HS_DTERM 0x02 #define CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT 0x50 @@ -198,7 +200,10 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG; writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l)); - val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS; + if (csiphy->camss->version == CAMSS_660) + val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660; + else + val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS; writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG4(l)); val = CSIPHY_3PH_LNn_MISC1_IS_CLKLANE; -- 2.28.0
[PATCH v2 4/7] media: camss: Add support for SDM630/636/660 camera subsystem
From: AngeloGioacchino Del Regno Add support for the Qualcomm SDM630/636/660 and SDA variants' camera subsystem. These SoCs are equipped with: - 3x CSI PHY 3-Phase v1.0 (downstream csiphy-v3.5) - 4x CSID v5.0 - 2x ISPIF v3.0 - 2x VFE 4.8 As a note, this camera subsystem is very similar to the one that is found in the MSM8998/APQ8098 SoCs. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Robert Foss --- .../media/platform/qcom/camss/camss-csid.c| 9 +- .../media/platform/qcom/camss/camss-csiphy.c | 3 +- .../media/platform/qcom/camss/camss-ispif.c | 15 +- drivers/media/platform/qcom/camss/camss-vfe.c | 19 +- .../media/platform/qcom/camss/camss-video.c | 3 +- drivers/media/platform/qcom/camss/camss.c | 206 +- drivers/media/platform/qcom/camss/camss.h | 1 + 7 files changed, 237 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 2ffcda06706b..be3fe76f3dc3 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -383,7 +383,8 @@ static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, return 0; return sink_code; - } else if (csid->camss->version == CAMSS_8x96) { + } else if (csid->camss->version == CAMSS_8x96 || + csid->camss->version == CAMSS_660) { switch (sink_code) { case MEDIA_BUS_FMT_SBGGR10_1X10: { @@ -718,7 +719,8 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; - if (csid->camss->version == CAMSS_8x96) { + if (csid->camss->version == CAMSS_8x96 || + csid->camss->version == CAMSS_660) { u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code; u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code; @@ -1098,7 +1100,8 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, csid->formats = csid_formats_8x16; csid->nformats = ARRAY_SIZE(csid_formats_8x16); - } else if (camss->version == CAMSS_8x96) { + } else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) { csid->formats = csid_formats_8x96; csid->nformats = ARRAY_SIZE(csid_formats_8x96); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 03ef9c5f4774..c00f25aac21b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -552,7 +552,8 @@ int msm_csiphy_subdev_init(struct camss *camss, csiphy->ops = _ops_2ph_1_0; csiphy->formats = csiphy_formats_8x16; csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16); - } else if (camss->version == CAMSS_8x96) { + } else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) { csiphy->ops = _ops_3ph_1_0; csiphy->formats = csiphy_formats_8x96; csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96); diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 754f0d044c38..adeb92808998 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -825,7 +825,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ispif_select_csid(ispif, intf, csid, vfe, 1); ispif_select_cid(ispif, intf, cid, vfe, 1); ispif_config_irq(ispif, intf, vfe, 1); - if (to_camss(ispif)->version == CAMSS_8x96) + if (to_camss(ispif)->version == CAMSS_8x96 || + to_camss(ispif)->version == CAMSS_660) ispif_config_pack(ispif, line->fmt[MSM_ISPIF_PAD_SINK].code, intf, cid, vfe, 1); @@ -842,7 +843,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) return ret; mutex_lock(>config_lock); - if (to_camss(ispif)->version == CAMSS_8x96) + if (to_camss(ispif)->version == CAMSS_8x96 || + to_camss(ispif)->version == CAMSS_660) ispif_config_pack(ispif, line->fmt[MSM_ISPIF_PAD_SINK].code, intf, cid, vfe, 0); @@ -1098,7 +1100,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, /* Number of
[PATCH v2 6/7] media: dt-bindings: media: qcom,camss: Add bindings for SDM660 camss
From: AngeloGioacchino Del Regno Add bindings for qcom,sdm660-camss in order to support the camera subsystem on SDM630/660 and SDA variants. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Robert Foss --- Documentation/devicetree/bindings/media/qcom,camss.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt index 09eb6ed99114..498234629e21 100644 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -8,6 +8,7 @@ Qualcomm Camera Subsystem Definition: Should contain one of: - "qcom,msm8916-camss" - "qcom,msm8996-camss" + - "qcom,sdm660-camss" - reg: Usage: required Value type: @@ -64,30 +65,36 @@ Qualcomm Camera Subsystem Value type: Definition: Should contain the following entries: - "top_ahb" + - "throttle_axi"(660 only) - "ispif_ahb" - "csiphy0_timer" - "csiphy1_timer" - "csiphy2_timer" (8996 only) + - "csiphy_ahb2crif" (660 only) - "csi0_ahb" - "csi0" - "csi0_phy" - "csi0_pix" - "csi0_rdi" + - "cphy_csid0" (660 only) - "csi1_ahb" - "csi1" - "csi1_phy" - "csi1_pix" - "csi1_rdi" + - "cphy_csid1" (660 only) - "csi2_ahb"(8996 only) - "csi2"(8996 only) - "csi2_phy"(8996 only) - "csi2_pix"(8996 only) - "csi2_rdi"(8996 only) + - "cphy_csid2" (660 only) - "csi3_ahb"(8996 only) - "csi3"(8996 only) - "csi3_phy"(8996 only) - "csi3_pix"(8996 only) - "csi3_rdi"(8996 only) + - "cphy_csid3" (660 only) - "ahb" - "vfe0" - "csi_vfe0" -- 2.28.0
[PATCH 3/6] media: camss: vfe: Add support for VFE 4.8
From: AngeloGioacchino Del Regno Add the support for VFE 4.8 in the camss-vfe-4-7 driver, as this one really is a minor revision, requiring the very same management and basically having the same register layout as VFE 4.7, but needing a different QoS and DS configuration, using a different register to enable the wm and habing the same UB size for both instances (instead of a different size between instance 0 and 1). Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-vfe-4-7.c | 129 -- drivers/media/platform/qcom/camss/camss-vfe.h | 1 + 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 0dca8bf9281e..e48d58a4a9d1 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -133,6 +133,11 @@ #define VFE_0_BUS_BDG_QOS_CFG_70x420 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG0x0001aaa9 +#define VFE48_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 +#define VFE48_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5 +#define VFE48_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55 +#define VFE48_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55 + #define VFE_0_BUS_BDG_DS_CFG_0 0x424 #define VFE_0_BUS_BDG_DS_CFG_0_CFG 0x0011 #define VFE_0_BUS_BDG_DS_CFG_1 0x428 @@ -153,6 +158,9 @@ #define VFE_0_BUS_BDG_DS_CFG_160x464 #define VFE_0_BUS_BDG_DS_CFG_16_CFG0x4103 +#define VFE48_0_BUS_BDG_DS_CFG_0_CFG 0x +#define VFE48_0_BUS_BDG_DS_CFG_16_CFG 0x0110 + #define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x))) #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK(0xf << 28) @@ -231,6 +239,9 @@ #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) +#define VFE48_0_BUS_IMAGE_MASTER_CMD 0xcec +#define VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(x)(2 * (x)) + #define CAMIF_TIMEOUT_SLEEP_US 1000 #define CAMIF_TIMEOUT_ALL_US 100 @@ -246,7 +257,7 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev) dev_err(dev, "VFE HW Version = 0x%08x\n", hw_version); } -static u16 vfe_get_ub_size(u8 vfe_id) +static u16 vfe47_get_ub_size(u8 vfe_id) { if (vfe_id == 0) return MSM_VFE_VFE0_UB_SIZE_RDI; @@ -299,7 +310,7 @@ static void vfe_halt_clear(struct vfe_device *vfe) writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); } -static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +static void vfe47_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) { if (enable) vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), @@ -883,7 +894,7 @@ static void vfe_set_clamp_cfg(struct vfe_device *vfe) writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); } -static void vfe_set_qos(struct vfe_device *vfe) +static void vfe47_set_qos(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; @@ -898,7 +909,7 @@ static void vfe_set_qos(struct vfe_device *vfe) writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); } -static void vfe_set_ds(struct vfe_device *vfe) +static void vfe47_set_ds(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; @@ -1098,11 +1109,113 @@ static irqreturn_t vfe_isr(int irq, void *dev) const struct vfe_hw_ops vfe_ops_4_7 = { .hw_version_read = vfe_hw_version_read, - .get_ub_size = vfe_get_ub_size, + .get_ub_size = vfe47_get_ub_size, + .global_reset = vfe_global_reset, + .halt_request = vfe_halt_request, + .halt_clear = vfe_halt_clear, + .wm_enable = vfe47_wm_enable, + .wm_frame_based = vfe_wm_frame_based, + .wm_line_based = vfe_wm_line_based, + .wm_set_framedrop_period = vfe_wm_set_framedrop_period, + .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, + .wm_set_ub_cfg = vfe_wm_set_ub_cfg, + .bus_reload_wm = vfe_bus_reload_wm, + .wm_set_ping_addr = vfe_wm_set_ping_addr, + .wm_set_pong_addr = vfe_wm_set_pong_addr, + .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, + .bus_enable_wr_if = vfe_bus_enable_wr_if, + .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, + .wm_set_subsample = vfe_wm_set_subsample, + .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, + .set_xbar_cfg = vfe_set_xbar_cfg, + .set_realign_cfg = vfe_set_realign_cfg, + .set_rdi_cid = vfe_set_rdi_cid, + .reg_update = vfe_reg_update, + .reg_update_clear = vfe_reg_update_clear, + .enable_irq_wm_line = vfe_enable_irq_wm_line, + .enable_irq_pix_line = vfe_enable_irq_pix_line, + .enable_irq_common = vfe_enable_irq_common, +
[PATCH 2/6] media: camss: ispif: Correctly reset based on the VFE ID
From: AngeloGioacchino Del Regno Resetting the ISPIF VFE0 context is wrong if we are using the VFE1 for dual-camera or simply because a secondary camera is connected to it: in this case the reset will always happen on the VFE0 ctx of the ISPIF, which is .. useless. Fix this usecase by adding the ISPIF_RST_CMD_1 address and choose where to do the (or what to) reset based on the VFE line id. Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-ispif.c | 87 --- .../media/platform/qcom/camss/camss-ispif.h | 2 +- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index db94cfd6c508..252db6b33dab 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -26,6 +26,7 @@ #define MSM_ISPIF_NAME "msm_ispif" #define ISPIF_RST_CMD_00x008 +#define ISPIF_RST_CMD_10x00c #define ISPIF_RST_CMD_0_STROBED_RST_EN (1 << 0) #define ISPIF_RST_CMD_0_MISC_LOGIC_RST (1 << 1) #define ISPIF_RST_CMD_0_SW_REG_RST (1 << 2) @@ -179,7 +180,10 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); if ((value0 >> 27) & 0x1) - complete(>reset_complete); + complete(>reset_complete[0]); + + if ((value3 >> 27) & 0x1) + complete(>reset_complete[1]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); @@ -237,7 +241,7 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); if ((value0 >> 27) & 0x1) - complete(>reset_complete); + complete(>reset_complete[0]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); @@ -257,33 +261,17 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) return IRQ_HANDLED; } -/* - * ispif_reset - Trigger reset on ISPIF module and wait to complete - * @ispif: ISPIF device - * - * Return 0 on success or a negative error code otherwise - */ -static int ispif_reset(struct ispif_device *ispif) +static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) { - unsigned long time; u32 val; - int ret; - - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); - if (ret < 0) - return ret; - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); - if (ret < 0) - return ret; - - ret = camss_enable_clocks(ispif->nclocks_for_reset, - ispif->clock_for_reset, - to_device(ispif)); - if (ret < 0) - return ret; + if (vfe_id > (to_camss(ispif)->vfe_num - 1)) { + dev_err(to_device(ispif), + "Error: asked reset for invalid VFE%d\n", vfe_id); + return -ENOENT; + } - reinit_completion(>reset_complete); + reinit_completion(>reset_complete[vfe_id]); val = ISPIF_RST_CMD_0_STROBED_RST_EN | ISPIF_RST_CMD_0_MISC_LOGIC_RST | @@ -303,15 +291,51 @@ static int ispif_reset(struct ispif_device *ispif) ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST | ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST; - writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0); + if (vfe_id == 1) + writel_relaxed(val, ispif->base + ISPIF_RST_CMD_1); + else + writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0); - time = wait_for_completion_timeout(>reset_complete, + time = wait_for_completion_timeout(>reset_complete[vfe_id], msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS)); if (!time) { - dev_err(to_device(ispif), "ISPIF reset timeout\n"); - ret = -EIO; + dev_err(to_device(ispif), + "ISPIF for VFE%d reset timeout\n", vfe_id); + return -EIO; } + return 0; +} + +/* + * ispif_reset - Trigger reset on ISPIF module and wait to complete + * @ispif: ISPIF device + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_reset(struct ispif_device *ispif, u8 vfe_id) +{ + unsigned long time; + int ret; + + ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); + if (ret < 0) + return ret; + + ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); + if (ret < 0) + return ret; + + ret = camss_enable_clocks(ispif->nclocks_for_reset, + ispif->clock_for_reset, +
[PATCH 5/6] media: dt-bindings: media: qcom,camss: Add bindings for SDM660 camss
From: AngeloGioacchino Del Regno Add bindings for qcom,sdm660-camss in order to support the camera subsystem on SDM630/660 and SDA variants. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/media/qcom,camss.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt index 09eb6ed99114..498234629e21 100644 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -8,6 +8,7 @@ Qualcomm Camera Subsystem Definition: Should contain one of: - "qcom,msm8916-camss" - "qcom,msm8996-camss" + - "qcom,sdm660-camss" - reg: Usage: required Value type: @@ -64,30 +65,36 @@ Qualcomm Camera Subsystem Value type: Definition: Should contain the following entries: - "top_ahb" + - "throttle_axi"(660 only) - "ispif_ahb" - "csiphy0_timer" - "csiphy1_timer" - "csiphy2_timer" (8996 only) + - "csiphy_ahb2crif" (660 only) - "csi0_ahb" - "csi0" - "csi0_phy" - "csi0_pix" - "csi0_rdi" + - "cphy_csid0" (660 only) - "csi1_ahb" - "csi1" - "csi1_phy" - "csi1_pix" - "csi1_rdi" + - "cphy_csid1" (660 only) - "csi2_ahb"(8996 only) - "csi2"(8996 only) - "csi2_phy"(8996 only) - "csi2_pix"(8996 only) - "csi2_rdi"(8996 only) + - "cphy_csid2" (660 only) - "csi3_ahb"(8996 only) - "csi3"(8996 only) - "csi3_phy"(8996 only) - "csi3_pix"(8996 only) - "csi3_rdi"(8996 only) + - "cphy_csid3" (660 only) - "ahb" - "vfe0" - "csi_vfe0" -- 2.28.0
[PATCH 6/6] media: camss: csiphy: Set rate on csiX_phy clock on SDM630/660
From: AngeloGioacchino Del Regno The SDM630/660 SoCs (and variants) have another clock source for the PHY, which must be set to a rate that's equal or greater than the CSI PHY timer clock: failing to do this will produce PHY overflows when trying to get a stream from a very high bandwidth camera sensor and outputting no frame or a partial one. Since I haven't found any usecase in which the csiX_phy clock needs to be higher than the csiXphy_timer, let's just set the same rate on both, which seems to work just perfect. Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-csiphy.c | 22 --- .../media/platform/qcom/camss/camss-csiphy.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index c00f25aac21b..a5d717d022a5 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -113,9 +113,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy) for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = >clock[i]; - if (!strcmp(clock->name, "csiphy0_timer") || - !strcmp(clock->name, "csiphy1_timer") || - !strcmp(clock->name, "csiphy2_timer")) { + if (csiphy->rate_set[i]) { u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats, csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); @@ -611,6 +609,13 @@ int msm_csiphy_subdev_init(struct camss *camss, if (!csiphy->clock) return -ENOMEM; + csiphy->rate_set = devm_kcalloc(dev, + csiphy->nclocks, + sizeof(*csiphy->rate_set), + GFP_KERNEL); + if (!csiphy->rate_set) + return -ENOMEM; + for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = >clock[i]; @@ -638,6 +643,17 @@ int msm_csiphy_subdev_init(struct camss *camss, for (j = 0; j < clock->nfreqs; j++) clock->freq[j] = res->clock_rate[i][j]; + + if (!strcmp(clock->name, "csiphy0_timer") || + !strcmp(clock->name, "csiphy1_timer") || + !strcmp(clock->name, "csiphy2_timer")) + csiphy->rate_set[i] = true; + + if (camss->version == CAMSS_660 && + (!strcmp(clock->name, "csi0_phy") || +!strcmp(clock->name, "csi1_phy") || +!strcmp(clock->name, "csi2_phy"))) + csiphy->rate_set[i] = true; } return 0; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 376f865ad383..f7967ef836dc 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -66,6 +66,7 @@ struct csiphy_device { u32 irq; char irq_name[30]; struct camss_clock *clock; + bool *rate_set; int nclocks; u32 timer_clk_rate; struct csiphy_config cfg; -- 2.28.0
[PATCH 4/6] media: camss: Add support for SDM630/636/660 camera subsystem
From: AngeloGioacchino Del Regno Add support for the Qualcomm SDM630/636/660 and SDA variants' camera subsystem. These SoCs are equipped with: - 3x CSI PHY 3-Phase v1.0 (downstream csiphy-v3.5) - 4x CSID v5.0 - 2x ISPIF v3.0 - 2x VFE 4.8 As a note, this camera subsystem is very similar to the one that is found in the MSM8998/APQ8098 SoCs. Signed-off-by: AngeloGioacchino Del Regno --- .../media/platform/qcom/camss/camss-csid.c| 9 +- .../media/platform/qcom/camss/camss-csiphy.c | 3 +- .../media/platform/qcom/camss/camss-ispif.c | 17 +- drivers/media/platform/qcom/camss/camss-vfe.c | 19 +- .../media/platform/qcom/camss/camss-video.c | 3 +- drivers/media/platform/qcom/camss/camss.c | 206 +- drivers/media/platform/qcom/camss/camss.h | 1 + 7 files changed, 238 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 2ffcda06706b..be3fe76f3dc3 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -383,7 +383,8 @@ static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, return 0; return sink_code; - } else if (csid->camss->version == CAMSS_8x96) { + } else if (csid->camss->version == CAMSS_8x96 || + csid->camss->version == CAMSS_660) { switch (sink_code) { case MEDIA_BUS_FMT_SBGGR10_1X10: { @@ -718,7 +719,8 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; - if (csid->camss->version == CAMSS_8x96) { + if (csid->camss->version == CAMSS_8x96 || + csid->camss->version == CAMSS_660) { u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code; u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code; @@ -1098,7 +1100,8 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, csid->formats = csid_formats_8x16; csid->nformats = ARRAY_SIZE(csid_formats_8x16); - } else if (camss->version == CAMSS_8x96) { + } else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) { csid->formats = csid_formats_8x96; csid->nformats = ARRAY_SIZE(csid_formats_8x96); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 03ef9c5f4774..c00f25aac21b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -552,7 +552,8 @@ int msm_csiphy_subdev_init(struct camss *camss, csiphy->ops = _ops_2ph_1_0; csiphy->formats = csiphy_formats_8x16; csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16); - } else if (camss->version == CAMSS_8x96) { + } else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) { csiphy->ops = _ops_3ph_1_0; csiphy->formats = csiphy_formats_8x96; csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96); diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 252db6b33dab..adeb92808998 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -263,6 +263,7 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) { + unsigned long time; u32 val; if (vfe_id > (to_camss(ispif)->vfe_num - 1)) { @@ -315,7 +316,6 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) */ static int ispif_reset(struct ispif_device *ispif, u8 vfe_id) { - unsigned long time; int ret; ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); @@ -825,7 +825,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ispif_select_csid(ispif, intf, csid, vfe, 1); ispif_select_cid(ispif, intf, cid, vfe, 1); ispif_config_irq(ispif, intf, vfe, 1); - if (to_camss(ispif)->version == CAMSS_8x96) + if (to_camss(ispif)->version == CAMSS_8x96 || + to_camss(ispif)->version == CAMSS_660) ispif_config_pack(ispif, line->fmt[MSM_ISPIF_PAD_SINK].code, intf, cid, vfe, 1); @@ -842,7 +843,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) return ret;
[PATCH 0/6] Add support for SDM630/660 Camera Subsystem
From: AngeloGioacchino Del Regno This patch series implements support for the entire camera subsystem found in SDM630/636/660 and SDA variants, including CSIPHY 3-Phase, CSID v5.0, ISPIF 3.0 (though it didn't need any adaptation) and VFE 4.8. One small note about VFE4.8, even if I wrote it in the commit that adds support for it: I know, the VFE support here is split in multiple files having the name of the actual VFE version that it is targeting... but it didn't feel right to commonize the VFE 4.7 file and make another one only for VFE4.8, when it's just about something like 3 small differences. That VFE 4.8 seems to be just a minor revision of VFE 4.7. While at it, also fix a small issue when using two VFEs: only one of them was being resetted (always VFE0) so, after the first usage of VFE1, in case we leave it in a bad state, it would not properly start again. Now... it's fine :))) P.S.: SDM630/660's camss seems to be *very* similar to MSM8998, so likely 90% of this series should be reusable on that one, too! Tested on: - Sony Xperia XA2 (IMX300 on CSI0/PHY0/VFE0, IMX219 on CSI2,PHY2,VFE1) * VFE0/1 RDI only, as the VIDEO one does not work with SRGGB Bayer formats yet. As far as I can see, that color format hasn't been implemented yet in the video interface. AngeloGioacchino Del Regno (6): media: camss: csiphy-3ph: Add support for SDM630/660 media: camss: ispif: Correctly reset based on the VFE ID media: camss: vfe: Add support for VFE 4.8 media: camss: Add support for SDM630/636/660 camera subsystem media: dt-bindings: media: qcom,camss: Add bindings for SDM660 camss media: camss: csiphy: Set rate on csiX_phy clock on SDM630/660 .../devicetree/bindings/media/qcom,camss.txt | 7 + .../media/platform/qcom/camss/camss-csid.c| 9 +- .../qcom/camss/camss-csiphy-3ph-1-0.c | 7 +- .../media/platform/qcom/camss/camss-csiphy.c | 25 ++- .../media/platform/qcom/camss/camss-csiphy.h | 1 + .../media/platform/qcom/camss/camss-ispif.c | 100 ++--- .../media/platform/qcom/camss/camss-ispif.h | 2 +- .../media/platform/qcom/camss/camss-vfe-4-7.c | 129 ++- drivers/media/platform/qcom/camss/camss-vfe.c | 19 +- drivers/media/platform/qcom/camss/camss-vfe.h | 1 + .../media/platform/qcom/camss/camss-video.c | 3 +- drivers/media/platform/qcom/camss/camss.c | 206 +- drivers/media/platform/qcom/camss/camss.h | 1 + 13 files changed, 448 insertions(+), 62 deletions(-) -- 2.28.0
[PATCH 1/6] media: camss: csiphy-3ph: Add support for SDM630/660
From: AngeloGioacchino Del Regno The CSIPHY on SDM630/660 needs a slightly longer T_HS_CLK_MISS configuration on lanes CFG4. Signed-off-by: AngeloGioacchino Del Regno --- drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 2e65caf1ecae..97cb9de85031 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -8,6 +8,7 @@ * Copyright (C) 2016-2018 Linaro Ltd. */ +#include "camss.h" #include "camss-csiphy.h" #include @@ -21,6 +22,7 @@ #define CSIPHY_3PH_LNn_CFG3(n) (0x008 + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG4(n) (0x00c + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS 0xa4 +#define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660 0xa5 #define CSIPHY_3PH_LNn_CFG5(n) (0x010 + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG5_T_HS_DTERM 0x02 #define CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT 0x50 @@ -198,7 +200,10 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG; writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l)); - val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS; + if (csiphy->camss->version == CAMSS_660) + val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660; + else + val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS; writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG4(l)); val = CSIPHY_3PH_LNn_MISC1_IS_CLKLANE; -- 2.28.0
[PATCH 1/2] media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This is a custom multi-aspect 25MegaPixels sensor from Sony, found in many Sony Xperia smartphones from various eras. The camera assembly for this sensor usually (at least in Xperia phones) has a lens that does not cover the entire sensor area, which means that the real corners are blind and that, in many lighting conditions, some more pixels in the corners are very getting obscured (as no decent amount of light can get in)... so, the maximum resolution that can produce a good image is: - In 4:3 aspect ratio, 5520x4160 (23.0MP) - In 16:9 aspect ratio, 5984x3392 (20.3MP). This sensor supports high frame rates (>=60FPS) when in binning mode and both RAW8 and RAW10 output modes. In this version of the driver, support has been provided for the following resolutions: W x H SZ MAX_FPS BINNING - 5520x4160 23.0MP 23 No - 5984x3392 20.3MP 26 No - 2992x1696 3.8MP 60 Yes - 1424x800 1.2MP 120 Yes Note 1: The "standard" camera assy for IMX300 also contains an actuator (to focus the image), but this driver only manages the actual image sensor. Note 2: The command tables for this sensor were reverse engineered from a downstream "userspace driver" that has been released in various versions on various Xperia smartphones. Register layout seems to be only vaguely similar to IMX219, which has a public datasheet from where some names for the figured out registers were taken and added to the driver: these names are probably not the right ones, but they surely represent the intended thing. Signed-off-by: AngeloGioacchino Del Regno --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/imx300.c | 3087 3 files changed, 3101 insertions(+) create mode 100644 drivers/media/i2c/imx300.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 878f66ef2719..032f45dfed16 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -801,6 +801,19 @@ config VIDEO_IMX290 To compile this driver as a module, choose M here: the module will be called imx290. +config VIDEO_IMX300 + tristate "Sony IMX300 Exmor RS sensor support" + depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the Sony + IMX300 Exmor RS multi-aspect sensor. + + To compile this driver as a module, choose M here: the + module will be called imx300. + config VIDEO_IMX319 tristate "Sony IMX319 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index f0a77473979d..8a3e003dea45 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_VIDEO_IMX219) += imx219.o obj-$(CONFIG_VIDEO_IMX258) += imx258.o obj-$(CONFIG_VIDEO_IMX274) += imx274.o obj-$(CONFIG_VIDEO_IMX290) += imx290.o +obj-$(CONFIG_VIDEO_IMX300) += imx300.o obj-$(CONFIG_VIDEO_IMX319) += imx319.o obj-$(CONFIG_VIDEO_IMX355) += imx355.o obj-$(CONFIG_VIDEO_MAX9286)+= max9286.o diff --git a/drivers/media/i2c/imx300.c b/drivers/media/i2c/imx300.c new file mode 100644 index ..a3e699d2dd42 --- /dev/null +++ b/drivers/media/i2c/imx300.c @@ -0,0 +1,3087 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A V4L2 driver for Sony IMX300 Exmor RS multi-aspect image sensors. + * Copyright (C) 2020, AngeloGioacchino Del Regno + * + * Based on Sony imx219 camera driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMX300_REG_VALUE_08BIT 1 +#define IMX300_REG_VALUE_16BIT 2 + +/* + * Supported external clock frequency is from (around) 6 to 26MHz + * but there is no information about how to configure this sensor + * for anything else but 24MHz, since there is no datasheet... + */ +#define IMX300_XCLK_FREQ_24M 2400 + +/* Delay after XCLK/RESET during power up for sensor boot/stabilization */ +#define IMX300_XCLK_STABLE_DELAY_US1 +#define IMX300_XCLK_DELAY_RANGE_US 1000 +#define IMX300_XCLR_MIN_DELAY_US 25000 +#define IMX300_XCLR_DELAY_RANGE_US 1000 + +/* + * Pixel rates: max resolution + max FPS uses high bw; low resolution + * can use low bw in order to save power and limit sensor heating + */ +#define IMX300_HIGH_BW_PIXEL_RATE 62400 +#define IMX300_LOW_BW_PIXEL_RATE 38400 +#define IMX300_HIGH_BW_LINK_FREQ 78000 +#define IMX300_LOW_BW_LINK_FREQ48000 + +/* + * About the Chip ID: + * + * IMX300 seems to be sort of flawed... scanning the registers reveals + * that there's no reg having the expected 0x300 ChipID, like literally + * all of the other Sony IMX sensors. + * There seem
[PATCH 2/2] media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding
From: AngeloGioacchino Del Regno Add YAML device tree binding for IMX300 CMOS image sensor, and the relevant MAINTAINERS entries. Signed-off-by: AngeloGioacchino Del Regno --- .../devicetree/bindings/media/i2c/imx300.yaml | 115 ++ MAINTAINERS | 8 ++ 2 files changed, 123 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/imx300.yaml diff --git a/Documentation/devicetree/bindings/media/i2c/imx300.yaml b/Documentation/devicetree/bindings/media/i2c/imx300.yaml new file mode 100644 index ..82fb19c5018c --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/imx300.yaml @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/imx300.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony 1/2.3-Inch 8Mpixel Stacked CMOS Digital Image Sensor + +maintainers: + - AngeloGioacchino Del Regno + +description: |- + The Sony IMX300 is a 1/2.3-inch Stacked CMOS (Exmor-RS) digital image + sensor with a pixel size of 1.08um and an active array size of + 5948H x 4140V. It is programmable through I2C interface at address 0x10. + Image data is sent through MIPI CSI-2, which is configured as either 2 or + 4 data lanes. + +properties: + compatible: +const: sony,imx300 + + reg: +description: I2C device address +maxItems: 1 + + clocks: +maxItems: 1 + + VDIG-supply: +description: + Digital I/O voltage supply, 1.15-1.20 volts + + VANA-supply: +description: + Analog voltage supply, 2.2 volts + + VDDL-supply: +description: + Digital core voltage supply, 1.8 volts + + reset-gpios: +description: |- + Reference to the GPIO connected to the xclr pin, if any. + Must be released (set high) after all supplies are applied. + + # See ../video-interfaces.txt for more details + port: +type: object +properties: + endpoint: +type: object +properties: + data-lanes: +description: |- + The sensor supports either two-lane, or four-lane operation. + If this property is omitted four-lane operation is assumed. + For four-lane operation the property must be set to <0 1 2 3>. +items: + - const: 0 + - const: 1 + - const: 2 + - const: 3 + + clock-noncontinuous: +type: boolean +description: |- + MIPI CSI-2 clock is non-continuous if this property is present, + otherwise it's continuous. + + link-frequencies: +$ref: /schemas/types.yaml#/definitions/uint64-array +description: + Allowed data bus frequencies. + +required: + - link-frequencies + +required: + - compatible + - reg + - clocks + - VANA-supply + - VDIG-supply + - VDDL-supply + - port + +additionalProperties: false + +examples: + - | +i2c0 { +#address-cells = <1>; +#size-cells = <0>; + +imx300: sensor@10 { +compatible = "sony,imx300"; +reg = <0x10>; +clocks = <_xclk>; +VANA-supply = <_vana>; /* 2.2v */ +VDIG-supply = <_vdig>; /* 1.2v */ +VDDL-supply = <_vddl>; /* 1.8v */ + +port { +imx300_0: endpoint { +remote-endpoint = <_ep>; +data-lanes = <0 1 2 3>; +clock-noncontinuous; +link-frequencies = /bits/ 64 <78000 48000>; +}; +}; +}; +}; + +... diff --git a/MAINTAINERS b/MAINTAINERS index c66710dd7e0a..231937d9d16a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16279,6 +16279,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx290.txt F: drivers/media/i2c/imx290.c +SONY IMX300 SENSOR DRIVER +M: AngeloGioacchino Del Regno +L: linux-me...@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/imx300.yaml +F: drivers/media/i2c/imx300.c + SONY IMX319 SENSOR DRIVER M: Bingbu Cao L: linux-me...@vger.kernel.org -- 2.28.0
[PATCH 0/2] Add support for the Sony Exmor-RS IMX300 camera sensor
From: AngeloGioacchino Del Regno This patch series adds support for the IMX300 camera sensor, (one of the) first Exmor-RS Stacked CMOS sensor(s), with support for both of the supported aspect ratios (4:3 and 16:9). This driver came out from reverse engineering of so called "userspace drivers" from Sony Xperia smartphones. I tried to document all of my findings and giving a sense to the registers as much as possible, but that was only partially possible and resembles some names from the IMX219 public datasheet, even though the addresses are basically completely different. This camera sensor driver was tested with all the resolutions declared in it on two phones: Sony Xperia XA2 and XA2 Ultra, on a SDM630 SoC (camss patches for this SoC will come in a later series) and is working great. AngeloGioacchino Del Regno (2): media: i2c: Add driver for the Sony Exmor-RS IMX300 camera sensor media: dt-bindings: media: i2c: Add IMX300 CMOS sensor binding .../devicetree/bindings/media/i2c/imx300.yaml | 115 + MAINTAINERS |8 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile|1 + drivers/media/i2c/imx300.c| 3087 + 5 files changed, 3224 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/imx300.yaml create mode 100644 drivers/media/i2c/imx300.c -- 2.28.0
[PATCH v2 2/2] dt-bindings: power: rpmpd: Add SDM660 power-domains bindings
From: Konrad Dybcio Add the new bindings for SDM660 rpmpd power domains. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- .../devicetree/bindings/power/qcom,rpmpd.yaml| 1 + include/dt-bindings/power/qcom-rpmpd.h | 12 2 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 8058955fb3b9..45ec2439ff51 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -20,6 +20,7 @@ properties: - qcom,msm8996-rpmpd - qcom,msm8998-rpmpd - qcom,qcs404-rpmpd + - qcom,sdm660-rpmpd - qcom,sc7180-rpmhpd - qcom,sdm845-rpmhpd - qcom,sm8150-rpmhpd diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 5e61eaf73bdd..2a39dc40483d 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -102,6 +102,18 @@ #define QCS404_LPIMX 5 #define QCS404_LPIMX_VFL 6 +/* SDM660 Power Domains */ +#define SDM660_VDDCX 0 +#define SDM660_VDDCX_AO1 +#define SDM660_VDDCX_VFL 2 +#define SDM660_VDDMX 3 +#define SDM660_VDDMX_AO4 +#define SDM660_VDDMX_VFL 5 +#define SDM660_SSCCX 6 +#define SDM660_SSCCX_VFL 7 +#define SDM660_SSCMX 8 +#define SDM660_SSCMX_VFL 9 + /* RPM SMD Power Domain performance levels */ #define RPM_SMD_LEVEL_RETENTION 16 #define RPM_SMD_LEVEL_RETENTION_PLUS 32 -- 2.28.0
[PATCH v2 1/2] soc: qcom: rpmpd: Add SDM660 power-domains
From: Konrad Dybcio Add the shared cx/mx and sensor sub-system's cx and mx power-domains found on SDM660. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- drivers/soc/qcom/rpmpd.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index f2168e4259b2..0de40ac1b42c 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -220,11 +220,44 @@ static const struct rpmpd_desc qcs404_desc = { .max_state = RPM_SMD_LEVEL_BINNING, }; +/* sdm660 RPM Power domains */ +DEFINE_RPMPD_PAIR(sdm660, vddcx, vddcx_ao, RWCX, LEVEL, 0); +DEFINE_RPMPD_VFL(sdm660, vddcx_vfl, RWCX, 0); + +DEFINE_RPMPD_PAIR(sdm660, vddmx, vddmx_ao, RWMX, LEVEL, 0); +DEFINE_RPMPD_VFL(sdm660, vddmx_vfl, RWMX, 0); + +DEFINE_RPMPD_LEVEL(sdm660, vdd_ssccx, RWLC, 0); +DEFINE_RPMPD_VFL(sdm660, vdd_ssccx_vfl, RWLC, 0); + +DEFINE_RPMPD_LEVEL(sdm660, vdd_sscmx, RWLM, 0); +DEFINE_RPMPD_VFL(sdm660, vdd_sscmx_vfl, RWLM, 0); + +static struct rpmpd *sdm660_rpmpds[] = { + [SDM660_VDDCX] =_vddcx, + [SDM660_VDDCX_AO] = _vddcx_ao, + [SDM660_VDDCX_VFL] =_vddcx_vfl, + [SDM660_VDDMX] =_vddmx, + [SDM660_VDDMX_AO] = _vddmx_ao, + [SDM660_VDDMX_VFL] =_vddmx_vfl, + [SDM660_SSCCX] =_vdd_ssccx, + [SDM660_SSCCX_VFL] =_vdd_ssccx_vfl, + [SDM660_SSCMX] =_vdd_sscmx, + [SDM660_SSCMX_VFL] =_vdd_sscmx_vfl, +}; + +static const struct rpmpd_desc sdm660_desc = { + .rpmpds = sdm660_rpmpds, + .num_pds = ARRAY_SIZE(sdm660_rpmpds), + .max_state = RPM_SMD_LEVEL_TURBO, +}; + static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,msm8976-rpmpd", .data = _desc }, { .compatible = "qcom,msm8996-rpmpd", .data = _desc }, { .compatible = "qcom,msm8998-rpmpd", .data = _desc }, { .compatible = "qcom,qcs404-rpmpd", .data = _desc }, + { .compatible = "qcom,sdm660-rpmpd", .data = _desc }, { } }; MODULE_DEVICE_TABLE(of, rpmpd_match_table); -- 2.28.0
[PATCH v5 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v5 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 815 3 files changed, 828 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..893ed7b6faf6 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, + NT36870_IC, + NTMAX_IC, +}; + +struct nt36xxx_trim_table { + u8
[PATCH v5 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski Changes in v5: - Replaced subsystem maintainer's name with .. mine, usage of additionalProperties to unevaluatedProperties and a typo fix for reset-gpios as per Rob Herring's review - Changed compatible string as per Krzysztof K. request - Renamed the novatek,nt36xxx.yaml file to just nt36xxx.yaml in order to now reflect the driver name instead of the DT compatible - Fixed blank line at EOF AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../bindings/input/touchscreen/nt36xxx.yaml | 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 815 ++ 5 files changed, 889 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v5 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/input/touchscreen/nt36xxx.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml new file mode 100644 index ..1486b20d6c49 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - AngeloGioacchino Del Regno + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36525 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36525"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v4 1/2] dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC
From: AngeloGioacchino Del Regno Add the bindings for the Qualcomm SDM660-class NoC, valid for SDM630, SDM636, SDM660 and SDA variants. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/interconnect/qcom,sdm660.yaml| 147 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 ++ 2 files changed, 263 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml new file mode 100644 index ..29de7807df54 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sdm660.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SDM660 Network-On-Chip interconnect + +maintainers: + - AngeloGioacchino Del Regno + +description: | + The Qualcomm SDM660 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + reg: +maxItems: 1 + + compatible: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-mnoc + - qcom,sdm660-snoc + + '#interconnect-cells': +const: 1 + + clocks: +minItems: 1 +maxItems: 3 + + clock-names: +minItems: 1 +maxItems: 3 + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: false + +allOf: + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-mnoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +- description: CPU-NoC High-performance Bus Clock. +clock-names: + items: +- const: bus +- const: bus_a +- const: iface + + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-snoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +clock-names: + items: +- const: bus +- const: bus_a + +examples: + - | + #include + #include + + bimc: interconnect@1008000 { + compatible = "qcom,sdm660-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_BIMC_CLK>, + < RPM_SMD_BIMC_A_CLK>; + }; + + cnoc: interconnect@150 { + compatible = "qcom,sdm660-cnoc"; + reg = <0x0150 0x1>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_CNOC_CLK>, + < RPM_SMD_CNOC_A_CLK>; + }; + + snoc: interconnect@1626000 { + compatible = "qcom,sdm660-snoc"; + reg = <0x01626000 0x7090>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_SNOC_CLK>, + < RPM_SMD_SNOC_A_CLK>; + }; + + a2noc: interconnect@1704000 { + compatible = "qcom,sdm660-a2noc"; + reg = <0x01704000 0xc100>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_AGGR2_NOC_CLK>, + < RPM_SMD_AGGR2_NOC_A_CLK>; + }; + + mnoc: interconnect@1745000 { + compatible = "qcom,sdm660-mnoc"; + reg = <0x01745000 0xa010>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a", "iface"; + clocks = < RPM_SMD_MMSSNOC_AXI_CLK>, + < RPM_SMD_MMSSNOC_AXI_CLK_A>, + < AHB_CLK_SRC>; + }; + + gnoc: interconnect@1790 { + compatible = "qcom,sdm660-gnoc"; + reg = <0x1790 0xe000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <_board>, <_board>; + }; diff --git a/include/dt-bindings/interconnect/qcom,sdm660.h b/include/dt-bindings/interconnect/qcom,sdm660.h new file mode 100644 index ..62e8d8670d5e --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sdm660.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* SDM660
[PATCH v4 2/2] interconnect: qcom: Add SDM660 interconnect provider driver
From: AngeloGioacchino Del Regno Introduce a driver for the Qualcomm interconnect busses found in the SDM630/SDM636/SDM660 SoCs. The topology consists of several NoCs that are controlled by a remote processor that collects the aggregated bandwidth for each master-slave pairs. On a note, these chips are managing the "bus QoS" in a "hybrid" fashion: some of the paths in the topology are managed through (and by, of course) the RPM uC, while some others are "AP Owned", meaning that the AP shall do direct writes to the appropriate QoS registers for the specific paths and ports, instead of sending an indication to the RPM and leaving the job to that one. Signed-off-by: AngeloGioacchino Del Regno --- drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/sdm660.c | 922 + 3 files changed, 933 insertions(+) create mode 100644 drivers/interconnect/qcom/sdm660.c diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index a8f93ba265f8..ae76527a22f6 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -42,6 +42,15 @@ config INTERCONNECT_QCOM_QCS404 This is a driver for the Qualcomm Network-on-Chip on qcs404-based platforms. +config INTERCONNECT_QCOM_SDM660 + tristate "Qualcomm SDM660 interconnect driver" + depends on INTERCONNECT_QCOM + depends on QCOM_SMD_RPM + select INTERCONNECT_QCOM_SMD_RPM + help + This is a driver for the Qualcomm Network-on-Chip on sdm660-based + platforms. + config INTERCONNECT_QCOM_RPMH tristate diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index cf628f7990cd..ebe15d1dfe8b 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -7,6 +7,7 @@ icc-osm-l3-objs := osm-l3.o qnoc-qcs404-objs := qcs404.o icc-rpmh-obj := icc-rpmh.o qnoc-sc7180-objs := sc7180.o +qnoc-sdm660-objs := sdm660.o qnoc-sdm845-objs := sdm845.o qnoc-sm8150-objs := sm8150.o qnoc-sm8250-objs := sm8250.o @@ -19,6 +20,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o +obj-$(CONFIG_INTERCONNECT_QCOM_SDM660) += qnoc-sdm660.o obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8150) += qnoc-sm8150.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8250) += qnoc-sm8250.o diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c new file mode 100644 index ..6953d6d99a11 --- /dev/null +++ b/drivers/interconnect/qcom/sdm660.c @@ -0,0 +1,922 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Qualcomm SDM630/SDM636/SDM660 Network-on-Chip (NoC) QoS driver + * Copyright (C) 2020, AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smd-rpm.h" + +#define RPM_BUS_MASTER_REQ 0x73616d62 +#define RPM_BUS_SLAVE_REQ 0x766c7362 + +/* BIMC QoS */ +#define M_BKE_REG_BASE(n) (0x300 + (0x4000 * n)) +#define M_BKE_EN_ADDR(n) (M_BKE_REG_BASE(n)) +#define M_BKE_HEALTH_CFG_ADDR(i, n)(M_BKE_REG_BASE(n) + 0x40 + (0x4 * i)) + +#define M_BKE_HEALTH_CFG_LIMITCMDS_MASK0x8000 +#define M_BKE_HEALTH_CFG_AREQPRIO_MASK 0x300 +#define M_BKE_HEALTH_CFG_PRIOLVL_MASK 0x3 +#define M_BKE_HEALTH_CFG_AREQPRIO_SHIFT0x8 +#define M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT 0x1f + +#define M_BKE_EN_EN_BMASK 0x1 + +/* Valid for both NoC and BIMC */ +#define NOC_QOS_MODE_FIXED 0x0 +#define NOC_QOS_MODE_LIMITER 0x1 +#define NOC_QOS_MODE_BYPASS0x2 + +/* NoC QoS */ +#define NOC_PERM_MODE_FIXED1 +#define NOC_PERM_MODE_BYPASS (1 << NOC_QOS_MODE_BYPASS) + +#define NOC_QOS_PRIORITYn_ADDR(n) (0x8 + (n * 0x1000)) +#define NOC_QOS_PRIORITY_MASK 0xf +#define NOC_QOS_PRIORITY_P1_SHIFT 0x2 +#define NOC_QOS_PRIORITY_P0_SHIFT 0x3 + +#define NOC_QOS_MODEn_ADDR(n) (0xc + (n * 0x1000)) +#define NOC_QOS_MODEn_MASK 0x3 + +enum { + SDM660_MASTER_IPA = 1, + SDM660_MASTER_CNOC_A2NOC, + SDM660_MASTER_SDCC_1, + SDM660_MASTER_SDCC_2, + SDM660_MASTER_BLSP_1, + SDM660_MASTER_BLSP_2, + SDM660_MASTER_UFS, + SDM660_MASTER_USB_HS, + SDM660_MASTER_USB3, + SDM660_MASTER_CRYPTO_C0, + SDM660_MASTER_GNOC_BIMC, + SDM660_MASTER_OXILI, + SDM660_MASTER_MNOC_BIMC, + SDM660_MASTER_SNOC_BIMC, + SDM660_MASTER_PIMEM, +
[PATCH v4 0/2] Add SDM630/636/660 interconnect driver
From: AngeloGioacchino Del Regno This patch series adds the SDM660 interconnect provider driver in order to stop some timeouts and achieve some decent performance by avoiding to be NoC limited. It's also providing some power consumption improvement, but I have only measured that as less heat, which is quite important when working on thermally constrained devices like smartphones. Please note that this driver's yaml binding is referring to a MMCC clock, so this series does depend on the SDM660 MMCC driver that I have sent separately. The multimedia clock is required only for the Multimedia NoC (mnoc). This patch series has been tested against the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Added missing qcom,mmcc-sdm660.h dt-binding include in the interconnect/qcom,sdm660.yaml binding, as pointed out by Rob Herring Changes in v3: - Moved the dt-bindings/interconnect/qcom,sdm660.h header to dt-bindings commit. Changes in v4: - Fixed code style issues and removed unused defines as per Georgi Djakov's review - Fixed the SDCC2 RPM master/slave IDs - Added an exception to stop writing LIMITCMDS to M_BKE_HEALTH_3 as it doesn't exist there (it seems to be harmless to write that there, but it's incorrect to) - Tested again on the aforementioned devices AngeloGioacchino Del Regno (2): dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC interconnect: qcom: Add SDM660 interconnect provider driver .../bindings/interconnect/qcom,sdm660.yaml| 147 +++ drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile| 2 + drivers/interconnect/qcom/sdm660.c| 922 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 +++ 5 files changed, 1196 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml create mode 100644 drivers/interconnect/qcom/sdm660.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h -- 2.28.0
[PATCH v3 1/2] dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC
From: AngeloGioacchino Del Regno Add the bindings for the Qualcomm SDM660-class NoC, valid for SDM630, SDM636, SDM660 and SDA variants. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/interconnect/qcom,sdm660.yaml| 147 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 ++ 2 files changed, 263 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml new file mode 100644 index ..440e9bc1382a --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sdm660.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SDM660 Network-On-Chip interconnect + +maintainers: + - Georgi Djakov + +description: | + The Qualcomm SDM660 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + reg: +maxItems: 1 + + compatible: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-mnoc + - qcom,sdm660-snoc + + '#interconnect-cells': +const: 1 + + clocks: +minItems: 1 +maxItems: 3 + + clock-names: +minItems: 1 +maxItems: 3 + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: false + +allOf: + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-mnoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +- description: CPU-NoC High-performance Bus Clock. +clock-names: + items: +- const: bus +- const: bus_a +- const: iface + + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-snoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +clock-names: + items: +- const: bus +- const: bus_a + +examples: + - | + #include + #include + + bimc: interconnect@1008000 { + compatible = "qcom,sdm660-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_BIMC_CLK>, + < RPM_SMD_BIMC_A_CLK>; + }; + + cnoc: interconnect@150 { + compatible = "qcom,sdm660-cnoc"; + reg = <0x0150 0x1>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_CNOC_CLK>, + < RPM_SMD_CNOC_A_CLK>; + }; + + snoc: interconnect@1626000 { + compatible = "qcom,sdm660-snoc"; + reg = <0x01626000 0x7090>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_SNOC_CLK>, + < RPM_SMD_SNOC_A_CLK>; + }; + + a2noc: interconnect@1704000 { + compatible = "qcom,sdm660-a2noc"; + reg = <0x01704000 0xc100>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_AGGR2_NOC_CLK>, + < RPM_SMD_AGGR2_NOC_A_CLK>; + }; + + mnoc: interconnect@1745000 { + compatible = "qcom,sdm660-mnoc"; + reg = <0x01745000 0xa010>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a", "iface"; + clocks = < RPM_SMD_MMSSNOC_AXI_CLK>, + < RPM_SMD_MMSSNOC_AXI_CLK_A>, + < AHB_CLK_SRC>; + }; + + gnoc: interconnect@1790 { + compatible = "qcom,sdm660-gnoc"; + reg = <0x1790 0xe000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <_board>, <_board>; + }; diff --git a/include/dt-bindings/interconnect/qcom,sdm660.h b/include/dt-bindings/interconnect/qcom,sdm660.h new file mode 100644 index ..62e8d8670d5e --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sdm660.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* SDM660 interconnect
[PATCH v3 2/2] interconnect: qcom: Add SDM660 interconnect provider driver
From: AngeloGioacchino Del Regno Introduce a driver for the Qualcomm interconnect busses found in the SDM630/SDM636/SDM660 SoCs. The topology consists of several NoCs that are controlled by a remote processor that collects the aggregated bandwidth for each master-slave pairs. On a note, these chips are managing the "bus QoS" in a "hybrid" fashion: some of the paths in the topology are managed through (and by, of course) the RPM uC, while some others are "AP Owned", meaning that the AP shall do direct writes to the appropriate QoS registers for the specific paths and ports, instead of sending an indication to the RPM and leaving the job to that one. Signed-off-by: AngeloGioacchino Del Regno --- drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/sdm660.c | 919 + 3 files changed, 930 insertions(+) create mode 100644 drivers/interconnect/qcom/sdm660.c diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index a8f93ba265f8..ae76527a22f6 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -42,6 +42,15 @@ config INTERCONNECT_QCOM_QCS404 This is a driver for the Qualcomm Network-on-Chip on qcs404-based platforms. +config INTERCONNECT_QCOM_SDM660 + tristate "Qualcomm SDM660 interconnect driver" + depends on INTERCONNECT_QCOM + depends on QCOM_SMD_RPM + select INTERCONNECT_QCOM_SMD_RPM + help + This is a driver for the Qualcomm Network-on-Chip on sdm660-based + platforms. + config INTERCONNECT_QCOM_RPMH tristate diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index cf628f7990cd..ebe15d1dfe8b 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -7,6 +7,7 @@ icc-osm-l3-objs := osm-l3.o qnoc-qcs404-objs := qcs404.o icc-rpmh-obj := icc-rpmh.o qnoc-sc7180-objs := sc7180.o +qnoc-sdm660-objs := sdm660.o qnoc-sdm845-objs := sdm845.o qnoc-sm8150-objs := sm8150.o qnoc-sm8250-objs := sm8250.o @@ -19,6 +20,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o +obj-$(CONFIG_INTERCONNECT_QCOM_SDM660) += qnoc-sdm660.o obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8150) += qnoc-sm8150.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8250) += qnoc-sm8250.o diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c new file mode 100644 index ..9ad709dde913 --- /dev/null +++ b/drivers/interconnect/qcom/sdm660.c @@ -0,0 +1,919 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Qualcomm SDM630/SDM636/SDM660 Network-on-Chip (NoC) QoS driver + * Copyright (C) 2020, AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smd-rpm.h" + +#define RPM_BUS_MASTER_REQ 0x73616d62 +#define RPM_BUS_SLAVE_REQ 0x766c7362 + +/* BIMC QoS */ +#define M_BKE_REG_BASE(n) (0x300 + (0x4000 * n)) +#define M_BKE_EN_ADDR(n) (M_BKE_REG_BASE(n)) +#define M_BKE_HEALTH_CFG_ADDR(i, n)(M_BKE_REG_BASE(n) + 0x40 + (0x4 * i)) + +#define M_BKE_HEALTH_CFG_LIMITCMDS_MASK0x8000 +#define M_BKE_HEALTH_CFG_AREQPRIO_MASK 0x300 +#define M_BKE_HEALTH_CFG_REG_MASK(n) ((n == 3) ? 0x303 : 0x8303) +#define M_BKE_HEALTH_CFG_PRIOLVL_MASK 0x3 +#define M_BKE_HEALTH_CFG_AREQPRIO_SHIFT0x8 +#define M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT 0x1f + +#define M_BKE_HEALTH_CFG_ALL_MASK (M_BKE_HEALTH_CFG_LIMITCMDS_MASK | \ +M_BKE_HEALTH_CFG_AREQPRIO_MASK | \ +M_BKE_HEALTH_CFG_PRIOLVL_MASK) + +#define M_BKE_EN_EN_BMASK 0x1 + +/* Valid for both NoC and BIMC */ +#define NOC_QOS_MODE_FIXED 0x0 +#define NOC_QOS_MODE_LIMITER 0x1 +#define NOC_QOS_MODE_BYPASS0x2 + +/* NoC QoS */ +#define NOC_PERM_MODE_FIXED1 +#define NOC_PERM_MODE_BYPASS (1 << NOC_QOS_MODE_BYPASS) + +#define NOC_QOS_PRIORITYn_ADDR(n) (0x8 + (n * 0x1000)) +#define NOC_QOS_PRIORITY_MASK 0xf +#define NOC_QOS_PRIORITY_P1_SHIFT 0x2 +#define NOC_QOS_PRIORITY_P0_SHIFT 0x3 + +#define NOC_QOS_MODEn_ADDR(n) (0xC + (n * 0x1000)) +#define NOC_QOS_MODEn_MASK 0x3 + +enum { + SDM660_MASTER_IPA = 1, + SDM660_MASTER_CNOC_A2NOC, + SDM660_MASTER_SDCC_1, + SDM660_MASTER_SDCC_2, + SDM660_MASTER_BLSP_1, +
[PATCH v3 0/2] Add SDM630/636/660 interconnect driver
From: AngeloGioacchino Del Regno This patch series adds the SDM660 interconnect provider driver in order to stop some timeouts and achieve some decent performance by avoiding to be NoC limited. It's also providing some power consumption improvement, but I have only measured that as less heat, which is quite important when working on thermally constrained devices like smartphones. Please note that this driver's yaml binding is referring to a MMCC clock, so this series does depend on the SDM660 MMCC driver that I have sent separately. The multimedia clock is required only for the Multimedia NoC (mnoc). This patch series has been tested against the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Added missing qcom,mmcc-sdm660.h dt-binding include in the interconnect/qcom,sdm660.yaml binding, as pointed out by Rob Herring Changes in v3: - Moved the dt-bindings/interconnect/qcom,sdm660.h header to dt-bindings commit. AngeloGioacchino Del Regno (2): dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC interconnect: qcom: Add SDM660 interconnect provider driver .../bindings/interconnect/qcom,sdm660.yaml| 147 +++ drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile| 2 + drivers/interconnect/qcom/sdm660.c| 919 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 +++ 5 files changed, 1193 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml create mode 100644 drivers/interconnect/qcom/sdm660.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h -- 2.28.0
[PATCH v4 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 816 3 files changed, 829 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..c6fe5d223051 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,816 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, + NT36870_IC, + NTMAX_IC, +}; + +struct nt36xxx_trim_table { + u8
[PATCH v4 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../input/touchscreen/novatek,nt36xxx.yaml| 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml new file mode 100644 index ..e747cacae036 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/novatek,nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - Dmitry Torokhov + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +const: novatek,nt36xxx + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + reset-gpio: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-supply: +description: Power supply regulator on VDD-IO pin + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +#include +#include + +i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@62 { +compatible = "novatek,nt36xxx"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v4 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v4 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! Changes in v4: - Fixed regmap read length for CRC_ERR_FLAG final check - Fixed YAML binding, as requested by Krzysztof Kozlowski AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../input/touchscreen/novatek,nt36xxx.yaml| 59 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 816 ++ 5 files changed, 890 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v3 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot Changes in v3 (as requested by Dmitry Torokhov): - Using shorthand u16/u32 (sorry for the overlook!) - Now using more input and touchscreen APIs - Fixed useless workqueue involvements - Removed useless locking - Switched reads and writes to use regmap - Moved header contents to nt36xxx.c - Fixed reset gpio handling - Other cleanups - P.S.: Thanks, Dmitry! AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../input/touchscreen/novatek,nt36xxx.yaml| 56 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 816 ++ 5 files changed, 887 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c -- 2.28.0
[PATCH v3 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v3 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../input/touchscreen/novatek,nt36xxx.yaml| 56 +++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml new file mode 100644 index ..9f350f4e6d6a --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/novatek,nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - TBD + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +enum: + - novatek,nt36xxx + + reg: +enum: [ 0x62 ] + + interrupts: +maxItems: 1 + + reset-gpio: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-reg-name: +description: Power supply regulator on VDD-IO pin + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +i2c { + #address-cells = <1>; + #size-cells = <0>; + nt36xxx@62 { +compatible = "novatek,nt36xxx"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v3 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 816 3 files changed, 829 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..ced649a4e769 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,816 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FW Param address */ +#define NT36XXX_FW_ADDR 0x01 + +/* Number of bytes for chip identification */ +#define NT36XXX_ID_LEN_MAX 6 + +/* Touch info */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2246 +#define TOUCH_MAX_FINGER_NUM10 +#define TOUCH_MAX_PRESSURE 1000 + +/* Point data length */ +#define POINT_DATA_LEN 65 + +/* Global pages */ +#define NT36XXX_PAGE_CHIP_INFO 0x0001f64e +#define NT36XXX_PAGE_CRC 0x0003f135 + +/* Misc */ +#define NT36XXX_NUM_SUPPLIES2 +#define NT36XXX_MAX_RETRIES 5 +#define NT36XXX_MAX_FW_RST_RETRY 50 + +struct nt36xxx_abs_object { + u16 x; + u16 y; + u16 z; + u8 tm; +}; + +struct nt36xxx_fw_info { + u8 fw_ver; + u8 x_num; + u8 y_num; + u8 max_buttons; + u16 abs_x_max; + u16 abs_y_max; + u16 nvt_pid; +}; + +struct nt36xxx_mem_map { + u32 evtbuf_addr; + u32 pipe0_addr; + u32 pipe1_addr; + u32 flash_csum_addr; + u32 flash_data_addr; +}; + +struct nt36xxx_i2c { + struct i2c_client *hw_client; + struct i2c_client *fw_client; + struct regmap *regmap; + struct regmap *fw_regmap; + struct input_dev *input; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + + struct mutex lock; + + struct touchscreen_properties prop; + struct nt36xxx_fw_info fw_info; + struct nt36xxx_abs_object abs_obj; + + const struct nt36xxx_mem_map *mmap; +}; + +enum nt36xxx_chips { + NT36525_IC = 0, + NT36672A_IC, + NT36676F_IC, + NT36772_IC, + NT36870_IC, + NTMAX_IC, +}; + +struct nt36xxx_trim_table { + u8
[PATCH v2 4/7] drm/msm/a5xx: Reset VBIF before PC only on A510 and A530
From: AngeloGioacchino Del Regno Resetting the VBIF before power collapse is done to avoid getting bogus FIFO entries during the suspend sequence or subsequent resume, but this is doable only on Adreno 510 and Adreno 530, as the other units will tendentially lock up. Especially on Adreno 508, the GPU will show lockups and very bad slownesses after processing the first frame. Avoiding to execute the RBBM SW Reset before suspend will stop the lockup issue from happening on at least Adreno 508/509/512. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index fd33a34961cc..6163c3b61a69 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1306,10 +1306,12 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu) /* * Reset the VBIF before power collapse to avoid issue with FIFO -* entries +* entries on Adreno A510 and A530 (the others will tend to lock up) */ - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C); - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x); + if (adreno_is_a510(adreno_gpu) || adreno_is_a530(adreno_gpu)) { + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C); + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x); + } return msm_gpu_pm_suspend(gpu); } -- 2.28.0
[PATCH v2 2/7] drm/msm/a5xx: Separate A5XX_PC_DBG_ECO_CNTL write from main branch
From: AngeloGioacchino Del Regno The "main" if branch where we program the other registers for the Adreno 5xx family of GPUs should not contain the PC_DBG_ECO_CNTL register programming because this has logical similarity differences from all the others. A later commit will show the entire sense of this. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 6262603e6e2e..f98f0844838c 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -577,8 +577,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20); gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x4030); gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A); - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, - (0x200 << 11 | 0x200 << 22)); } else { gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40); if (adreno_is_a530(adreno_gpu)) @@ -587,9 +585,14 @@ static int a5xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400); gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x8060); gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16); + } + + if (adreno_is_a510(adreno_gpu)) + gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, + (0x200 << 11 | 0x200 << 22)); + else gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22)); - } if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); -- 2.28.0
[PATCH v2 5/7] drm/msm/a5xx: Fix VPC protect value in gpu_write()
From: Konrad Dybcio The upstream API for some reason uses logbase2 instead of just passing the argument as-is, whereas downstream CAF kernel does the latter. Hence, a mistake has been made when porting: 4 is the value that's supposed to be passed, but log2(4) = 2. Changing the value to 16 (= 2^4) fixes the issue. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 6163c3b61a69..448fded571d3 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -789,7 +789,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu) /* VPC */ gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8)); - gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 4)); + gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 16)); /* UCHE */ gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16)); -- 2.28.0
[PATCH v2 6/7] drm/msm/a5xx: Disable flat shading optimization
From: Konrad Dybcio Port over the command from downstream to prevent undefined behaviour. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 448fded571d3..6dac060902a3 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -759,6 +759,9 @@ static int a5xx_hw_init(struct msm_gpu *gpu) adreno_is_a540(adreno_gpu)) gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, bit); + /* Disable All flat shading optimization (ALLFLATOPTDIS) */ + gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10)); + /* Protect registers from the CP */ gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x0007); -- 2.28.0
[PATCH v2 7/7] drm/msm/a5xx: Disable UCHE global filter
From: Konrad Dybcio Port over the command from downstream to prevent undefined behaviour. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/msm/adreno/a5xx.xml.h | 2 ++ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx.xml.h b/drivers/gpu/drm/msm/adreno/a5xx.xml.h index 346cc6ff3a36..7b9fcfe95c04 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a5xx.xml.h @@ -2367,6 +2367,8 @@ static inline uint32_t A5XX_VSC_RESOLVE_CNTL_Y(uint32_t val) #define REG_A5XX_UCHE_ADDR_MODE_CNTL 0x0e80 +#define REG_A5XX_UCHE_MODE_CNTL 0x0e81 + #define REG_A5XX_UCHE_SVM_CNTL 0x0e82 #define REG_A5XX_UCHE_WRITE_THRU_BASE_LO 0x0e87 diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 6dac060902a3..979397372505 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -722,6 +722,9 @@ static int a5xx_hw_init(struct msm_gpu *gpu) adreno_is_a512(adreno_gpu)) gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, 0, (1 << 9)); + /* Disable UCHE global filter as SP can invalidate/flush independently */ + gpu_write(gpu, REG_A5XX_UCHE_MODE_CNTL, BIT(29)); + /* Enable USE_RETENTION_FLOPS */ gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x0200); -- 2.28.0
[PATCH v2 3/7] drm/msm/a5xx: Add support for Adreno 508, 509, 512 GPUs
From: AngeloGioacchino Del Regno The Adreno 508/509/512 GPUs are stripped versions of the Adreno 5xx found in the mid-end SoCs such as SDM630, SDM636, SDM660 and SDA variants; these SoCs are usually provided with ZAP firmwares, but they have no available GPMU. Signed-off-by: AngeloGioacchino Del Regno Tested-by: Martin Botka Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 172 ++--- drivers/gpu/drm/msm/adreno/a5xx_power.c| 4 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 60 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 15 ++ 4 files changed, 231 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index f98f0844838c..fd33a34961cc 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -212,7 +212,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, a5xx_preempt_trigger(gpu); } -static const struct { +static const struct adreno_five_hwcg_regs { u32 offset; u32 value; } a5xx_hwcg[] = { @@ -308,16 +308,124 @@ static const struct { {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x4000}, {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x0200}, {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x} +}, a50x_hwcg[] = { + {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x0222}, + {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x0220}, + {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0xF3CF}, + {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x0080}, + {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x0022}, + {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00F4}, + {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x0002}, + {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x0022}, + {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x0000}, + {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x0552}, + {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x0050}, + {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, + {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, + {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x0002}, + {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, + {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x0422}, + {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x0222}, + {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x4000}, + {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x0200}, + {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x}, +}, a512_hwcg[] = { + {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x0222}, + {REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x0222}, + {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x0220}, + {REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x0220}, + {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0xF3CF}, + {REG_A5XX_RBBM_CLOCK_HYST_SP1, 0xF3CF}, + {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x0080}, + {REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x0080}, + {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x}, + {REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x}, + {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x}, +
[PATCH v2 1/7] drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register
From: AngeloGioacchino Del Regno The PC_DBG_ECO_CNTL register on the Adreno A5xx family gets programmed to some different values on a per-model basis. At least, this is what we intend to do here; Unfortunately, though, this register is being overwritten with a static magic number, right after applying the GPU-specific configuration (including the GPU-specific quirks) and that is effectively nullifying the efforts. Let's remove the redundant and wrong write to the PC_DBG_ECO_CNTL register in order to retain the wanted configuration for the target GPU. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 91726da82ed6..6262603e6e2e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -594,8 +594,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu) if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); - /* Enable USE_RETENTION_FLOPS */ gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x0200); -- 2.28.0
[PATCH v2 0/7] Add support for Adreno 508/509/512
From: AngeloGioacchino Del Regno In this patch series, we are adding support for lower end Adreno 5 series GPUs, such as A508, A509 and A512 that we have found in the Qualcomm SDM630, SDM636 and SDM660 SoCs. On a note, adding support for these three units, also adds 99% of the required "things" for another two GPUs, A505 and A506 but, even if adding them requires literally two lines of code, noone of us has got any SoC equipped with these ones hence we wouldn't be able to test. Even though there is basically no reason for them to not work correctly, kernel side, I chose to avoid adding the two "magic" lines. Anyway, this patchset also addresses some issues that we've found in the A5XX part of the Adreno driver, regarding a logic mistake in one of the VPC protect values and a forced overwrite of the register named A5XX_PC_DBG_ECO_CNTL, forcing the setting of vtxFifo and primFifo thresholds that was valid only for higher end GPUs. This patch series has been tested on the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Define REG_A5XX_UCHE_MODE_CNTL and fix open-coded REG_A5XX_VPC_DBG_ECO_CNTL in the all flat shading optimization disablement commit, as requested by Rob Clark. AngeloGioacchino Del Regno (4): drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register drm/msm/a5xx: Separate A5XX_PC_DBG_ECO_CNTL write from main branch drm/msm/a5xx: Add support for Adreno 508, 509, 512 GPUs drm/msm/a5xx: Reset VBIF before PC only on A510 and A530 Konrad Dybcio (3): drm/msm/a5xx: Fix VPC protect value in gpu_write() drm/msm/a5xx: Disable flat shading optimization drm/msm/a5xx: Disable UCHE global filter drivers/gpu/drm/msm/adreno/a5xx.xml.h | 2 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 195 ++--- drivers/gpu/drm/msm/adreno/a5xx_power.c| 4 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 60 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 15 ++ 5 files changed, 249 insertions(+), 27 deletions(-) -- 2.28.0
[PATCH v2 2/2] dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC
From: AngeloGioacchino Del Regno Add the bindings for the Qualcomm SDM660-class NoC, valid for SDM630, SDM636, SDM660 and SDA variants. Signed-off-by: AngeloGioacchino Del Regno --- .../bindings/interconnect/qcom,sdm660.yaml| 147 ++ 1 file changed, 147 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml new file mode 100644 index ..440e9bc1382a --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sdm660.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SDM660 Network-On-Chip interconnect + +maintainers: + - Georgi Djakov + +description: | + The Qualcomm SDM660 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + reg: +maxItems: 1 + + compatible: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-mnoc + - qcom,sdm660-snoc + + '#interconnect-cells': +const: 1 + + clocks: +minItems: 1 +maxItems: 3 + + clock-names: +minItems: 1 +maxItems: 3 + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: false + +allOf: + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-mnoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +- description: CPU-NoC High-performance Bus Clock. +clock-names: + items: +- const: bus +- const: bus_a +- const: iface + + - if: + properties: +compatible: + contains: +enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-snoc +then: + properties: +clocks: + items: +- description: Bus Clock. +- description: Bus A Clock. +clock-names: + items: +- const: bus +- const: bus_a + +examples: + - | + #include + #include + + bimc: interconnect@1008000 { + compatible = "qcom,sdm660-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_BIMC_CLK>, + < RPM_SMD_BIMC_A_CLK>; + }; + + cnoc: interconnect@150 { + compatible = "qcom,sdm660-cnoc"; + reg = <0x0150 0x1>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_CNOC_CLK>, + < RPM_SMD_CNOC_A_CLK>; + }; + + snoc: interconnect@1626000 { + compatible = "qcom,sdm660-snoc"; + reg = <0x01626000 0x7090>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_SNOC_CLK>, + < RPM_SMD_SNOC_A_CLK>; + }; + + a2noc: interconnect@1704000 { + compatible = "qcom,sdm660-a2noc"; + reg = <0x01704000 0xc100>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = < RPM_SMD_AGGR2_NOC_CLK>, + < RPM_SMD_AGGR2_NOC_A_CLK>; + }; + + mnoc: interconnect@1745000 { + compatible = "qcom,sdm660-mnoc"; + reg = <0x01745000 0xa010>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a", "iface"; + clocks = < RPM_SMD_MMSSNOC_AXI_CLK>, + < RPM_SMD_MMSSNOC_AXI_CLK_A>, + < AHB_CLK_SRC>; + }; + + gnoc: interconnect@1790 { + compatible = "qcom,sdm660-gnoc"; + reg = <0x1790 0xe000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <_board>, <_board>; + }; -- 2.28.0
[PATCH v2 0/2] Add SDM630/636/660 interconnect driver
From: AngeloGioacchino Del Regno This patch series adds the SDM660 interconnect provider driver in order to stop some timeouts and achieve some decent performance by avoiding to be NoC limited. It's also providing some power consumption improvement, but I have only measured that as less heat, which is quite important when working on thermally constrained devices like smartphones. Please note that this driver's yaml binding is referring to a MMCC clock, so this series does depend on the SDM660 MMCC driver that I have sent separately. The multimedia clock is required only for the Multimedia NoC (mnoc). This patch series has been tested against the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Added missing qcom,mmcc-sdm660.h dt-binding include in the interconnect/qcom,sdm660.yaml binding, as pointed out by Rob Herring AngeloGioacchino Del Regno (2): interconnect: qcom: Add SDM660 interconnect provider driver dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC AngeloGioacchino Del Regno (2): interconnect: qcom: Add SDM660 interconnect provider driver dt-bindings: interconnect: Add bindings for Qualcomm SDM660 NoC .../bindings/interconnect/qcom,sdm660.yaml| 147 +++ drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile| 2 + drivers/interconnect/qcom/sdm660.c| 919 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 +++ 5 files changed, 1193 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml create mode 100644 drivers/interconnect/qcom/sdm660.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h -- 2.28.0
[PATCH v2 1/2] interconnect: qcom: Add SDM660 interconnect provider driver
From: AngeloGioacchino Del Regno Introduce a driver for the Qualcomm interconnect busses found in the SDM630/SDM636/SDM660 SoCs. The topology consists of several NoCs that are controlled by a remote processor that collects the aggregated bandwidth for each master-slave pairs. On a note, these chips are managing the "bus QoS" in a "hybrid" fashion: some of the paths in the topology are managed through (and by, of course) the RPM uC, while some others are "AP Owned", meaning that the AP shall do direct writes to the appropriate QoS registers for the specific paths and ports, instead of sending an indication to the RPM and leaving the job to that one. Signed-off-by: AngeloGioacchino Del Regno --- drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile| 2 + drivers/interconnect/qcom/sdm660.c| 919 ++ .../dt-bindings/interconnect/qcom,sdm660.h| 116 +++ 4 files changed, 1046 insertions(+) create mode 100644 drivers/interconnect/qcom/sdm660.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm660.h diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index a8f93ba265f8..ae76527a22f6 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -42,6 +42,15 @@ config INTERCONNECT_QCOM_QCS404 This is a driver for the Qualcomm Network-on-Chip on qcs404-based platforms. +config INTERCONNECT_QCOM_SDM660 + tristate "Qualcomm SDM660 interconnect driver" + depends on INTERCONNECT_QCOM + depends on QCOM_SMD_RPM + select INTERCONNECT_QCOM_SMD_RPM + help + This is a driver for the Qualcomm Network-on-Chip on sdm660-based + platforms. + config INTERCONNECT_QCOM_RPMH tristate diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index cf628f7990cd..ebe15d1dfe8b 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -7,6 +7,7 @@ icc-osm-l3-objs := osm-l3.o qnoc-qcs404-objs := qcs404.o icc-rpmh-obj := icc-rpmh.o qnoc-sc7180-objs := sc7180.o +qnoc-sdm660-objs := sdm660.o qnoc-sdm845-objs := sdm845.o qnoc-sm8150-objs := sm8150.o qnoc-sm8250-objs := sm8250.o @@ -19,6 +20,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o +obj-$(CONFIG_INTERCONNECT_QCOM_SDM660) += qnoc-sdm660.o obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8150) += qnoc-sm8150.o obj-$(CONFIG_INTERCONNECT_QCOM_SM8250) += qnoc-sm8250.o diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c new file mode 100644 index ..9ad709dde913 --- /dev/null +++ b/drivers/interconnect/qcom/sdm660.c @@ -0,0 +1,919 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Qualcomm SDM630/SDM636/SDM660 Network-on-Chip (NoC) QoS driver + * Copyright (C) 2020, AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smd-rpm.h" + +#define RPM_BUS_MASTER_REQ 0x73616d62 +#define RPM_BUS_SLAVE_REQ 0x766c7362 + +/* BIMC QoS */ +#define M_BKE_REG_BASE(n) (0x300 + (0x4000 * n)) +#define M_BKE_EN_ADDR(n) (M_BKE_REG_BASE(n)) +#define M_BKE_HEALTH_CFG_ADDR(i, n)(M_BKE_REG_BASE(n) + 0x40 + (0x4 * i)) + +#define M_BKE_HEALTH_CFG_LIMITCMDS_MASK0x8000 +#define M_BKE_HEALTH_CFG_AREQPRIO_MASK 0x300 +#define M_BKE_HEALTH_CFG_REG_MASK(n) ((n == 3) ? 0x303 : 0x8303) +#define M_BKE_HEALTH_CFG_PRIOLVL_MASK 0x3 +#define M_BKE_HEALTH_CFG_AREQPRIO_SHIFT0x8 +#define M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT 0x1f + +#define M_BKE_HEALTH_CFG_ALL_MASK (M_BKE_HEALTH_CFG_LIMITCMDS_MASK | \ +M_BKE_HEALTH_CFG_AREQPRIO_MASK | \ +M_BKE_HEALTH_CFG_PRIOLVL_MASK) + +#define M_BKE_EN_EN_BMASK 0x1 + +/* Valid for both NoC and BIMC */ +#define NOC_QOS_MODE_FIXED 0x0 +#define NOC_QOS_MODE_LIMITER 0x1 +#define NOC_QOS_MODE_BYPASS0x2 + +/* NoC QoS */ +#define NOC_PERM_MODE_FIXED1 +#define NOC_PERM_MODE_BYPASS (1 << NOC_QOS_MODE_BYPASS) + +#define NOC_QOS_PRIORITYn_ADDR(n) (0x8 + (n * 0x1000)) +#define NOC_QOS_PRIORITY_MASK 0xf +#define NOC_QOS_PRIORITY_P1_SHIFT 0x2 +#define NOC_QOS_PRIORITY_P0_SHIFT 0x3 + +#define NOC_QOS_MODEn_ADDR(n) (0xC + (n * 0x1000)) +#define NOC_QOS_MODEn_MASK 0x3 + +enum { + SDM660_MASTER_IPA = 1, +
[PATCH v2 1/3] dt-bindings: Add vendor prefix for Novatek Microelectronics Corp.
From: AngeloGioacchino Del Regno Add prefix for Novatek Microelectronics Corp. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 66e45112a8d7..f98ea0af487d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -740,6 +740,8 @@ patternProperties: description: Nokia "^nordic,.*": description: Nordic Semiconductor + "^novatek,.*": +description: Novatek Microelectronics Corp. "^novtech,.*": description: NovTech, Inc. "^nutsboard,.*": -- 2.28.0
[PATCH v2 2/3] Input: Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This is a driver for the Novatek in-cell touch controller and supports various chips from the NT36xxx family, currently including NT36525, NT36672A, NT36676F, NT36772 and NT36870. Functionality like wake gestures and firmware flashing is not included: I am not aware of any of these DrIC+Touch combo chips not including a non-volatile memory and it should be highly unlikely to find one, since the touch firmware is embedded into the DriverIC one, which is obviously necessary to drive the display unit. However, the necessary address for the firmware update procedure was included into the address table in this driver so, in the event that someone finds the need to implement it for a reason or another, it will be pretty straightforward to. This driver is lightly based on the downstream implementation [1]. [1] https://github.com/Rasenkai/caf-tsoft-Novatek-nt36xxx Signed-off-by: AngeloGioacchino Del Regno --- drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/nt36xxx.c | 742 drivers/input/touchscreen/nt36xxx.h | 122 + 4 files changed, 877 insertions(+) create mode 100644 drivers/input/touchscreen/nt36xxx.c create mode 100644 drivers/input/touchscreen/nt36xxx.h diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 35c867b2d9a7..6d118b967021 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -605,6 +605,18 @@ config TOUCHSCREEN_MTOUCH To compile this driver as a module, choose M here: the module will be called mtouch. +config TOUCHSCREEN_NT36XXX + tristate "Novatek NT36XXX In-Cell I2C touchscreen controller" + depends on I2C + help + Say Y here if you have a Novatek NT36xxx series In-Cell + touchscreen connected to your system over I2C. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nt36xxx. + config TOUCHSCREEN_IMX6UL_TSC tristate "Freescale i.MX6UL touchscreen controller" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 30d1e1b42492..424a555e03d5 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o +obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o obj-$(CONFIG_TOUCHSCREEN_HP600)+= hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX)+= jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o diff --git a/drivers/input/touchscreen/nt36xxx.c b/drivers/input/touchscreen/nt36xxx.c new file mode 100644 index ..57e189938d12 --- /dev/null +++ b/drivers/input/touchscreen/nt36xxx.c @@ -0,0 +1,742 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010 - 2017 Novatek, Inc. + * Copyright (C) 2020 AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "nt36xxx.h" + +static const struct nt36xxx_mem_map nt36xxx_memory_maps[] = { + [NT36525_IC] = { 0x11a00, 0x1, 0x12000, 0x14000, 0x14002 }, + [NT36672A_IC] = { 0x21c00, 0x2, 0x23000, 0x24000, 0x24002 }, + [NT36676F_IC] = { 0x11a00, 0x1, 0x12000, 0x14000, 0x14002 }, + [NT36772_IC] = { 0x11e00, 0x1, 0x12000, 0x14000, 0x14002 }, + [NT36870_IC] = { 0x25000, 0x2, 0x23000, 0x24000, 0x24002 }, +}; + +static const struct nt36xxx_trim_table trim_id_table[] = { + { +.id = { 0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, +.mask = { 1, 0, 0, 1, 1, 1 }, +.mapid = NT36672A_IC, + }, + { +.id = { 0x55, 0x00, 0xFF, 0x00, 0x00, 0x00 }, +.mask = { 1, 1, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0x55, 0x72, 0xFF, 0x00, 0x00, 0x00 }, +.mask = { 1, 1, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00 }, +.mask = { 1, 1, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00 }, +.mask = { 1, 1, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03 }, +.mask = { 0, 0, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, +.mask = { 0, 0, 0, 1, 1, 1 }, +.mapid = NT36772_IC, + }, + { +.id = { 0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03 }, +.mask = { 0, 0, 0, 1, 1, 1 }, +
[PATCH v2 3/3] dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver
From: AngeloGioacchino Del Regno Add binding for the Novatek NT36xxx series touchscreen driver. Signed-off-by: AngeloGioacchino Del Regno --- .../input/touchscreen/novatek,nt36xxx.yaml| 56 +++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml new file mode 100644 index ..9f350f4e6d6a --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/novatek,nt36xxx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36xxx series touchscreen controller Bindings + +maintainers: + - TBD + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: +enum: + - novatek,nt36xxx + + reg: +enum: [ 0x62 ] + + interrupts: +maxItems: 1 + + reset-gpio: +maxItems: 1 + + vdd-supply: +description: Power supply regulator for VDD pin + + vio-reg-name: +description: Power supply regulator on VDD-IO pin + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | +i2c { + #address-cells = <1>; + #size-cells = <0>; + nt36xxx@62 { +compatible = "novatek,nt36xxx"; +reg = <0x62>; +interrupt-parent = <>; +interrupts = <45 IRQ_TYPE_EDGE_RISING>; +reset-gpio = < 102 GPIO_ACTIVE_HIGH>; + }; +}; + +... -- 2.28.0
[PATCH v2 0/3] Add Novatek NT36xxx touchscreen driver
From: AngeloGioacchino Del Regno This patch series adds support for the Novatek NT36xxx Series' In-Cell touchscreen (integrated into the DriverIC). This patch series has been tested against the following devices: - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) Changes in v2: - Fixed sparse warnings from lkp kernel test robot AngeloGioacchino Del Regno (3): dt-bindings: Add vendor prefix for Novatek Microelectronics Corp. Input: Add Novatek NT36xxx touchscreen driver dt-bindings: touchscreen: Add binding for Novatek NT36xxx series driver .../input/touchscreen/novatek,nt36xxx.yaml| 56 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/nt36xxx.c | 742 ++ drivers/input/touchscreen/nt36xxx.h | 122 +++ 6 files changed, 935 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/novatek,nt36xxx.yaml create mode 100644 drivers/input/touchscreen/nt36xxx.c create mode 100644 drivers/input/touchscreen/nt36xxx.h -- 2.28.0
[RESEND] [PATCH 1/2] iio: adc: qcom-spmi-vadc: Use right ratiometric range for 8998,660,845
From: AngeloGioacchino Del Regno The ratiometric range for MSM8998, SDM630/636/660 and SDM845 is 1875mV instead of the standard 1800mV: address this by adding a new compatible "qcom,spmi-vadc-8998" and assigning the different range to the machines declaring this one. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iio/adc/qcom-spmi-vadc.c | 10 +- drivers/iio/adc/qcom-vadc-common.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index b0388f8a69f4..59a94ea7bf78 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -101,6 +101,7 @@ struct vadc_channel_prop { * @dev: pointer to struct device. * @base: base address for the ADC peripheral. * @nchannels: number of VADC channels. + * @ratio_range: ratiometric range for ref points. * @chan_props: array of VADC channel properties. * @iio_chans: array of IIO channels specification. * @are_ref_measured: are reference points measured. @@ -114,6 +115,7 @@ struct vadc_priv { struct device*dev; u16 base; unsigned int nchannels; + unsigned int ratio_range; struct vadc_channel_prop *chan_props; struct iio_chan_spec *iio_chans; bool are_ref_measured; @@ -355,7 +357,7 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc) u16 read_1, read_2; int ret; - vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; + vadc->graph[VADC_CALIB_RATIOMETRIC].dx = vadc->ratio_range; vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; prop = vadc_get_channel(vadc, VADC_REF_1250MV); @@ -885,6 +887,11 @@ static int vadc_probe(struct platform_device *pdev) if (ret) return ret; + if (of_device_is_compatible(node, "qcom,spmi-vadc-8998")) + vadc->ratio_range = VADC_RATIOMETRIC_RANGE_8998; + else + vadc->ratio_range = VADC_RATIOMETRIC_RANGE; + irq_eoc = platform_get_irq(pdev, 0); if (irq_eoc < 0) { if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) @@ -918,6 +925,7 @@ static int vadc_probe(struct platform_device *pdev) static const struct of_device_id vadc_match_table[] = { { .compatible = "qcom,spmi-vadc" }, + { .compatible = "qcom-spmi-vadc-8998" }, { } }; MODULE_DEVICE_TABLE(of, vadc_match_table); diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h index 17b2fc4d8bf2..b10d5fd59034 100644 --- a/drivers/iio/adc/qcom-vadc-common.h +++ b/drivers/iio/adc/qcom-vadc-common.h @@ -16,6 +16,7 @@ #define VADC_ABSOLUTE_RANGE_UV 625000 #define VADC_RATIOMETRIC_RANGE 1800 +#define VADC_RATIOMETRIC_RANGE_89981875 #define VADC_DEF_PRESCALING0 /* 1:1 */ #define VADC_DEF_DECIMATION0 /* 512 */ -- 2.28.0
[PATCH 2/2] dt-bindings: qcom-spmi-vadc: Document qcom,spmi-vadc-8998 compatible
From: AngeloGioacchino Del Regno This compatible is used in the qcom-spmi-vadc driver to select a variation in the ratiometric range, valid for MSM8998-style VADCs, like MSM8998 itself, SDM630, SDM636, SDM660, SDM845 and others. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 0ca992465a21..e9f0ebba5e2a 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -26,6 +26,7 @@ properties: - items: - enum: - qcom,spmi-vadc + - qcom,spmi-vadc-8998 - qcom,spmi-adc5 - qcom,spmi-adc-rev2 - qcom,spmi-adc7 -- 2.28.0
[PATCH] phy: qcom-qusb2: Add support for SDM630/660
From: Konrad Dybcio QUSB on these SoCs actually uses *almost* the same configuration that msm8996 does, so we can reuse the phy_cfg from there with just a single change (se clock scheme). Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 + drivers/phy/qualcomm/phy-qcom-qusb2.c | 7 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index ccda92859eca..97dae24752b4 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -21,6 +21,7 @@ properties: - qcom,ipq8074-qusb2-phy - qcom,msm8996-qusb2-phy - qcom,msm8998-qusb2-phy + - qcom,sdm660-qusb2-phy - items: - enum: - qcom,sc7180-qusb2-phy diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 557547dabfd5..a4d706b361b9 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -702,7 +702,8 @@ static int qusb2_phy_init(struct phy *phy) usleep_range(150, 160); /* Default is single-ended clock on msm8996 */ - qphy->has_se_clk_scheme = true; + if (!of_device_is_compatible(phy->dev.of_node, "qcom,sdm660-qusb2-phy")) + qphy->has_se_clk_scheme = true; /* * read TCSR_PHY_CLK_SCHEME register to check if single-ended * clock scheme is selected. If yes, then disable differential @@ -818,6 +819,10 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { }, { .compatible = "qcom,msm8998-qusb2-phy", .data = _phy_cfg, + }, { + .compatible = "qcom,sdm660-qusb2-phy", + /* sdm630/660 use the same config as msm8996. */ + .data = _phy_cfg, }, { /* * Deprecated. Only here to support legacy device -- 2.28.0
[PATCH 1/2] iio: adc: qcom-spmi-vadc: Use right ratiometric range for 8998,660,845
From: AngeloGioacchino Del Regno The ratiometric range for MSM8998, SDM630/636/660 and SDM845 is 1875mV instead of the standard 1800mV: address this by adding a new compatible "qcom,spmi-vadc-8998" and assigning the different range to the machines declaring this one. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iio/adc/qcom-spmi-vadc.c | 10 +- drivers/iio/adc/qcom-vadc-common.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index b0388f8a69f4..59a94ea7bf78 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -101,6 +101,7 @@ struct vadc_channel_prop { * @dev: pointer to struct device. * @base: base address for the ADC peripheral. * @nchannels: number of VADC channels. + * @ratio_range: ratiometric range for ref points. * @chan_props: array of VADC channel properties. * @iio_chans: array of IIO channels specification. * @are_ref_measured: are reference points measured. @@ -114,6 +115,7 @@ struct vadc_priv { struct device*dev; u16 base; unsigned int nchannels; + unsigned int ratio_range; struct vadc_channel_prop *chan_props; struct iio_chan_spec *iio_chans; bool are_ref_measured; @@ -355,7 +357,7 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc) u16 read_1, read_2; int ret; - vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; + vadc->graph[VADC_CALIB_RATIOMETRIC].dx = vadc->ratio_range; vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; prop = vadc_get_channel(vadc, VADC_REF_1250MV); @@ -885,6 +887,11 @@ static int vadc_probe(struct platform_device *pdev) if (ret) return ret; + if (of_device_is_compatible(node, "qcom,spmi-vadc-8998")) + vadc->ratio_range = VADC_RATIOMETRIC_RANGE_8998; + else + vadc->ratio_range = VADC_RATIOMETRIC_RANGE; + irq_eoc = platform_get_irq(pdev, 0); if (irq_eoc < 0) { if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) @@ -918,6 +925,7 @@ static int vadc_probe(struct platform_device *pdev) static const struct of_device_id vadc_match_table[] = { { .compatible = "qcom,spmi-vadc" }, + { .compatible = "qcom-spmi-vadc-8998" }, { } }; MODULE_DEVICE_TABLE(of, vadc_match_table); diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h index 17b2fc4d8bf2..b10d5fd59034 100644 --- a/drivers/iio/adc/qcom-vadc-common.h +++ b/drivers/iio/adc/qcom-vadc-common.h @@ -16,6 +16,7 @@ #define VADC_ABSOLUTE_RANGE_UV 625000 #define VADC_RATIOMETRIC_RANGE 1800 +#define VADC_RATIOMETRIC_RANGE_89981875 #define VADC_DEF_PRESCALING0 /* 1:1 */ #define VADC_DEF_DECIMATION0 /* 512 */ -- 2.28.0
[PATCH 2/2] dt-bindings: qcom-spmi-vadc: Document qcom,spmi-vadc-8998 compatible
From: AngeloGioacchino Del Regno This compatible is used in the qcom-spmi-vadc driver to select a variation in the ratiometric range, valid for MSM8998-style VADCs, like MSM8998 itself, SDM630, SDM636, SDM660, SDM845 and others. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 0ca992465a21..e9f0ebba5e2a 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -26,6 +26,7 @@ properties: - items: - enum: - qcom,spmi-vadc + - qcom,spmi-vadc-8998 - qcom,spmi-adc5 - qcom,spmi-adc-rev2 - qcom,spmi-adc7 -- 2.28.0
[PATCH] soc: qcom: rpmpd: Add SDM660 power-domains
From: Konrad Dybcio Add the shared cx/mx and sensor sub-system's cx and mx power-domains found on SDM660. Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno --- .../devicetree/bindings/power/qcom,rpmpd.yaml | 1 + drivers/soc/qcom/rpmpd.c | 33 +++ include/dt-bindings/power/qcom-rpmpd.h| 12 +++ 3 files changed, 46 insertions(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 8058955fb3b9..45ec2439ff51 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -20,6 +20,7 @@ properties: - qcom,msm8996-rpmpd - qcom,msm8998-rpmpd - qcom,qcs404-rpmpd + - qcom,sdm660-rpmpd - qcom,sc7180-rpmhpd - qcom,sdm845-rpmhpd - qcom,sm8150-rpmhpd diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index f2168e4259b2..d54a84dd83a8 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -220,11 +220,44 @@ static const struct rpmpd_desc qcs404_desc = { .max_state = RPM_SMD_LEVEL_BINNING, }; +/* sdm660 RPM Power domains */ +DEFINE_RPMPD_PAIR(sdm660, vddcx, vddcx_ao, RWCX, LEVEL, 0); +DEFINE_RPMPD_VFL(sdm660, vddcx_vfl, RWCX, 0); + +DEFINE_RPMPD_PAIR(sdm660, vddmx, vddmx_ao, RWMX, LEVEL, 0); +DEFINE_RPMPD_VFL(sdm660, vddmx_vfl, RWMX, 0); + +DEFINE_RPMPD_LEVEL(sdm660, vdd_ssccx, RWSC, 0); +DEFINE_RPMPD_VFL(sdm660, vdd_ssccx_vfl, RWSC, 0); + +DEFINE_RPMPD_LEVEL(sdm660, vdd_sscmx, RWSM, 0); +DEFINE_RPMPD_VFL(sdm660, vdd_sscmx_vfl, RWSM, 0); + +static struct rpmpd *sdm660_rpmpds[] = { + [SDM660_VDDCX] =_vddcx, + [SDM660_VDDCX_AO] = _vddcx_ao, + [SDM660_VDDCX_VFL] =_vddcx_vfl, + [SDM660_VDDMX] =_vddmx, + [SDM660_VDDMX_AO] = _vddmx_ao, + [SDM660_VDDMX_VFL] =_vddmx_vfl, + [SDM660_SSCCX] =_vdd_ssccx, + [SDM660_SSCCX_VFL] =_vdd_ssccx_vfl, + [SDM660_SSCMX] =_vdd_sscmx, + [SDM660_SSCMX_VFL] =_vdd_sscmx_vfl, +}; + +static const struct rpmpd_desc sdm660_desc = { + .rpmpds = sdm660_rpmpds, + .num_pds = ARRAY_SIZE(sdm660_rpmpds), + .max_state = RPM_SMD_LEVEL_TURBO, +}; + static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,msm8976-rpmpd", .data = _desc }, { .compatible = "qcom,msm8996-rpmpd", .data = _desc }, { .compatible = "qcom,msm8998-rpmpd", .data = _desc }, { .compatible = "qcom,qcs404-rpmpd", .data = _desc }, + { .compatible = "qcom,sdm660-rpmpd", .data = _desc }, { } }; MODULE_DEVICE_TABLE(of, rpmpd_match_table); diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 5e61eaf73bdd..2a39dc40483d 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -102,6 +102,18 @@ #define QCS404_LPIMX 5 #define QCS404_LPIMX_VFL 6 +/* SDM660 Power Domains */ +#define SDM660_VDDCX 0 +#define SDM660_VDDCX_AO1 +#define SDM660_VDDCX_VFL 2 +#define SDM660_VDDMX 3 +#define SDM660_VDDMX_AO4 +#define SDM660_VDDMX_VFL 5 +#define SDM660_SSCCX 6 +#define SDM660_SSCCX_VFL 7 +#define SDM660_SSCMX 8 +#define SDM660_SSCMX_VFL 9 + /* RPM SMD Power Domain performance levels */ #define RPM_SMD_LEVEL_RETENTION 16 #define RPM_SMD_LEVEL_RETENTION_PLUS 32 -- 2.28.0
[PATCH 3/5] clk: qcom: mmcc-sdm660: Add MDP clock source CXC to MDSS GDSC
From: AngeloGioacchino Del Regno It is required for optimal performance and to avoid MDP stalls to retain mem/periph on GDSC enablement: to achieve this, let's add the required CXC to the MDSS GDSC. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/mmcc-sdm660.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 234aca7c873b..7b1384cf8506 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2572,6 +2572,8 @@ static struct gdsc mdss_gdsc = { .pd = { .name = "mdss", }, + .cxcs = (unsigned int []){ 0x2040 }, + .cxc_count = 1, .pwrsts = PWRSTS_OFF_ON, }; -- 2.28.0
[PATCH 3/4] clk: qcom: rcg2: Stop hardcoding gfx3d pingpong parent numbers
From: AngeloGioacchino Del Regno The function clk_gfx3d_determine_rate is selecting different PLLs to manage the GFX3D clock source in a special way: this one needs to be ping-pong'ed on different PLLs to ensure stability during frequency switching (set a PLL rate, let it stabilize, switch the RCG to the new PLL) and fast frequency transitions. This technique is currently being used in the MSM8996 SoC and the function was assuming that the parents were always at a specific index in the parents list, which is TRUE, if we use this only on the MSM8996 MMCC. Unfortunately, MSM8996 is not the only SoC that needs to ping-pong the graphics RCG, so choices are: 1. Make new special ops just to hardcode *again* other indexes, creating code duplication for (imo) no reason; or 2. Generalize this function, so that it becomes usable for a range of SoCs with slightly different ping-pong configuration. In this commit, the second road was taken: define a new "special" struct clk_rcg2_gfx3d, containing the ordered list of parents to ping-pong the graphics clock on, and the "regular" rcg2 clock structure in order to generalize the clk_gfx3d_determine_rate function and make it working for other SoCs. As for the function itself it is left with the assumption that we need to ping-pong over three parents. The reasons for this are: 1. The initial model was MSM8996, which has 3 parents for the graphics clock pingpong; 2. The other example that was taken into consideration is the SDM630/636/660 SoC gpu clock controller, which is ping-ponging over two dynamic clocked and one fixed clock PLL. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/clk-rcg.h | 9 ++ drivers/clk/qcom/clk-rcg2.c | 56 - 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 86d2b8b90173..99efcc7f8d88 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -153,6 +153,15 @@ struct clk_rcg2 { #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) +struct clk_rcg2_gfx3d { + u8 div; + struct clk_rcg2 rcg; + struct clk_hw **hws; +}; + +#define to_clk_rcg2_gfx3d(_hw) \ + container_of(to_clk_rcg2(_hw), struct clk_rcg2_gfx3d, rcg) + extern const struct clk_ops clk_rcg2_ops; extern const struct clk_ops clk_rcg2_floor_ops; extern const struct clk_ops clk_edp_pixel_ops; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 357159fe85b5..cebdacc188aa 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -728,40 +728,49 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_rate_request parent_req = { }; - struct clk_hw *p2, *p8, *p9, *xo; - unsigned long p9_rate; + struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); + struct clk_hw *xo; + unsigned long request, p0_rate; int ret; + /* +* This function does ping-pong the RCG between PLLs: if we don't +* have at least one fixed PLL and two variable ones, +* then it's not going to work correctly. +*/ + if (unlikely(cgfx->hws[0] == NULL || cgfx->hws[1] == NULL || + cgfx->hws[2] == NULL)) + return -EINVAL; + xo = clk_hw_get_parent_by_index(hw, 0); if (req->rate == clk_hw_get_rate(xo)) { req->best_parent_hw = xo; return 0; } - p9 = clk_hw_get_parent_by_index(hw, 2); - p2 = clk_hw_get_parent_by_index(hw, 3); - p8 = clk_hw_get_parent_by_index(hw, 4); + request = req->rate; + if (cgfx->div > 1) + parent_req.rate = request = request * cgfx->div; - /* PLL9 is a fixed rate PLL */ - p9_rate = clk_hw_get_rate(p9); + /* This has to be a fixed rate PLL */ + p0_rate = clk_hw_get_rate(cgfx->hws[0]); - parent_req.rate = req->rate = min(req->rate, p9_rate); - if (req->rate == p9_rate) { - req->rate = req->best_parent_rate = p9_rate; - req->best_parent_hw = p9; + if (request == p0_rate) { + req->rate = req->best_parent_rate = p0_rate; + req->best_parent_hw = cgfx->hws[0]; return 0; } - if (req->best_parent_hw == p9) { + if (req->best_parent_hw == cgfx->hws[0]) { /* Are we going back to a previously used rate? */ - if (clk_hw_get_rate(p8) == req->rate) - req->best_parent_hw = p8; + if (clk_hw_get_rate(cgfx->hws[2]) == request) + req->best_parent_hw = cgfx->hws[2]; else - req->best_parent_hw = p2; - } else if (req->best_parent_hw == p8) { - req->best_parent_hw = p2; +
[PATCH 2/4] clk: qcom: gcc-sdm660: Mark GPU CFG AHB clock as critical
From: AngeloGioacchino Del Regno This clock is critical for any access to the GPU: gating it will crash the system when the GPU has been initialized (so, you cannot gate it unless you deinit the Adreno completely). So, to achieve a working state with GPU on, set the CLK_IS_CRITICAL flag to this clock. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/gcc-sdm660.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index 93ac77628bec..7b1c8d1f6388 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -1571,6 +1571,7 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_gpu_cfg_ahb_clk", .ops = _branch2_ops, + .flags = CLK_IS_CRITICAL, }, }, }; -- 2.28.0
[PATCH 1/5] clk: qcom: Add SDM660 Multimedia Clock Controller (MMCC) driver
From: Martin Botka Add a driver for the multimedia clock controller found on SDM660 based devices. This should allow most multimedia device drivers to probe and control their clocks. Signed-off-by: Martin Botka Co-Developed-by: Konrad Dybcio Signed-off-by: Konrad Dybcio Signed-off-by: AngeloGioacchino Del Regno Tested-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile|1 + drivers/clk/qcom/mmcc-sdm660.c | 2855 ++ include/dt-bindings/clock/qcom,mmcc-sdm660.h | 162 + 4 files changed, 3027 insertions(+) create mode 100644 drivers/clk/qcom/mmcc-sdm660.c create mode 100644 include/dt-bindings/clock/qcom,mmcc-sdm660.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 058327310c25..a12d37a4d729 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -357,6 +357,15 @@ config SDM_GCC_660 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_MMCC_660 + tristate "SDM660 Multimedia Clock Controller" + select SDM_GCC_660 + select QCOM_GDSC + help + Support for the multimedia clock controller on SDM660 devices. + Say Y if you want to support multimedia devices such as display, + graphics, video encode/decode, camera, etc. + config QCS_TURING_404 tristate "QCS404 Turing Clock Controller" help diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9677e769e7e9..ada4f1bbe203 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o +obj-$(CONFIG_SDM_MMCC_660) += mmcc-sdm660.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c new file mode 100644 index ..234aca7c873b --- /dev/null +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -0,0 +1,2855 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, Martin Botka + * Copyright (c) 2020, Konrad Dybcio + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_XO, + P_DSI0PLL_BYTE, + P_DSI0PLL, + P_DSI1PLL_BYTE, + P_DSI1PLL, + P_GPLL0, + P_GPLL0_DIV, + P_MMPLL0, + P_MMPLL10, + P_MMPLL3, + P_MMPLL4, + P_MMPLL5, + P_MMPLL6, + P_MMPLL7, + P_MMPLL8, + P_SLEEP_CLK, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV, +}; + +static const struct parent_map mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0, 1 }, + { P_MMPLL4, 2 }, + { P_MMPLL7, 3 }, + { P_MMPLL8, 4 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, +}; + +/* Voteable PLL */ +static struct clk_alpha_pll mmpll0 = { + .offset = 0xc000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x1f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = _alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll mmpll6 = { + .offset = 0xf0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x1f0, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "mmpll6", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = _alpha_pll_ops, + }, + }, +}; + +/* APSS controlled PLLs */ +static struct pll_vco vco[] = { + { 10, 20, 0 }, + { 75000, 15, 1 }, + { 5, 10, 2 }, + { 25000, 5, 3 }, +}; + +static struct pll_vco mmpll3_vco[] = { + { 75000, 15, 1 }, +}; + +static const struct alpha_pll_config
[PATCH 5/5] dt-bindings: clock: Add QCOM SDM630 and SDM660 graphics clock bindings
From: AngeloGioacchino Del Regno Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SDM630 and SDM660 SoCs. --- .../bindings/clock/qcom,sdm660-gpucc.yaml | 75 +++ 1 file changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sdm660-gpucc.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm660-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdm660-gpucc.yaml new file mode 100644 index ..dbb14b274d5b --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sdm660-gpucc.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sdm660-gpucc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Graphics Clock & Reset Controller Binding for SDM630 and SDM660 + +maintainers: + - Taniya Das + +description: | + Qualcomm graphics clock control module which supports the clocks, resets and + power domains on SDM630 and SDM660. + + See also dt-bindings/clock/qcom,gpucc-sdm660.h. + +properties: + compatible: +enum: + - qcom,sdm630-gpucc + - qcom,sdm660-gpucc + + clocks: +items: + - description: Board XO source + - description: GPLL0 main gpu branch + - description: GPLL0 divider gpu branch + + clock-names: +items: + - const: xo + - const: gcc_gpu_gpll0_clk + - const: gcc_gpu_gpll0_div_clk + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include + +clock-controller@5065000 { + compatible = "qcom,sdm660-gpucc"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x05065000 0x9038>; + clocks = < RPM_SMD_XO_CLK_SRC>, + < GCC_GPU_GPLL0_CLK>, + < GCC_GPU_GPLL0_DIV_CLK>; + clock-names = "xo", "gpll0"; +}; +... -- 2.28.0
[PATCH 4/5] clk: qcom: Add SDM660 GPU Clock Controller (GPUCC) driver
From: AngeloGioacchino Del Regno The GPUCC manages the clocks for the Adreno GPU found on the SDM630, SDM636, SDM660 SoCs. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm660.c | 349 ++ include/dt-bindings/clock/qcom,gpucc-sdm660.h | 28 ++ 4 files changed, 387 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm660.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm660.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a12d37a4d729..377fba33d041 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -366,6 +366,15 @@ config SDM_MMCC_660 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. +config SDM_GPUCC_660 + tristate "SDM660 Graphics Clock Controller" + select SDM_GCC_660 + select QCOM_GDSC + help + Support for the graphics clock controller on SDM630/636/660 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics + config QCS_TURING_404 tristate "QCS404 Turing Clock Controller" help diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index ada4f1bbe203..6a6906a62f96 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o obj-$(CONFIG_SDM_MMCC_660) += mmcc-sdm660.o +obj-$(CONFIG_SDM_GPUCC_660) += gpucc-sdm660.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o diff --git a/drivers/clk/qcom/gpucc-sdm660.c b/drivers/clk/qcom/gpucc-sdm660.c new file mode 100644 index ..447a34aaa21f --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm660.c @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-alpha-pll.h" +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_GPU_XO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_PLL0_PLL_OUT_MAIN, + P_GPU_PLL1_PLL_OUT_MAIN, +}; + +static struct clk_branch gpucc_cxo_clk = { + .halt_reg = 0x1020, + .clkr = { + .enable_reg = 0x1020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpucc_cxo_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = _branch2_ops, + .flags = CLK_IS_CRITICAL, + }, + }, +}; + +static struct pll_vco gpu_vco[] = { + { 10, 20, 0 }, + { 5, 10, 2 }, + { 25000, 5, 3 }, +}; + +static struct clk_alpha_pll gpu_pll0_pll_out_main = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .vco_table = gpu_vco, + .num_vco = ARRAY_SIZE(gpu_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_pll0_pll_out_main", + .parent_data = &(const struct clk_parent_data){ + .hw = _cxo_clk.clkr.hw, + }, + .num_parents = 1, + .ops = _alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll gpu_pll1_pll_out_main = { + .offset = 0x40, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .vco_table = gpu_vco, + .num_vco = ARRAY_SIZE(gpu_vco), + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_pll1_pll_out_main", + .parent_data = &(const struct clk_parent_data){ + .hw = _cxo_clk.clkr.hw, + }, + .num_parents = 1, + .ops = _alpha_pll_ops, + }, +}; + +static const struct parent_map gpucc_parent_map_1[] = { + { P_GPU_XO, 0 }, + { P_GPU_PLL0_PLL_OUT_MAIN, 1 }, + { P_GPU_PLL1_PLL_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gpucc_parent_data_1[] = { + { .hw = _cxo_clk.clkr.hw }, + { .hw = _pll0_pll_out_main.clkr.hw }, + { .hw =
[PATCH 2/5] dt-bindings: clock: Add support for the SDM630 and SDM660 mmcc
From: AngeloGioacchino Del Regno Document the multimedia clock controller found on SDM630/660. Signed-off-by: AngeloGioacchino Del Regno --- Documentation/devicetree/bindings/clock/qcom,mmcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml index af32dee14fc6..8b0b1c56f354 100644 --- a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml @@ -24,6 +24,8 @@ properties: - qcom,mmcc-msm8974 - qcom,mmcc-msm8996 - qcom,mmcc-msm8998 + - qcom,mmcc-sdm630 + - qcom,mmcc-sdm660 clocks: items: -- 2.28.0
[PATCH 0/5] SDM630/660 Multimedia and GPU clock controllers
From: AngeloGioacchino Del Regno This patch series brings up the MultiMedia Clock Controller (MMCC) and the GPU Clock Controller (GPUCC) on the SDM660 series of SoCs, including SDM630, SDM636, SDM660 and SDA variants, where applicable. This series depends on "Qualcomm clock fixes and preparation for SDM660", which is required for the drivers to work correctly and to even compile (due to the gfx3d rcg2 changes). This patch series has been tested against the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) AngeloGioacchino Del Regno (4): dt-bindings: clock: Add support for the SDM630 and SDM660 mmcc clk: qcom: mmcc-sdm660: Add MDP clock source CXC to MDSS GDSC clk: qcom: Add SDM660 GPU Clock Controller (GPUCC) driver dt-bindings: clock: Add QCOM SDM630 and SDM660 graphics clock bindings Martin Botka (1): clk: qcom: Add SDM660 Multimedia Clock Controller (MMCC) driver .../devicetree/bindings/clock/qcom,mmcc.yaml |2 + .../bindings/clock/qcom,sdm660-gpucc.yaml | 75 + drivers/clk/qcom/Kconfig | 18 + drivers/clk/qcom/Makefile |2 + drivers/clk/qcom/gpucc-sdm660.c | 349 ++ drivers/clk/qcom/mmcc-sdm660.c| 2857 + include/dt-bindings/clock/qcom,gpucc-sdm660.h | 28 + include/dt-bindings/clock/qcom,mmcc-sdm660.h | 162 + 8 files changed, 3493 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sdm660-gpucc.yaml create mode 100644 drivers/clk/qcom/gpucc-sdm660.c create mode 100644 drivers/clk/qcom/mmcc-sdm660.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm660.h create mode 100644 include/dt-bindings/clock/qcom,mmcc-sdm660.h -- 2.28.0
[PATCH 4/4] clk: qcom: mmcc-msm8996: Migrate gfx3d clock to clk_rcg2_gfx3d
From: AngeloGioacchino Del Regno In commit 8c5dc88b064d the gfx3d ping-pong ops (clk_gfx3d_ops) were generalized in order to be able to reuse the same ops for more than just one clock for one SoC: follow the change here in the MSM8996 MMCC. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/mmcc-msm8996.c | 29 ++--- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 3b3aac07fb2d..24843e4f2599 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -528,16 +528,23 @@ static struct clk_rcg2 maxi_clk_src = { }, }; -static struct clk_rcg2 gfx3d_clk_src = { - .cmd_rcgr = 0x4000, - .hid_width = 5, - .parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gfx3d_clk_src", - .parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0, - .num_parents = 6, - .ops = _gfx3d_ops, - .flags = CLK_SET_RATE_PARENT, +static struct clk_rcg2_gfx3d gfx3d_clk_src = { + .rcg = { + .cmd_rcgr = 0x4000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0, + .num_parents = 6, + .ops = _gfx3d_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, + .hws = (struct clk_hw*[]) { + , + , + }, }; @@ -3089,7 +3096,7 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = { [AHB_CLK_SRC] = _clk_src.clkr, [AXI_CLK_SRC] = _clk_src.clkr, [MAXI_CLK_SRC] = _clk_src.clkr, - [GFX3D_CLK_SRC] = _clk_src.clkr, + [GFX3D_CLK_SRC] = _clk_src.rcg.clkr, [RBBMTIMER_CLK_SRC] = _clk_src.clkr, [ISENSE_CLK_SRC] = _clk_src.clkr, [RBCPR_CLK_SRC] = _clk_src.clkr, -- 2.28.0
[PATCH 0/4] Qualcomm clock fixes and preparation for SDM660
From: AngeloGioacchino Del Regno This patch series includes two fixes for the SDM660 GCC, and a change in the rcg2 gfx3d ops, which are essential for a later series that will add the MMCC and GPUCC for this SoC. The change in rcg2 gfx3d is only about generalizing the functions in order to reuse them for more than just one MMCC for one SoC and brings no functional changes on MSM8996. For more informations, look at the commit description for patch 3/4. This patch series has been tested against the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) AngeloGioacchino Del Regno (4): clk: qcom: gcc-sdm660: Mark MMSS NoC CFG AHB clock as critical clk: qcom: gcc-sdm660: Mark GPU CFG AHB clock as critical clk: qcom: rcg2: Stop hardcoding gfx3d pingpong parent numbers clk: qcom: mmcc-msm8996: Migrate gfx3d clock to clk_rcg2_gfx3d drivers/clk/qcom/clk-rcg.h | 9 ++ drivers/clk/qcom/clk-rcg2.c | 56 + drivers/clk/qcom/gcc-sdm660.c | 7 + drivers/clk/qcom/mmcc-msm8996.c | 29 ++--- 4 files changed, 70 insertions(+), 31 deletions(-) -- 2.28.0
[PATCH 1/4] clk: qcom: gcc-sdm660: Mark MMSS NoC CFG AHB clock as critical
From: AngeloGioacchino Del Regno Similarly to MSM8998, any access to the MMSS depends on this clock. Gating it will crash the system when RPMCC inits mmssnoc_axi_rpm_clk. Signed-off-by: AngeloGioacchino Del Regno --- drivers/clk/qcom/gcc-sdm660.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index f0b47b7d50ca..93ac77628bec 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -1684,6 +1684,12 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_mmss_noc_cfg_ahb_clk", .ops = _branch2_ops, + /* +* Any access to mmss depends on this clock. +* Gating this clock has been shown to crash the system +* when mmssnoc_axi_rpm_clk is inited in rpmcc. +*/ + .flags = CLK_IS_CRITICAL, }, }, }; -- 2.28.0
[PATCH 6/8] iommu/arm-smmu: Move stream mapping reset to separate function
From: AngeloGioacchino Del Regno Move the stream mapping reset logic from arm_smmu_device_reset into a separate arm_smmu_stream_mapping_reset function, in preparation for implementing an implementation detail. This commit brings no functional changes. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 446a78dde9cd..8c070c493315 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1652,14 +1652,9 @@ static struct iommu_ops arm_smmu_ops = { .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; -static void arm_smmu_device_reset(struct arm_smmu_device *smmu) +static void arm_smmu_stream_mapping_reset(struct arm_smmu_device *smmu) { int i; - u32 reg; - - /* clear global FSR */ - reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR); - arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, reg); /* * Reset stream mapping groups: Initial values mark all SMRn as @@ -1673,6 +1668,18 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) arm_smmu_write_context_bank(smmu, i); arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT); } +} + +static void arm_smmu_device_reset(struct arm_smmu_device *smmu) +{ + u32 reg; + + /* clear global FSR */ + reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR); + arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, reg); + + /* Reset stream mapping */ + arm_smmu_stream_mapping_reset(smmu); /* Invalidate the TLB, just in case */ arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIALLH, QCOM_DUMMY_VAL); -- 2.28.0
[PATCH 5/8] iommu/arm-smmu-qcom: Add test_smr_masks detail to QCOM SMMUv2
From: AngeloGioacchino Del Regno On some Qualcomm SoCs with certain hypervisor configurations, writing the streamid masks to the SMRs will trigger a hyp-fault and crash the system. This is seen on at least Qualcomm SDM630, SDM636 and SDM660. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index f5bbfe86ef30..b18e70bddf29 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -85,8 +85,21 @@ static int qcom_smmuv2_cfg_probe(struct arm_smmu_device *smmu) return 0; } +static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu) +{ + /* +* Broken firmware quirk: +* On some Qualcomm SoCs with certain hypervisor configurations, +* writing the streamid masks to the SMRs will trigger a hyp-fault +* and crash the system. +*/ + smmu->streamid_mask = 0x7FFF; + smmu->smr_mask_mask = 0x7FFF; +} + static const struct arm_smmu_impl qcom_smmuv2_impl = { .cfg_probe = qcom_smmuv2_cfg_probe, + .test_smr_masks = qcom_smmuv2_test_smr_masks, }; struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) -- 2.28.0
[PATCH 4/8] iommu/arm-smmu: Support test_smr_masks implementation detail deviation
From: AngeloGioacchino Del Regno At least some Qualcomm SoCs do need to override the function arm_smmu_test_smr_masks entirely: add a test_smr_masks function to the implementation details structure and call it properly. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 ++ drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 09c42af9f31e..446a78dde9cd 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -977,6 +977,12 @@ static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu) if (!smmu->smrs) return; + + if (smmu->impl && smmu->impl->test_smr_masks) { + smmu->impl->test_smr_masks(smmu); + return; + } + /* * If we've had to accommodate firmware memory regions, we may * have live SMRs by now; tread carefully... diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index d890a4a968e8..2cd3d126f675 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -387,6 +387,7 @@ struct arm_smmu_impl { int (*cfg_probe)(struct arm_smmu_device *smmu); int (*reset)(struct arm_smmu_device *smmu); int (*init_context)(struct arm_smmu_domain *smmu_domain); + void (*test_smr_masks)(struct arm_smmu_device *smmu); void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync, int status); int (*def_domain_type)(struct device *dev); -- 2.28.0
[PATCH 0/8] Implement firmware quirks for Qualcomm ARM-SMMUv2
From: AngeloGioacchino Del Regno In this patch series, I'm implementing some quirks for firmware issues happening on various Qualcomm SoCs, including SDM630, SDM636, SDM660, their SDA variants and, most probably, other MSM/APQs. In the specific case of the 630/660 family of SoCs, failing to apply all of these quirks means complete havoc when enabling the IOMMUs, as the firmware that is running on (almost?) all of the commercial boards (smartphones) is set to give us a "nice" hypervisor fault, resulting in either a system hang or a reboot. The actual implementation of these quirks in downstream kernels is done through reading some DT property and varying code paths, while here it's done through the implementation details for ARM-SMMU instead. In short, the quirks that are proposed in this patch series are the ones relative to the following downstream properties: - qcom,use-3-lvl-tables (39-bit VA size) - qcom,skip-init(avoid stream mapping reset for secure CBs) - qcom,no-smr-check (manually set correct streamid/smr masks) This patch series has been tested on the following devices: - Sony Xperia XA2 Ultra (SDM630 Nile Discovery) - Sony Xperia 10(SDM630 Ganges Kirin) - Sony Xperia 10 Plus (SDM636 Ganges Mermaid) AngeloGioacchino Del Regno (8): iommu/arm-smmu-qcom: Rename qcom_smmu_impl to qcom_smmu500_impl iommu/arm-smmu-qcom: Add QC SMMUv2 VA Size quirk for SDM660 dt-bindings: arm-smmu: add binding for SMMUv2 on Qualcomm SDM660 iommu/arm-smmu: Support test_smr_masks implementation detail deviation iommu/arm-smmu-qcom: Add test_smr_masks detail to QCOM SMMUv2 iommu/arm-smmu: Move stream mapping reset to separate function iommu/arm-smmu: Support stream_mapping_reset implementation detail iommu/arm-smmu-qcom: Add stream_mapping_reset detail to QCOM SMMUv2 .../devicetree/bindings/iommu/arm,smmu.yaml | 1 + drivers/iommu/arm/arm-smmu/arm-smmu-impl.c| 3 +- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c| 59 ++- drivers/iommu/arm/arm-smmu/arm-smmu.c | 28 +++-- drivers/iommu/arm/arm-smmu/arm-smmu.h | 2 + 5 files changed, 85 insertions(+), 8 deletions(-) -- 2.28.0
[PATCH 1/8] iommu/arm-smmu-qcom: Rename qcom_smmu_impl to qcom_smmu500_impl
From: AngeloGioacchino Del Regno Rename qcom_smmu_impl to qcom_smmu500_impl, as it refers only to the MMU-500 in Qualcomm SoCs, in preparation for adding implementation details for ones having SMMUv2. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index be4318044f96..7859fd0db22a 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -60,7 +60,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu) return 0; } -static const struct arm_smmu_impl qcom_smmu_impl = { +static const struct arm_smmu_impl qcom_smmu500_impl = { .def_domain_type = qcom_smmu_def_domain_type, .reset = qcom_smmu500_reset, }; @@ -75,7 +75,7 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) qsmmu->smmu = *smmu; - qsmmu->smmu.impl = _smmu_impl; + qsmmu->smmu.impl = _smmu500_impl; devm_kfree(smmu->dev, smmu); return >smmu; -- 2.28.0
[PATCH 8/8] iommu/arm-smmu-qcom: Add stream_mapping_reset detail to QCOM SMMUv2
From: AngeloGioacchino Del Regno On some Qualcomm SoCs with certain hypervisor configurations, some context banks are hyp-protected and cannot be disabled, nor the relative S2CRs can be set as bypass, or a hyp-fault will be triggered and the system will hang. This is seen on at least Qualcomm SDM630, SDM636 and SDM660. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index b18e70bddf29..364908cc2adf 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -85,6 +85,18 @@ static int qcom_smmuv2_cfg_probe(struct arm_smmu_device *smmu) return 0; } +static void qcom_smmuv2_stream_mapping_reset(struct arm_smmu_device *smmu) +{ + /* +* Broken firmware quirk: +* On some Qualcomm SoCs with certain hypervisor configurations, +* some context banks are hyp-protected and cannot be disabled, +* nor the relative S2CRs can be set as bypass, or a hyp-fault +* will be triggered and the system will hang. +*/ + return; +} + static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu) { /* @@ -99,6 +111,7 @@ static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu) static const struct arm_smmu_impl qcom_smmuv2_impl = { .cfg_probe = qcom_smmuv2_cfg_probe, + .stream_mapping_reset = qcom_smmuv2_stream_mapping_reset, .test_smr_masks = qcom_smmuv2_test_smr_masks, }; -- 2.28.0
[PATCH 7/8] iommu/arm-smmu: Support stream_mapping_reset implementation detail
From: AngeloGioacchino Del Regno Some IOMMUs may be in need of overriding the stream mapping reset function and this is seen on at least some Qualcomm SoCs: add a stream_mapping_reset function to the implementation details and call it in the appropriate function. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 + drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 8c070c493315..44571873f148 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1656,6 +1656,11 @@ static void arm_smmu_stream_mapping_reset(struct arm_smmu_device *smmu) { int i; + if (smmu->impl && smmu->impl->stream_mapping_reset) { + smmu->impl->stream_mapping_reset(smmu); + return; + } + /* * Reset stream mapping groups: Initial values mark all SMRn as * invalid and all S2CRn as bypass unless overridden. diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index 2cd3d126f675..9c045594b8cf 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -387,6 +387,7 @@ struct arm_smmu_impl { int (*cfg_probe)(struct arm_smmu_device *smmu); int (*reset)(struct arm_smmu_device *smmu); int (*init_context)(struct arm_smmu_domain *smmu_domain); + void (*stream_mapping_reset)(struct arm_smmu_device *smmu); void (*test_smr_masks)(struct arm_smmu_device *smmu); void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync, int status); -- 2.28.0
[PATCH 2/8] iommu/arm-smmu-qcom: Add QC SMMUv2 VA Size quirk for SDM660
From: AngeloGioacchino Del Regno Some IOMMUs are getting set-up for Shared Virtual Address, but: 1. They are secured by the Hypervisor, so any configuration change will generate a hyp-fault and crash the system 2. This 39-bits Virtual Address size deviates from the ARM System MMU Architecture specification for SMMUv2, hence it is non-standard. In this case, the only way to keep the IOMMU as the firmware did configure it, is to hardcode a maximum VA size of 39 bits (because of point 1). This gives the need to add implementation details bits for at least some of the SoCs having this kind of configuration, which are at least SDM630, SDM636 and SDM660. These implementation details will be enabled on finding the qcom,sdm660-smmu-v2 compatible. Signed-off-by: AngeloGioacchino Del Regno --- drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 3 ++- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 31 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c index f4ff124a1967..9d753f8af2cc 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c @@ -216,7 +216,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu) if (of_device_is_compatible(np, "nvidia,tegra194-smmu")) return nvidia_smmu_impl_init(smmu); - if (of_device_is_compatible(np, "qcom,sdm845-smmu-500") || + if (of_device_is_compatible(np, "qcom,sdm660-smmu-v2") || + of_device_is_compatible(np, "qcom,sdm845-smmu-500") || of_device_is_compatible(np, "qcom,sc7180-smmu-500") || of_device_is_compatible(np, "qcom,sm8150-smmu-500") || of_device_is_compatible(np, "qcom,sm8250-smmu-500")) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 7859fd0db22a..f5bbfe86ef30 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -65,8 +65,33 @@ static const struct arm_smmu_impl qcom_smmu500_impl = { .reset = qcom_smmu500_reset, }; +static int qcom_smmuv2_cfg_probe(struct arm_smmu_device *smmu) +{ + /* +* Some IOMMUs are getting set-up for Shared Virtual Address, but: +* 1. They are secured by the Hypervisor, so any configuration +*change will generate a hyp-fault and crash the system +* 2. This 39-bits Virtual Address size deviates from the ARM +*System MMU Architecture specification for SMMUv2, hence +*it is non-standard. In this case, the only way to keep the +*IOMMU as the firmware did configure it, is to hardcode a +*maximum VA size of 39 bits (because of point 1). +*/ + if (smmu->va_size > 39UL) + dev_notice(smmu->dev, + "\tenabling workaround for QCOM SMMUv2 VA size\n"); + smmu->va_size = min(smmu->va_size, 39UL); + + return 0; +} + +static const struct arm_smmu_impl qcom_smmuv2_impl = { + .cfg_probe = qcom_smmuv2_cfg_probe, +}; + struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) { + const struct device_node *np = smmu->dev->of_node; struct qcom_smmu *qsmmu; qsmmu = devm_kzalloc(smmu->dev, sizeof(*qsmmu), GFP_KERNEL); @@ -75,7 +100,11 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) qsmmu->smmu = *smmu; - qsmmu->smmu.impl = _smmu500_impl; + if (of_device_is_compatible(np, "qcom,sdm660-smmu-v2")) { + qsmmu->smmu.impl = _smmuv2_impl; + } else { + qsmmu->smmu.impl = _smmu500_impl; + } devm_kfree(smmu->dev, smmu); return >smmu; -- 2.28.0