From 9b32f8951f0f3f8e07c0682d853f5aaf77603aef Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 9 Jul 2018 14:37:50 +0530 Subject: dt-bindings: mipi-dsi: Add info about peripherals with non-DSI control bus Add a section that describes dt-bindings for peripherals that support MIPI DSI, but have a different bus as the primary control bus, or no control bus at all. Add an example for a peripheral with a non-DSI control bus. Reviewed-by: Rob Herring Reviewed-by: Boris Brezillon Reviewed-by: Philippe Cornu Reviewed-by: Sean Paul Signed-off-by: Archit Taneja Link: https://patchwork.freedesktop.org/patch/msgid/20180709090751.10221-2-architt@codeaurora.org --- .../devicetree/bindings/display/mipi-dsi-bus.txt | 71 +++++++++++++++++++--- 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index 973c27273772..b7c5bf47403c 100644 --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt @@ -16,7 +16,7 @@ The following assumes that only a single peripheral is connected to a DSI host. Experience shows that this is true for the large majority of setups. DSI host --------- +======== In addition to the standard properties and those defined by the parent bus of a DSI host, the following properties apply to a node representing a DSI host. @@ -30,11 +30,16 @@ Required properties: different value here. See below. DSI peripheral --------------- +============== -Peripherals are represented as child nodes of the DSI host's node. Properties -described here apply to all DSI peripherals, but individual bindings may want -to define additional, device-specific properties. +Peripherals with DSI as control bus, or no control bus +------------------------------------------------------ + +Peripherals with the DSI bus as the primary control bus, or peripherals with +no control bus but use the DSI bus to transmit pixel data are represented +as child nodes of the DSI host's node. Properties described here apply to all +DSI peripherals, but individual bindings may want to define additional, +device-specific properties. Required properties: - reg: The virtual channel number of a DSI peripheral. Must be in the range @@ -49,9 +54,25 @@ case two alternative representations can be chosen: property is the number of the first virtual channel and the second cell is the number of consecutive virtual channels. -Example -------- +Peripherals with a different control bus +---------------------------------------- + +There are peripherals that have I2C/SPI (or some other non-DSI bus) as the +primary control bus, but are also connected to a DSI bus (mostly for the data +path). Connections between such peripherals and a DSI host can be represented +using the graph bindings [1], [2]. + +[1] Documentation/devicetree/bindings/graph.txt +[2] Documentation/devicetree/bindings/media/video-interfaces.txt +Examples +======== +- (1), (2) and (3) are examples of a DSI host and peripheral on the DSI bus + with different virtual channel configurations. +- (4) is an example of a peripheral on a I2C control bus connected to a + DSI host using of-graph bindings. + +1) dsi-host { ... @@ -67,6 +88,7 @@ Example ... }; +2) dsi-host { ... @@ -82,6 +104,7 @@ Example ... }; +3) dsi-host { ... @@ -96,3 +119,37 @@ Example ... }; + +4) + i2c-host { + ... + + dsi-bridge@35 { + compatible = "..."; + reg = <0x35>; + + ports { + ... + + port { + bridge_mipi_in: endpoint { + remote-endpoint = <&host_mipi_out>; + }; + }; + }; + }; + }; + + dsi-host { + ... + + ports { + ... + + port { + host_mipi_out: endpoint { + remote-endpoint = <&bridge_mipi_in>; + }; + }; + }; + }; -- cgit v1.2.3 From 5e03f02cb58d1cee5d98f323da9abe2e7073b2b4 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 9 Jul 2018 14:37:51 +0530 Subject: dt-bindings: mipi-dsi: Add dual-channel DSI related info Add binding info for peripherals that support dual-channel DSI. Add corresponding optional bindings for DSI host controllers that may be configured in this mode. Add an example of an I2C controlled device operating in dual-channel DSI mode. Reviewed-by: Rob Herring Reviewed-by: Philippe Cornu Reviewed-by: Sean Paul Reviewed-by: Heiko Stuebner Signed-off-by: Archit Taneja Link: https://patchwork.freedesktop.org/patch/msgid/20180709090751.10221-3-architt@codeaurora.org --- .../devicetree/bindings/display/mipi-dsi-bus.txt | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index b7c5bf47403c..a336599f6c03 100644 --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt @@ -29,6 +29,13 @@ Required properties: - #size-cells: Should be 0. There are cases where it makes sense to use a different value here. See below. +Optional properties: +- clock-master: boolean. Should be enabled if the host is being used in + conjunction with another DSI host to drive the same peripheral. Hardware + supporting such a configuration generally requires the data on both the busses + to be driven by the same clock. Only the DSI host instance controlling this + clock should contain this property. + DSI peripheral ============== @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data path). Connections between such peripherals and a DSI host can be represented using the graph bindings [1], [2]. +Peripherals that support dual channel DSI +----------------------------------------- + +Peripherals with higher bandwidth requirements can be connected to 2 DSI +busses. Each DSI bus/channel drives some portion of the pixel data (generally +left/right half of each line of the display, or even/odd lines of the display). +The graph bindings should be used to represent the multiple DSI busses that are +connected to this peripheral. Each DSI host's output endpoint can be linked to +an input endpoint of the DSI peripheral. + [1] Documentation/devicetree/bindings/graph.txt [2] Documentation/devicetree/bindings/media/video-interfaces.txt @@ -71,6 +88,8 @@ Examples with different virtual channel configurations. - (4) is an example of a peripheral on a I2C control bus connected to a DSI host using of-graph bindings. +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral, + which uses I2C as its primary control bus. 1) dsi-host { @@ -153,3 +172,64 @@ Examples }; }; }; + +5) + i2c-host { + dsi-bridge@35 { + compatible = "..."; + reg = <0x35>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi0_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + dsi1_in: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + }; + }; + }; + + dsi0-host { + ... + + /* + * this DSI instance drives the clock for both the host + * controllers + */ + clock-master; + + ports { + ... + + port { + dsi0_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + }; + }; + + dsi1-host { + ... + + ports { + ... + + port { + dsi1_out: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + }; -- cgit v1.2.3 From e3896e6dddf0b821dc3214b623a922aa7ee2c2d5 Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Mon, 16 Jul 2018 14:13:30 +0530 Subject: dt-bindings: drm/bridge: Document sn65dsi86 bridge bindings Document the bindings used for the sn65dsi86 DSI to eDP bridge. Changes in v1: - Rephrase the dt-binding descriptions to be more inline with existing bindings (Andrzej Hajda). - Add missing dt-binding that are parsed by corresponding driver (Andrzej Hajda). Changes in v2: - Remove edp panel specific dt-binding entries. Only keep bridge specific entries (Sean Paul). - Remove custom-modes dt entry since its usage is removed from driver also (Sean Paul). - Remove is-pluggable dt entry since this will not be needed anymore (Sean Paul). Changes in v3: - Remove irq-gpio dt entry and instead populate is an interrupt property (Rob Herring). Changes in v4: - Add link to bridge chip datasheet (Stephen Boyd) - Add vpll and vcc regulator supply bindings (Stephen Boyd) - Add ref clk optional dt binding (Stephen Boyd) - Add gpio-controller optional dt binding (Stephen Boyd) Changes in v5: - Use clock property to specify the input refclk (Stephen Boyd). - Update gpio cell and pwm cell numbers (Stephen Boyd). Changes in v6: - Add property to mention the lane mapping scheme and polarity inversion (Stephen Boyd). Changes in v7: - Detail description of lane mapping scheme dt property (Andrzej Hajda/ Rob Herring). - Removed HDP gpio binding, since the bridge uses IRQ signal to determine HPD, and IRQ property is already documented in binding. Changes in v8: - Removed unnecessary explanation of lane mapping and polarity dt property, since these are already explained in media/video-interface dt binidng (Rob Herring). Changes in v9: - Avoid putting re-definition of lane mapping and polarity dt binding (Rob Herring). Changes in v10: - Use interrupts-extended property instead of interrupts to specify interrupt line (Andrzej Hajda). - Move data-lanes and lane-polarity property example to proper place (Andrzej Hajda). Changes in v11: - Add a property for suspend gpio function of GPIO1 pin on bridge chip (Stephen Boyd). Changes in v12: - Remove binding for dedicated DDC line (Andrzej Hajda). Signed-off-by: Sandeep Panda Reviewed-by: Stephen Boyd Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20180716084330.26698-3-spanda@codeaurora.org --- .../bindings/display/bridge/ti,sn65dsi86.txt | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.txt b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.txt new file mode 100644 index 000000000000..0a3fbb53a16e --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.txt @@ -0,0 +1,87 @@ +SN65DSI86 DSI to eDP bridge chip +-------------------------------- + +This is the binding for Texas Instruments SN65DSI86 bridge. +http://www.ti.com/general/docs/lit/getliterature.tsp?genericPartNumber=sn65dsi86&fileType=pdf + +Required properties: +- compatible: Must be "ti,sn65dsi86" +- reg: i2c address of the chip, 0x2d as per datasheet +- enable-gpios: gpio specification for bridge_en pin (active high) + +- vccio-supply: A 1.8V supply that powers up the digital IOs. +- vpll-supply: A 1.8V supply that powers up the displayport PLL. +- vcca-supply: A 1.2V supply that powers up the analog circuits. +- vcc-supply: A 1.2V supply that powers up the digital core. + +Optional properties: +- interrupts-extended: Specifier for the SN65DSI86 interrupt line. + +- gpio-controller: Marks the device has a GPIO controller. +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify flags. + See ../../gpio/gpio.txt for more information. +- #pwm-cells : Should be one. See ../../pwm/pwm.txt for description of + the cell formats. + +- clock-names: should be "refclk" +- clocks: Specification for input reference clock. The reference + clock rate must be 12 MHz, 19.2 MHz, 26 MHz, 27 MHz or 38.4 MHz. + +- data-lanes: See ../../media/video-interface.txt +- lane-polarities: See ../../media/video-interface.txt + +- suspend-gpios: specification for GPIO1 pin on bridge (active low) + +Required nodes: +This device has two video ports. Their connections are modelled using the +OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. + +- Video port 0 for DSI input +- Video port 1 for eDP output + +Example +------- + +edp-bridge@2d { + compatible = "ti,sn65dsi86"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2d>; + + enable-gpios = <&msmgpio 33 GPIO_ACTIVE_HIGH>; + suspend-gpios = <&msmgpio 34 GPIO_ACTIVE_LOW>; + + interrupts-extended = <&gpio3 4 IRQ_TYPE_EDGE_FALLING>; + + vccio-supply = <&pm8916_l17>; + vcca-supply = <&pm8916_l6>; + vpll-supply = <&pm8916_l17>; + vcc-supply = <&pm8916_l6>; + + clock-names = "refclk"; + clocks = <&input_refclk>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + edp_bridge_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + + port@1 { + reg = <1>; + + edp_bridge_out: endpoint { + data-lanes = <2 1 3 0>; + lane-polarities = <0 1 0 1>; + remote-endpoint = <&edp_panel_in>; + }; + }; + }; +} -- cgit v1.2.3 From eb91cde094f523c06adf463aad0e41ae35765d71 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Wed, 25 Jul 2018 17:46:39 +0200 Subject: dt-bindings: tc358754: add DT bindings The patch adds bindings to Toshiba DSI/LVDS bridge TC358764. Bindings describe power supplies, reset gpio and video interfaces. Signed-off-by: Andrzej Hajda Signed-off-by: Maciej Purski Reviewed-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20180725154644.25412-5-a.hajda@samsung.com --- .../bindings/display/bridge/toshiba,tc358764.txt | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new file mode 100644 index 000000000000..8f9abf28a8fa --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt @@ -0,0 +1,35 @@ +TC358764 MIPI-DSI to LVDS panel bridge + +Required properties: + - compatible: "toshiba,tc358764" + - reg: the virtual channel number of a DSI peripheral + - vddc-supply: core voltage supply, 1.2V + - vddio-supply: I/O voltage supply, 1.8V or 3.3V + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V + - reset-gpios: a GPIO spec for the reset pin + +The device node can contain following 'port' child nodes, +according to the OF graph bindings defined in [1]: + 0: DSI Input, not required, if the bridge is DSI controlled + 1: LVDS Output, mandatory + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + bridge@0 { + reg = <0>; + compatible = "toshiba,tc358764"; + vddc-supply = <&vcc_1v2_reg>; + vddio-supply = <&vcc_1v8_reg>; + vddlvds-supply = <&vcc_3v3_reg>; + reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + port@1 { + reg = <1>; + lvds_ep: endpoint { + remote-endpoint = <&panel_ep>; + }; + }; + }; -- cgit v1.2.3 From d5890d5ff4b93bb4ccb0fb2085fc2da77c89790a Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Tue, 26 Jun 2018 16:53:34 +0800 Subject: dt-bindings: display: rockchip: add document for px30 vop Add the compatible values for the px30 display controllers. Signed-off-by: Sandy Huang Acked-by: Rob Herring [added commit message] Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/1530003215-46593-2-git-send-email-hjc@rock-chips.com --- Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index eeda3597011e..5de2a0f0d1f4 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt @@ -8,6 +8,8 @@ Required properties: - compatible: value should be one of the following "rockchip,rk3036-vop"; "rockchip,rk3126-vop"; + "rockchip,px30-vop-lit"; + "rockchip,px30-vop-big"; "rockchip,rk3288-vop"; "rockchip,rk3368-vop"; "rockchip,rk3366-vop"; -- cgit v1.2.3 From 2fca585502716c25c52ad4fe54207f80762bc7b4 Mon Sep 17 00:00:00 2001 From: Siddartha Mohanadoss Date: Thu, 2 Aug 2018 18:43:38 -0700 Subject: dt-bindings: iio: adc: Add DT binding document for PMIC5 ADC PMIC5 ADC has support for clients to measure voltage and current on inputs connected to the PMIC. Clients include reading voltage phone power and on board system thermistors for thermal management. ADC5 on certain PMIC has support to read battery current. This change adds documentation. Signed-off-by: Siddartha Mohanadoss Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/qcom,spmi-vadc.txt | 77 ++++++++++---- include/dt-bindings/iio/qcom,spmi-vadc.h | 115 ++++++++++++++++++++- 2 files changed, 172 insertions(+), 20 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt index 0fb46137f936..8498f11d06cd 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt @@ -1,7 +1,9 @@ -Qualcomm's SPMI PMIC voltage ADC +Qualcomm's SPMI PMIC ADC -SPMI PMIC voltage ADC (VADC) provides interface to clients to read -voltage. The VADC is a 15-bit sigma-delta ADC. +- SPMI PMIC voltage ADC (VADC) provides interface to clients to read + voltage. The VADC is a 15-bit sigma-delta ADC. +- SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read + voltage. The VADC is a 16-bit sigma-delta ADC. VADC node: @@ -9,6 +11,8 @@ VADC node: Usage: required Value type: Definition: Should contain "qcom,spmi-vadc". + Should contain "qcom,spmi-adc5" for PMIC5 ADC driver. + Should contain "qcom,spmi-adc-rev2" for PMIC rev2 ADC driver. - reg: Usage: required @@ -45,13 +49,26 @@ Channel node properties: Definition: ADC channel number. See include/dt-bindings/iio/qcom,spmi-vadc.h +- label: + Usage: required for "qcom,spmi-adc5" and "qcom,spmi-adc-rev2" + Value type: + Definition: ADC input of the platform as seen in the schematics. + For thermistor inputs connected to generic AMUX or GPIO inputs + these can vary across platform for the same pins. Hence select + the platform schematics name for this channel. + - qcom,decimation: Usage: optional Value type: Definition: This parameter is used to decrease ADC sampling rate. Quicker measurements can be made by reducing decimation ratio. - Valid values are 512, 1024, 2048, 4096. - If property is not found, default value of 512 will be used. + - For compatible property "qcom,spmi-vadc", valid values are + 512, 1024, 2048, 4096. If property is not found, default value + of 512 will be used. + - For compatible property "qcom,spmi-adc5", valid values are 250, 420 + and 840. If property is not found, default value of 840 is used. + - For compatible property "qcom,spmi-adc-rev2", valid values are 256, + 512 and 1024. If property is not present, default value is 1024. - qcom,pre-scaling: Usage: optional @@ -66,21 +83,38 @@ Channel node properties: - qcom,ratiometric: Usage: optional Value type: - Definition: Channel calibration type. If this property is specified - VADC will use the VDD reference (1.8V) and GND for channel - calibration. If property is not found, channel will be - calibrated with 0.625V and 1.25V reference channels, also - known as absolute calibration. + Definition: Channel calibration type. + - For compatible property "qcom,spmi-vadc", if this property is + specified VADC will use the VDD reference (1.8V) and GND for + channel calibration. If property is not found, channel will be + calibrated with 0.625V and 1.25V reference channels, also + known as absolute calibration. + - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2", + if this property is specified VADC will use the VDD reference + (1.875V) and GND for channel calibration. If property is not found, + channel will be calibrated with 0V and 1.25V reference channels, + also known as absolute calibration. - qcom,hw-settle-time: Usage: optional Value type: Definition: Time between AMUX getting configured and the ADC starting - conversion. Delay = 100us * (value) for value < 11, and - 2ms * (value - 10) otherwise. - Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800, - 900 us and 1, 2, 4, 6, 8, 10 ms - If property is not found, channel will use 0us. + conversion. The 'hw_settle_time' is an index used from valid values + and programmed in hardware to achieve the hardware settling delay. + - For compatible property "qcom,spmi-vadc" and "qcom,spmi-adc-rev2", + Delay = 100us * (hw_settle_time) for hw_settle_time < 11, + and 2ms * (hw_settle_time - 10) otherwise. + Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800, + 900 us and 1, 2, 4, 6, 8, 10 ms. + If property is not found, channel will use 0us. + - For compatible property "qcom,spmi-adc5", delay = 15us for + value 0, 100us * (value) for values < 11, + and 2ms * (value - 10) otherwise. + Valid values are: 15, 100, 200, 300, 400, 500, 600, 700, 800, + 900 us and 1, 2, 4, 6, 8, 10 ms + Certain controller digital versions have valid values of + 15, 100, 200, 300, 400, 500, 600, 700, 1, 2, 4, 8, 16, 32, 64, 128 ms + If property is not found, channel will use 15us. - qcom,avg-samples: Usage: optional @@ -89,13 +123,18 @@ Channel node properties: Averaging provides the option to obtain a single measurement from the ADC that is an average of multiple samples. The value selected is 2^(value). - Valid values are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 - If property is not found, 1 sample will be used. + - For compatible property "qcom,spmi-vadc", valid values + are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 + If property is not found, 1 sample will be used. + - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2", + valid values are: 1, 2, 4, 8, 16 + If property is not found, 1 sample will be used. NOTE: -Following channels, also known as reference point channels, are used for -result calibration and their channel configuration nodes should be defined: +For compatible property "qcom,spmi-vadc" following channels, also known as +reference point channels, are used for result calibration and their channel +configuration nodes should be defined: VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV, VADC_GND_REF and VADC_VDD_VADC. diff --git a/include/dt-bindings/iio/qcom,spmi-vadc.h b/include/dt-bindings/iio/qcom,spmi-vadc.h index 42121fa238fa..bf54b5adc065 100644 --- a/include/dt-bindings/iio/qcom,spmi-vadc.h +++ b/include/dt-bindings/iio/qcom,spmi-vadc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014,2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -116,4 +116,117 @@ #define VADC_LR_MUX10_PU1_PU2_AMUX_USB_ID 0xf9 #define VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM 0xfc +/* ADC channels for SPMI PMIC5 */ + +#define ADC5_REF_GND 0x00 +#define ADC5_1P25VREF 0x01 +#define ADC5_VREF_VADC 0x02 +#define ADC5_VREF_VADC5_DIV_3 0x82 +#define ADC5_VPH_PWR 0x83 +#define ADC5_VBAT_SNS 0x84 +#define ADC5_VCOIN 0x85 +#define ADC5_DIE_TEMP 0x06 +#define ADC5_USB_IN_I 0x07 +#define ADC5_USB_IN_V_16 0x08 +#define ADC5_CHG_TEMP 0x09 +#define ADC5_BAT_THERM 0x0a +#define ADC5_BAT_ID 0x0b +#define ADC5_XO_THERM 0x0c +#define ADC5_AMUX_THM1 0x0d +#define ADC5_AMUX_THM2 0x0e +#define ADC5_AMUX_THM3 0x0f +#define ADC5_AMUX_THM4 0x10 +#define ADC5_AMUX_THM5 0x11 +#define ADC5_GPIO1 0x12 +#define ADC5_GPIO2 0x13 +#define ADC5_GPIO3 0x14 +#define ADC5_GPIO4 0x15 +#define ADC5_GPIO5 0x16 +#define ADC5_GPIO6 0x17 +#define ADC5_GPIO7 0x18 +#define ADC5_SBUx 0x99 +#define ADC5_MID_CHG_DIV6 0x1e +#define ADC5_OFF 0xff + +/* 30k pull-up1 */ +#define ADC5_BAT_THERM_30K_PU 0x2a +#define ADC5_BAT_ID_30K_PU 0x2b +#define ADC5_XO_THERM_30K_PU 0x2c +#define ADC5_AMUX_THM1_30K_PU 0x2d +#define ADC5_AMUX_THM2_30K_PU 0x2e +#define ADC5_AMUX_THM3_30K_PU 0x2f +#define ADC5_AMUX_THM4_30K_PU 0x30 +#define ADC5_AMUX_THM5_30K_PU 0x31 +#define ADC5_GPIO1_30K_PU 0x32 +#define ADC5_GPIO2_30K_PU 0x33 +#define ADC5_GPIO3_30K_PU 0x34 +#define ADC5_GPIO4_30K_PU 0x35 +#define ADC5_GPIO5_30K_PU 0x36 +#define ADC5_GPIO6_30K_PU 0x37 +#define ADC5_GPIO7_30K_PU 0x38 +#define ADC5_SBUx_30K_PU 0x39 + +/* 100k pull-up2 */ +#define ADC5_BAT_THERM_100K_PU 0x4a +#define ADC5_BAT_ID_100K_PU 0x4b +#define ADC5_XO_THERM_100K_PU 0x4c +#define ADC5_AMUX_THM1_100K_PU 0x4d +#define ADC5_AMUX_THM2_100K_PU 0x4e +#define ADC5_AMUX_THM3_100K_PU 0x4f +#define ADC5_AMUX_THM4_100K_PU 0x50 +#define ADC5_AMUX_THM5_100K_PU 0x51 +#define ADC5_GPIO1_100K_PU 0x52 +#define ADC5_GPIO2_100K_PU 0x53 +#define ADC5_GPIO3_100K_PU 0x54 +#define ADC5_GPIO4_100K_PU 0x55 +#define ADC5_GPIO5_100K_PU 0x56 +#define ADC5_GPIO6_100K_PU 0x57 +#define ADC5_GPIO7_100K_PU 0x58 +#define ADC5_SBUx_100K_PU 0x59 + +/* 400k pull-up3 */ +#define ADC5_BAT_THERM_400K_PU 0x6a +#define ADC5_BAT_ID_400K_PU 0x6b +#define ADC5_XO_THERM_400K_PU 0x6c +#define ADC5_AMUX_THM1_400K_PU 0x6d +#define ADC5_AMUX_THM2_400K_PU 0x6e +#define ADC5_AMUX_THM3_400K_PU 0x6f +#define ADC5_AMUX_THM4_400K_PU 0x70 +#define ADC5_AMUX_THM5_400K_PU 0x71 +#define ADC5_GPIO1_400K_PU 0x72 +#define ADC5_GPIO2_400K_PU 0x73 +#define ADC5_GPIO3_400K_PU 0x74 +#define ADC5_GPIO4_400K_PU 0x75 +#define ADC5_GPIO5_400K_PU 0x76 +#define ADC5_GPIO6_400K_PU 0x77 +#define ADC5_GPIO7_400K_PU 0x78 +#define ADC5_SBUx_400K_PU 0x79 + +/* 1/3 Divider */ +#define ADC5_GPIO1_DIV3 0x92 +#define ADC5_GPIO2_DIV3 0x93 +#define ADC5_GPIO3_DIV3 0x94 +#define ADC5_GPIO4_DIV3 0x95 +#define ADC5_GPIO5_DIV3 0x96 +#define ADC5_GPIO6_DIV3 0x97 +#define ADC5_GPIO7_DIV3 0x98 +#define ADC5_SBUx_DIV3 0x99 + +/* Current and combined current/voltage channels */ +#define ADC5_INT_EXT_ISENSE 0xa1 +#define ADC5_PARALLEL_ISENSE 0xa5 +#define ADC5_CUR_REPLICA_VDS 0xa7 +#define ADC5_CUR_SENS_BATFET_VDS_OFFSET 0xa9 +#define ADC5_CUR_SENS_REPLICA_VDS_OFFSET 0xab +#define ADC5_EXT_SENS_OFFSET 0xad + +#define ADC5_INT_EXT_ISENSE_VBAT_VDATA 0xb0 +#define ADC5_INT_EXT_ISENSE_VBAT_IDATA 0xb1 +#define ADC5_EXT_ISENSE_VBAT_VDATA 0xb2 +#define ADC5_EXT_ISENSE_VBAT_IDATA 0xb3 +#define ADC5_PARALLEL_ISENSE_VBAT_VDATA 0xb4 +#define ADC5_PARALLEL_ISENSE_VBAT_IDATA 0xb5 + +#define ADC5_MAX_CHANNEL 0xc0 + #endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */ -- cgit v1.2.3 From 07c12b1c007c5c1d9c434ec9a19373ce5d87fe04 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 2 Aug 2018 20:18:52 -0400 Subject: iio: imu: mpu6050: add support for regulator framework This patch adds support for the regulator framework to the mpu6050 driver. Signed-off-by: Brian Masney Signed-off-by: Jonathan Marek Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/imu/inv_mpu6050.txt | 1 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 62 ++++++++++++++++++++++ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 2 + 3 files changed, 65 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt index b7def51c8ad9..d39907b12a46 100644 --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt +++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt @@ -21,6 +21,7 @@ Required properties: bindings. Optional properties: + - vddio-supply: regulator phandle for VDDIO supply - mount-matrix: an optional 3x3 mounting rotation matrix - i2c-gate node. These devices also support an auxiliary i2c bus. This is simple enough to be described using the i2c-gate binding. See diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index d80ef468508a..1e428c196a82 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "inv_mpu_iio.h" /* @@ -926,6 +927,39 @@ error_power_off: return result; } +static int inv_mpu_core_enable_regulator(struct inv_mpu6050_state *st) +{ + int result; + + result = regulator_enable(st->vddio_supply); + if (result) { + dev_err(regmap_get_device(st->map), + "Failed to enable regulator: %d\n", result); + } else { + /* Give the device a little bit of time to start up. */ + usleep_range(35000, 70000); + } + + return result; +} + +static int inv_mpu_core_disable_regulator(struct inv_mpu6050_state *st) +{ + int result; + + result = regulator_disable(st->vddio_supply); + if (result) + dev_err(regmap_get_device(st->map), + "Failed to disable regulator: %d\n", result); + + return result; +} + +static void inv_mpu_core_disable_regulator_action(void *_data) +{ + inv_mpu_core_disable_regulator(_data); +} + int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type) { @@ -992,6 +1026,28 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, return -EINVAL; } + st->vddio_supply = devm_regulator_get(dev, "vddio"); + if (IS_ERR(st->vddio_supply)) { + if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER) + dev_err(dev, "Failed to get vddio regulator %d\n", + (int)PTR_ERR(st->vddio_supply)); + + return PTR_ERR(st->vddio_supply); + } + + result = inv_mpu_core_enable_regulator(st); + if (result) + return result; + + result = devm_add_action(dev, inv_mpu_core_disable_regulator_action, + st); + if (result) { + inv_mpu_core_disable_regulator_action(st); + dev_err(dev, "Failed to setup regulator cleanup action %d\n", + result); + return result; + } + /* power is turned on inside check chip type*/ result = inv_check_and_setup_chip(st); if (result) @@ -1051,7 +1107,12 @@ static int inv_mpu_resume(struct device *dev) int result; mutex_lock(&st->lock); + result = inv_mpu_core_enable_regulator(st); + if (result) + goto out_unlock; + result = inv_mpu6050_set_power_itg(st, true); +out_unlock: mutex_unlock(&st->lock); return result; @@ -1064,6 +1125,7 @@ static int inv_mpu_suspend(struct device *dev) mutex_lock(&st->lock); result = inv_mpu6050_set_power_itg(st, false); + inv_mpu_core_disable_regulator(st); mutex_unlock(&st->lock); return result; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index e69a59659dbc..6bcc11fc1b88 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -129,6 +129,7 @@ struct inv_mpu6050_hw { * @chip_period: chip internal period estimation (~1kHz). * @it_timestamp: timestamp from previous interrupt. * @data_timestamp: timestamp for next data sample. + * @vddio_supply voltage regulator for the chip. */ struct inv_mpu6050_state { struct mutex lock; @@ -149,6 +150,7 @@ struct inv_mpu6050_state { s64 chip_period; s64 it_timestamp; s64 data_timestamp; + struct regulator *vddio_supply; }; /*register and associated bit definition*/ -- cgit v1.2.3 From 1ed80a817bc42de91701cc60e58d968077359a58 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 2 Aug 2018 20:18:55 -0400 Subject: dt-bindings: iio: tsl2772: add new bindings This patch adds the new properties amstaos,proximity-diodes and led-max-microamp to the tsl2772 driver. This patch also removes the driver from the trivial-devices.txt. Signed-off-by: Brian Masney Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/light/tsl2772.txt | 41 ++++++++++++++++++++++ .../devicetree/bindings/trivial-devices.txt | 10 ------ 2 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/light/tsl2772.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/light/tsl2772.txt b/Documentation/devicetree/bindings/iio/light/tsl2772.txt new file mode 100644 index 000000000000..4e7d98627cbf --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/tsl2772.txt @@ -0,0 +1,41 @@ +* AMS/TAOS ALS and proximity sensor + +Required properties: + + - compatible: Should be one of + "amstaos,tsl2571" + "amstaos,tsl2671" + "amstaos,tmd2671" + "amstaos,tsl2771" + "amstaos,tmd2771" + "amstaos,tsl2572" + "amstaos,tsl2672" + "amstaos,tmd2672" + "amstaos,tsl2772" + "amstaos,tmd2772" + - reg: the I2C address of the device + +Optional properties: + + - amstaos,proximity-diodes - proximity diodes to enable. <0>, <1>, or <0 1> + are the only valid values. + - led-max-microamp - current for the proximity LED. Must be 100000, 50000, + 25000, or 13000. + - vdd-supply: phandle to the regulator that provides power to the sensor. + - vddio-supply: phandle to the regulator that provides power to the bus. + - interrupts: the sole interrupt generated by the device + + Refer to interrupt-controller/interrupts.txt for generic interrupt client + node bindings. + +Example: + +tsl2772@39 { + compatible = "amstaos,tsl2772"; + reg = <0x39>; + interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&pm8941_l17>; + vddio-supply = <&pm8941_lvs1>; + amstaos,proximity-diodes = <0>; + led-max-microamp = <100000>; +}; diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt index 763a2808a95c..a977ccef7230 100644 --- a/Documentation/devicetree/bindings/trivial-devices.txt +++ b/Documentation/devicetree/bindings/trivial-devices.txt @@ -21,16 +21,6 @@ adi,adt7490 +/-1C TDM Extended Temp Range I.C adi,adxl345 Three-Axis Digital Accelerometer adi,adxl346 Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too) ams,iaq-core AMS iAQ-Core VOC Sensor -amstaos,tsl2571 AMS/TAOS ALS and proximity sensor -amstaos,tsl2671 AMS/TAOS ALS and proximity sensor -amstaos,tmd2671 AMS/TAOS ALS and proximity sensor -amstaos,tsl2771 AMS/TAOS ALS and proximity sensor -amstaos,tmd2771 AMS/TAOS ALS and proximity sensor -amstaos,tsl2572 AMS/TAOS ALS and proximity sensor -amstaos,tsl2672 AMS/TAOS ALS and proximity sensor -amstaos,tmd2672 AMS/TAOS ALS and proximity sensor -amstaos,tsl2772 AMS/TAOS ALS and proximity sensor -amstaos,tmd2772 AMS/TAOS ALS and proximity sensor at,24c08 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor -- cgit v1.2.3 From 28b6977e089dda97f8f32ac1a6a223f59e7065f4 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 2 Aug 2018 20:18:59 -0400 Subject: dt-bindings: iio: tsl2772: add binding for avago,apds9930 This patch adds avago,apds9930 to the tsl2772 bindings. Signed-off-by: Brian Masney Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/light/tsl2772.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/light/tsl2772.txt b/Documentation/devicetree/bindings/iio/light/tsl2772.txt index 4e7d98627cbf..1c5e6f17a1df 100644 --- a/Documentation/devicetree/bindings/iio/light/tsl2772.txt +++ b/Documentation/devicetree/bindings/iio/light/tsl2772.txt @@ -13,6 +13,7 @@ Required properties: "amstaos,tmd2672" "amstaos,tsl2772" "amstaos,tmd2772" + "avago,apds9930" - reg: the I2C address of the device Optional properties: -- cgit v1.2.3 From ad6e1fb0312c5a4b4fc70e17b73ca1cdfc68c429 Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Fri, 10 Aug 2018 11:46:19 +0300 Subject: dt-bindings: iio: accel: Add docs for ADXL372 Add the device tree binding documentation for the ADXL372 3-axis digital accelerometer. Signed-off-by: Stefan Popa Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/accel/adxl372.txt | 22 ++++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl372.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/accel/adxl372.txt b/Documentation/devicetree/bindings/iio/accel/adxl372.txt new file mode 100644 index 000000000000..9409984719e9 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/accel/adxl372.txt @@ -0,0 +1,22 @@ +Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer + +http://www.analog.com/media/en/technical-documentation/data-sheets/adxl372.pdf + +Required properties: + - compatible : should be "adi,adxl372" + - reg: SPI chip select number for the device + - spi-max-frequency: Max SPI frequency to use + +Optional properties: + - interrupts: interrupt mapping for IRQ as documented in + Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +Example: + + accelerometer@0 { + compatible = "adi,adxl372"; + reg = <0>; + spi-max-frequency = <1000000>; + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index fe23f8b66712..2605b733f603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -548,6 +548,7 @@ M: Stefan Popa W: http://ez.analog.com/community/linux-device-drivers S: Supported F: drivers/iio/accel/adxl372.c +F: Documentation/devicetree/bindings/iio/accel/adxl372.txt AF9013 MEDIA DRIVER M: Antti Palosaari -- cgit v1.2.3 From 1c4fbbea34087007b871d444bcbe7c24fad32bd3 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Wed, 8 Aug 2018 10:09:16 +0200 Subject: dt-bindings: iio: adc: add bindings for mcp3911 MCP3911 is a dual channel Analog Front End (AFE) containing two synchronous sampling delta-sigma Analog-to-Digital Converters (ADC). Co-Developed-by: Kent Gustavsson Signed-off-by: Kent Gustavsson Signed-off-by: Marcus Folkesson Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/mcp3911.txt | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/mcp3911.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3911.txt b/Documentation/devicetree/bindings/iio/adc/mcp3911.txt new file mode 100644 index 000000000000..3071f48fb30b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/mcp3911.txt @@ -0,0 +1,30 @@ +* Microchip MCP3911 Dual channel analog front end (ADC) + +Required properties: + - compatible: Should be "microchip,mcp3911" + - reg: SPI chip select number for the device + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt. + Max frequency for this chip is 20MHz. + +Optional properties: + - clocks: Phandle and clock identifier for sampling clock + - interrupt-parent: Phandle to the parent interrupt controller + - interrupts: IRQ line for the ADC + - microchip,device-addr: Device address when multiple MCP3911 chips are present on the + same SPI bus. Valid values are 0-3. Defaults to 0. + - vref-supply: Phandle to the external reference voltage supply. + +Example: +adc@0 { + compatible = "microchip,mcp3911"; + reg = <0>; + interrupt-parent = <&gpio5>; + interrupts = <15 IRQ_TYPE_EDGE_RISING>; + spi-max-frequency = <20000000>; + microchip,device-addr = <0>; + vref-supply = <&vref_reg>; + clocks = <&xtal>; +}; -- cgit v1.2.3 From 7e7b68ef0076691f05b85a3ecd604a6160015fe9 Mon Sep 17 00:00:00 2001 From: Brian Starkey Date: Tue, 21 Aug 2018 17:16:11 +0100 Subject: drm/fourcc: Add DOC: overview comment There's a number of things which haven't previously been documented around the usage of format modifiers. Capture the current understanding in an overview comment and add it to the rst documentation. Ideally, the generated documentation would also include documentation of all of the #defines, but the kernel-doc system doesn't currently support kernel-doc comments on #define constants. Suggested-by: Daniel Vetter Signed-off-by: Brian Starkey Reviewed-by: Daniel Vetter Signed-off-by: Alexandru Gheorghe Link: https://patchwork.freedesktop.org/patch/msgid/20180821161611.10424-1-brian.starkey@arm.com --- Documentation/gpu/drm-kms.rst | 6 ++++++ include/uapi/drm/drm_fourcc.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 5dee6b8a4c12..f8f5bf11a6ca 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -323,6 +323,12 @@ Frame Buffer Functions Reference DRM Format Handling =================== +.. kernel-doc:: include/uapi/drm/drm_fourcc.h + :doc: overview + +Format Functions Reference +-------------------------- + .. kernel-doc:: include/drm/drm_fourcc.h :internal: diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index d43949b5bb3e..21c50b39596f 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -30,6 +30,42 @@ extern "C" { #endif +/** + * DOC: overview + * + * In the DRM subsystem, framebuffer pixel formats are described using the + * fourcc codes defined in `include/uapi/drm/drm_fourcc.h`. In addition to the + * fourcc code, a Format Modifier may optionally be provided, in order to + * further describe the buffer's format - for example tiling or compression. + * + * Format Modifiers + * ---------------- + * + * Format modifiers are used in conjunction with a fourcc code, forming a + * unique fourcc:modifier pair. This format:modifier pair must fully define the + * format and data layout of the buffer, and should be the only way to describe + * that particular buffer. + * + * Having multiple fourcc:modifier pairs which describe the same layout should + * be avoided, as such aliases run the risk of different drivers exposing + * different names for the same data format, forcing userspace to understand + * that they are aliases. + * + * Format modifiers may change any property of the buffer, including the number + * of planes and/or the required allocation size. Format modifiers are + * vendor-namespaced, and as such the relationship between a fourcc code and a + * modifier is specific to the modifer being used. For example, some modifiers + * may preserve meaning - such as number of planes - from the fourcc code, + * whereas others may not. + * + * Vendors should document their modifier usage in as much detail as + * possible, to ensure maximum compatibility across devices, drivers and + * applications. + * + * The authoritative list of format modifier codes is found in + * `include/uapi/drm/drm_fourcc.h` + */ + #define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \ ((__u32)(c) << 16) | ((__u32)(d) << 24)) -- cgit v1.2.3 From d1071f726a7640ce0525d1868844bbb107e9e43a Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Tue, 21 Aug 2018 21:31:25 +0200 Subject: dt-bindings: iio: dac: add bindings for ltc1660 LTC1665/LTC1660 is a 8/10-bit Digital-to-Analog Converter (DAC) with eight individual channels. Signed-off-by: Marcus Folkesson Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/ltc1660.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/dac/ltc1660.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/ltc1660.txt b/Documentation/devicetree/bindings/iio/dac/ltc1660.txt new file mode 100644 index 000000000000..c5b5f22d6c64 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/ltc1660.txt @@ -0,0 +1,21 @@ +* Linear Technology Micropower octal 8-Bit and 10-Bit DACs + +Required properties: + - compatible: Must be one of the following: + "lltc,ltc1660" + "lltc,ltc1665" + - reg: SPI chip select number for the device + - vref-supply: Phandle to the voltage reference supply + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt. + Max frequency for this chip is 5 MHz. + +Example: +dac@0 { + compatible = "lltc,ltc1660"; + reg = <0>; + spi-max-frequency = <5000000>; + vref-supply = <&vref_reg>; +}; -- cgit v1.2.3 From 8bb878cf20ae10809c36db96993bfce7026d062b Mon Sep 17 00:00:00 2001 From: Levin Du Date: Mon, 30 Jul 2018 10:12:01 +0800 Subject: arm64: dts: rockchip: add support for ROC-RK3399-PC board ROC-RK3399-PC is a power efficient 4GB LPDDR4 single board computer with USB 3.0 and Gigabit Ethernet in a form factor compatible with the Raspberry Pi. It is based on the Rockchip RK3399 SoC, powered by the Type-C port. The devicetree currently supports peripherals of: - Ethernet - HDMI - SD Card - UART2 debug - Type-C - eMMC USB3 in Type-C port currently only works with normal orientation, not flip one. Signed-off-by: Levin Du Reviewed-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 + arch/arm64/boot/dts/rockchip/Makefile | 1 + arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts | 680 +++++++++++++++++++++ 3 files changed, 685 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index acfd3c773dd0..ab5fde889c6f 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -59,6 +59,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328"; +- Firefly ROC-RK3399-PC board: + Required root node properties: + - compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + - ChipSPARK PopMetal-RK3288 board: Required root node properties: - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index b0092d95b574..06028db2d490 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -14,5 +14,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts new file mode 100644 index 000000000000..19f7732d728c --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts @@ -0,0 +1,680 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd + */ + +/dts-v1/; +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Firefly ROC-RK3399-PC Board"; + compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 25000 0>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + vcc_vbus_typec0: vcc-vbus-typec0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_vbus_typec0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + /* + * should be placed inside mp8859, but not until mp8859 has + * its own dt-binding. + */ + vcc12v_sys: mp8859-dcdc1 { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + vin-supply = <&vcc_vbus_typec0>; + }; + + /* switched by pmic_sleep */ + vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc12v_sys>; + }; + + /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */ + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en &hub_rst>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_vbus_typec1: vcc-vbus-typec1 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_vbus_typec1_en>; + regulator-name = "vcc_vbus_typec1"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_sys>; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc3v3_sys>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c3>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_cec>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + vcc10-supply = <&vcc3v3_sys>; + vcc11-supply = <&vcc3v3_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_codec: LDO_REG1 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_hdmi: LDO_REG2 { + regulator-name = "vcc1v8_hdmi"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca0v9_hdmi: LDO_REG7 { + regulator-name = "vcca0v9_hdmi"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: vcc_lan: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel1_gpio>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel2_gpio>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + i2c-scl-rising-time-ns = <300>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c4 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + fusb1: usb-typec@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio1>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&fusb1_int>; + vbus-supply = <&vcc_vbus_typec1>; + status = "okay"; + }; +}; + +&i2c7 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + fusb0: usb-typec@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&fusb0_int>; + vbus-supply = <&vcc_vbus_typec0>; + status = "okay"; + }; +}; + +&i2s0 { + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + status = "okay"; +}; + +&i2s1 { + rockchip,playback-channels = <2>; + rockchip,capture-channels = <2>; + status = "okay"; +}; + +&i2s2 { + status = "okay"; +}; + +&io_domains { + audio-supply = <&vcca1v8_codec>; + bt656-supply = <&vcc_3v0>; + gpio1830-supply = <&vcc_3v0>; + sdmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + lcd-panel { + lcd_panel_reset: lcd-panel-reset { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + hub_rst: hub-rst { + rockchip,pins = <2 RK_PA4 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + usb-typec { + vcc_vbus_typec1_en: vcc-vbus-typec1-en { + rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + fusb30x { + fusb0_int: fusb0-int { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + fusb1_int: fusb1-int { + rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&tcphy0 { + status = "okay"; +}; + +&tcphy1 { + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + phy-supply = <&vcc_vbus_typec0>; + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + phy-supply = <&vcc_vbus_typec1>; + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; -- cgit v1.2.3 From d15524609bd66f72c511d410c0490825962983c1 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 1 Aug 2018 16:45:14 +0800 Subject: dt-bindings: rockchip: grf: add grf and pmugrf description for px30 This patch adds the compatible of GRF and PMUGRF for PX30 SoCs. Signed-off-by: Liang Chen Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/soc/rockchip/grf.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt index 7dc5ce858a0e..46e27cd69f18 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt @@ -13,6 +13,7 @@ On RK3328 SoCs, the GRF adds a section for USB2PHYGRF, Required Properties: - compatible: GRF should be one of the following: + - "rockchip,px30-grf", "syscon": for px30 - "rockchip,rk3036-grf", "syscon": for rk3036 - "rockchip,rk3066-grf", "syscon": for rk3066 - "rockchip,rk3188-grf", "syscon": for rk3188 @@ -23,6 +24,7 @@ Required Properties: - "rockchip,rk3399-grf", "syscon": for rk3399 - "rockchip,rv1108-grf", "syscon": for rv1108 - compatible: PMUGRF should be one of the following: + - "rockchip,px30-pmugrf", "syscon": for px30 - "rockchip,rk3368-pmugrf", "syscon": for rk3368 - "rockchip,rk3399-pmugrf", "syscon": for rk3399 - compatible: SGRF should be one of the following -- cgit v1.2.3 From 4afbce842a5c5eb413142e267c9ff56cc6ee6b91 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 1 Aug 2018 16:45:16 +0800 Subject: arm64: dts: rockchip: add PX30 evaluation board devicetree This patch add px30-evb.dts for PX30 evaluation board. Tested on PX30 evb. Signed-off-by: Liang Chen Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 + arch/arm64/boot/dts/rockchip/Makefile | 1 + arch/arm64/boot/dts/rockchip/px30-evb.dts | 231 +++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/px30-evb.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index ab5fde889c6f..5fc9c236ca87 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -172,6 +172,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368"; +- Rockchip PX30 Evaluation board: + Required root node properties: + - compatible = "rockchip,px30-evb", "rockchip,px30"; + - Rockchip RV1108 Evaluation board Required root node properties: - compatible = "rockchip,rv1108-evb", "rockchip,rv1108"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 06028db2d490..d08b7eda28d2 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts new file mode 100644 index 000000000000..c74aa910a631 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-evb.dts @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include +#include +#include +#include "px30.dtsi" + +/ { + model = "Rockchip PX30 EVB"; + compatible = "rockchip,px30-evb", "rockchip,px30"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + esc-key { + label = "esc"; + linux,code = ; + press-threshold-microvolt = <1310000>; + }; + + home-key { + label = "home"; + linux,code = ; + press-threshold-microvolt = <624000>; + }; + + menu-key { + label = "menu"; + linux,code = ; + press-threshold-microvolt = <987000>; + }; + + vol-down-key { + label = "volume down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + label = "volume up"; + linux,code = ; + press-threshold-microvolt = <17000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc5v0_sys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&display_subsystem { + status = "okay"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&gmac { + clock_in_out = "output"; + phy-supply = <&vcc_phy>; + snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 50000 50000>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2s1_2ch { + status = "okay"; +}; + +&io_domains { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <800>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; -- cgit v1.2.3 From d9be10edf7d6040468f89824df0dfcfcbf3a693b Mon Sep 17 00:00:00 2001 From: Aapo Vienamo Date: Fri, 10 Aug 2018 21:08:03 +0300 Subject: dt-bindings: Add Tegra PMC pad configuration bindings Document the PMC pinctrl bindings for pad power state and signaling voltage configuration. Both nvidia,tegra186-pmc.txt and nvidia,tegra20-pmc.txt are modified as they both cover SoC generations for which these bindings apply. Add a header defining Tegra PMC pad voltage configurations. Signed-off-by: Aapo Vienamo Acked-by: Jon Hunter Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 93 +++++++++++++++++++ .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 103 +++++++++++++++++++++ include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h | 18 ++++ 3 files changed, 214 insertions(+) create mode 100644 include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt index 5a3bf7c5a7a0..c9fd6d1de57e 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt @@ -34,3 +34,96 @@ Board DTS: pmc@c360000 { nvidia,invert-interrupt; }; + +== Pad Control == + +On Tegra SoCs a pad is a set of pins which are configured as a group. +The pin grouping is a fixed attribute of the hardware. The PMC can be +used to set pad power state and signaling voltage. A pad can be either +in active or power down mode. The support for power state and signaling +voltage configuration varies depending on the pad in question. 3.3 V and +1.8 V signaling voltages are supported on pins where software +controllable signaling voltage switching is available. + +Pad configurations are described with pin configuration nodes which +are placed under the pmc node and they are referred to by the pinctrl +client properties. For more information see +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. + +The following pads are present on Tegra186: +csia csib dsi mipi-bias +pex-clk-bias pex-clk3 pex-clk2 pex-clk1 +usb0 usb1 usb2 usb-bias +uart audio hsic dbg +hdmi-dp0 hdmi-dp1 pex-cntrl sdmmc2-hv +sdmmc4 cam dsib dsic +dsid csic csid csie +dsif spi ufs dmic-hv +edp sdmmc1-hv sdmmc3-hv conn +audio-hv ao-hv + +Required pin configuration properties: + - pins: A list of strings, each of which contains the name of a pad + to be configured. + +Optional pin configuration properties: + - low-power-enable: Configure the pad into power down mode + - low-power-disable: Configure the pad into active mode + - power-source: Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or + TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages. + The values are defined in + include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. + +Note: The power state can be configured on all of the above pads except + for ao-hv. Following pads have software configurable signaling + voltages: sdmmc2-hv, dmic-hv, sdmmc1-hv, sdmmc3-hv, audio-hv, + ao-hv. + +Pad configuration state example: + pmc: pmc@7000e400 { + compatible = "nvidia,tegra186-pmc"; + reg = <0 0x0c360000 0 0x10000>, + <0 0x0c370000 0 0x10000>, + <0 0x0c380000 0 0x10000>, + <0 0x0c390000 0 0x10000>; + reg-names = "pmc", "wake", "aotag", "scratch"; + + ... + + sdmmc1_3v3: sdmmc1-3v3 { + pins = "sdmmc1-hv"; + power-source = ; + }; + + sdmmc1_1v8: sdmmc1-1v8 { + pins = "sdmmc1-hv"; + power-source = ; + }; + + hdmi_off: hdmi-off { + pins = "hdmi"; + low-power-enable; + } + + hdmi_on: hdmi-on { + pins = "hdmi"; + low-power-disable; + } + }; + +Pinctrl client example: + sdmmc1: sdhci@3400000 { + ... + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; + pinctrl-0 = <&sdmmc1_3v3>; + pinctrl-1 = <&sdmmc1_1v8>; + }; + + ... + + sor0: sor@15540000 { + ... + pinctrl-0 = <&hdmi_off>; + pinctrl-1 = <&hdmi_on>; + pinctrl-names = "hdmi-on", "hdmi-off"; + }; diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt index a74b37b07e5c..cb12f33a247f 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt @@ -195,3 +195,106 @@ Example: power-domains = <&pd_audio>; ... }; + +== Pad Control == + +On Tegra SoCs a pad is a set of pins which are configured as a group. +The pin grouping is a fixed attribute of the hardware. The PMC can be +used to set pad power state and signaling voltage. A pad can be either +in active or power down mode. The support for power state and signaling +voltage configuration varies depending on the pad in question. 3.3 V and +1.8 V signaling voltages are supported on pins where software +controllable signaling voltage switching is available. + +The pad configuration state nodes are placed under the pmc node and they +are referred to by the pinctrl client properties. For more information +see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt. +The pad name should be used as the value of the pins property in pin +configuration nodes. + +The following pads are present on Tegra124 and Tegra132: +audio bb cam comp +csia csb cse dsi +dsib dsic dsid hdmi +hsic hv lvds mipi-bias +nand pex-bias pex-clk1 pex-clk2 +pex-cntrl sdmmc1 sdmmc3 sdmmc4 +sys_ddc uart usb0 usb1 +usb2 usb_bias + +The following pads are present on Tegra210: +audio audio-hv cam csia +csib csic csid csie +csif dbg debug-nonao dmic +dp dsi dsib dsic +dsid emmc emmc2 gpio +hdmi hsic lvds mipi-bias +pex-bias pex-clk1 pex-clk2 pex-cntrl +sdmmc1 sdmmc3 spi spi-hv +uart usb0 usb1 usb2 +usb3 usb-bias + +Required pin configuration properties: + - pins: Must contain name of the pad(s) to be configured. + +Optional pin configuration properties: + - low-power-enable: Configure the pad into power down mode + - low-power-disable: Configure the pad into active mode + - power-source: Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 + or TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages. + The values are defined in + include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h. + +Note: The power state can be configured on all of the Tegra124 and + Tegra132 pads. None of the Tegra124 or Tegra132 pads support + signaling voltage switching. + +Note: All of the listed Tegra210 pads except pex-cntrl support power + state configuration. Signaling voltage switching is supported on + following Tegra210 pads: audio, audio-hv, cam, dbg, dmic, gpio, + pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart. + +Pad configuration state example: + pmc: pmc@7000e400 { + compatible = "nvidia,tegra210-pmc"; + reg = <0x0 0x7000e400 0x0 0x400>; + clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>; + clock-names = "pclk", "clk32k_in"; + + ... + + sdmmc1_3v3: sdmmc1-3v3 { + pins = "sdmmc1"; + power-source = ; + }; + + sdmmc1_1v8: sdmmc1-1v8 { + pins = "sdmmc1"; + power-source = ; + }; + + hdmi_off: hdmi-off { + pins = "hdmi"; + low-power-enable; + } + + hdmi_on: hdmi-on { + pins = "hdmi"; + low-power-disable; + } + }; + +Pinctrl client example: + sdmmc1: sdhci@700b0000 { + ... + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; + pinctrl-0 = <&sdmmc1_3v3>; + pinctrl-1 = <&sdmmc1_1v8>; + }; + ... + sor@54540000 { + ... + pinctrl-0 = <&hdmi_off>; + pinctrl-1 = <&hdmi_on>; + pinctrl-names = "hdmi-on", "hdmi-off"; + }; diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h new file mode 100644 index 000000000000..20f43404cac0 --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * pinctrl-tegra-io-pad.h: Tegra I/O pad source voltage configuration constants + * pinctrl bindings. + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Author: Aapo Vienamo + */ + +#ifndef _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H +#define _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H + +/* Voltage levels of the I/O pad's source rail */ +#define TEGRA_IO_PAD_VOLTAGE_1V8 0 +#define TEGRA_IO_PAD_VOLTAGE_3V3 1 + +#endif -- cgit v1.2.3 From 01588646dbce3bf9a79a190f3949677067cc1e20 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 24 Jul 2018 16:47:16 +0100 Subject: dt-bindings: arm: Document RZ/G2M SoC DT bindings Add device tree bindings documentation for Renesas RZ/G2M (r8a774a1) SoC. Signed-off-by: Biju Das Reviewed-by: Chris Paterson Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 89b4a389fbc7..8acd3cd819b3 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -23,6 +23,8 @@ SoCs: compatible = "renesas,r8a7745" - RZ/G1C (R8A77470) compatible = "renesas,r8a77470" + - RZ/G2M (R8A774A1) + compatible = "renesas,r8a774a1" - R-Car M1A (R8A77781) compatible = "renesas,r8a7778" - R-Car H1 (R8A77790) -- cgit v1.2.3 From d0990cd0930c93e06bdf815ce7c350b621e7fd2f Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 27 Jul 2018 11:53:33 -0500 Subject: dt-bindings: arm: Document RZ/A2 SoC DT bindings Add device tree bindings documentation for Renesas RZ/A2 (r7s9210) SoC. Also document new option for "renesas,bsid" Signed-off-by: Chris Brandt Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/shmobile.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 8acd3cd819b3..c0f0a344dfe0 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -7,6 +7,8 @@ SoCs: compatible = "renesas,emev2" - RZ/A1H (R7S72100) compatible = "renesas,r7s72100" + - RZ/A2 (R7S9210) + compatible = "renesas,r7s9210" - SH-Mobile AG5 (R8A73A00/SH73A0) compatible = "renesas,sh73a0" - R-Mobile APE6 (R8A73A40) @@ -145,12 +147,12 @@ Boards: compatible = "renesas,wheat", "renesas,r8a7792" -Most Renesas ARM SoCs have a Product Register that allows to retrieve SoC -product and revision information. If present, a device node for this register -should be added. +Most Renesas ARM SoCs have a Product Register or Boundary Scan ID Register that +allows to retrieve SoC product and revision information. If present, a device +node for this register should be added. Required properties: - - compatible: Must be "renesas,prr". + - compatible: Must be "renesas,prr" or "renesas,bsid" - reg: Base address and length of the register block. -- cgit v1.2.3 From 43bcac2396f7874338016d3c6d86d0bdad8e63e8 Mon Sep 17 00:00:00 2001 From: Eugeniu Rosca Date: Sun, 12 Aug 2018 15:31:43 +0200 Subject: dt-bindings: arm: Document Renesas R-Car M3-N-based ULCB board In harmony with ATF and U-Boot outputs [1] and [2], the new board is based on M3-N revision ES1.1 and the amount of memory present on SiP is 2GiB, contiguously addressed. The amount of RAM is mentioned based on the assumption that it is encoded in the board id/string. There is some evidence supporting this in form of last-digit-mismatch between two R-Car H3 ES2.0 ULCB board ids, one with 4GiB and one with 8GiB of RAM (see [3]). [1] BL2: R-Car Gen3 Initial Program Loader(CA57) Rev.1.0.21 BL2: PRR is R-Car M3N Ver.1.1 [2] U-Boot 2015.04-00295-* CPU: Renesas Electronics R8A77965 rev 1.1 ---8<---- DRAM: 1.9 GiB Bank #0: 0x048000000 - 0x0bfffffff, 1.9 GiB ---8<---- [3] https://patchwork.kernel.org/patch/10555957/#22169325 Signed-off-by: Eugeniu Rosca Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index c0f0a344dfe0..4a03a6b3397e 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -111,6 +111,8 @@ Boards: compatible = "renesas,lager", "renesas,r8a7790" - M3ULCB (R-Car Starter Kit Pro, RTP0RC7796SKBX0010SA09 (M3 ES1.0)) compatible = "renesas,m3ulcb", "renesas,r8a7796" + - M3NULCB (R-Car Starter Kit Pro, RTP0RC77965SKBX010SA00 (M3-N ES1.1)) + compatible = "renesas,m3nulcb", "renesas,r8a77965" - Marzen (R0P7779A00010S) compatible = "renesas,marzen", "renesas,r8a7779" - Porter (M2-LCDP) -- cgit v1.2.3 From 331a53e05b67b40a107e7e2597d22b4f8a2ca0d2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:57:51 +0100 Subject: clk: renesas: cpg-mssr: Add r8a774a1 support Add RZ/G2M (R8A774A1) Clock Pulse Generator / Module Standby and Software Reset support. Based on the Table 8.2b of "RZ/G Series, 2nd Generation User's Manual: Hardware ((Rev. 0.61, June 12, 2018)". Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 9 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774a1-cpg-mssr.c | 323 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/renesas/r8a774a1-cpg-mssr.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index db542abadb75..42d0f83d812b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -16,6 +16,7 @@ Required Properties: - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) + - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) @@ -35,10 +36,10 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7792, - r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, - r8a77980, r8a77990, r8a77995) - - "extalr" (r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) + - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, + r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + r8a77970, r8a77980, r8a77990, r8a77995) + - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 9022bbe1297e..f998a7333acb 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -8,6 +8,7 @@ config CLK_RENESAS select CLK_R8A7743 if ARCH_R8A7743 select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 + select CLK_R8A774A1 if ARCH_R8A774A1 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -67,6 +68,10 @@ config CLK_R8A77470 bool "RZ/G1C clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG +config CLK_R8A774A1 + bool "RZ/G2M clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index e4aa3d6143d2..71d4cafe15c0 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c new file mode 100644 index 000000000000..b0da34217bdf --- /dev/null +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774a1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774A1_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A774A1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A774A1_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), + DEF_FIXED("ztr", R8A774A1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774A1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774A1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774A1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774A1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774A1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774A1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774A1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774A1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774A1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774A1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774A1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774A1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774A1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774A1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774A1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774A1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774A1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("csi0", R8A774A1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774A1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774A1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774A1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774A1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { + DEF_MOD("fdp1-0", 119, R8A774A1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774A1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774A1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774A1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774A1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774A1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774A1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774A1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774A1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774A1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac1", 218, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac0", 219, R8A774A1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774A1_CLK_R), + DEF_MOD("cmt2", 301, R8A774A1_CLK_R), + DEF_MOD("cmt1", 302, R8A774A1_CLK_R), + DEF_MOD("cmt0", 303, R8A774A1_CLK_R), + DEF_MOD("scif2", 310, R8A774A1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774A1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774A1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774A1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774A1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774A1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774A1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774A1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774A1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774A1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774A1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774A1_CLK_S0D3), + DEF_MOD("audmac0", 502, R8A774A1_CLK_S0D3), + DEF_MOD("hscif4", 516, R8A774A1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774A1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774A1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774A1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774A1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774A1_CLK_CP), + DEF_MOD("pwm", 523, R8A774A1_CLK_S0D12), + DEF_MOD("fcpvd2", 601, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd1", 602, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774A1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774A1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774A1_CLK_S0D1), + DEF_MOD("fcpci0", 617, R8A774A1_CLK_S0D2), + DEF_MOD("fcpcs", 619, R8A774A1_CLK_S0D2), + DEF_MOD("vspd2", 621, R8A774A1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774A1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774A1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774A1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774A1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774A1_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A774A1_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A774A1_CLK_S3D4), + DEF_MOD("csi20", 714, R8A774A1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774A1_CLK_CSI0), + DEF_MOD("du2", 722, R8A774A1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774A1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774A1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774A1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774A1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774A1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774A1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774A1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774A1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774A1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774A1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774A1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774A1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774A1_CLK_S0D6), + DEF_MOD("gpio7", 905, R8A774A1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774A1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774A1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774A1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774A1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774A1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774A1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774A1_CLK_S3D4), + DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774A1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774A1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774A1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774A1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774A1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774A1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774A1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774a1_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774a1_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774a1_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774a1_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774a1_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774a1_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774a1_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774a1_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774a1_crit_mod_clks), + + /* Callbacks */ + .init = r8a774a1_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e04338932786..f90b0d0ba46a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -664,6 +664,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77470_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774A1 + { + .compatible = "renesas,r8a774a1-cpg-mssr", + .data = &r8a774a1_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 87bb8f368d4e..2e1730bc5ef2 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -137,6 +137,7 @@ struct cpg_mssr_info { extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; -- cgit v1.2.3 From 851c2509aef6ee2374d8192130f33e1166c1c2a3 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 15 Aug 2018 12:58:13 +0200 Subject: drm/doc: Adapt GPU scheduler references for renamed C file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: "drm/scheduler: rename gpu_scheduler.c to sched_main.c" Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- Documentation/gpu/drm-mm.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 21b6b72a9ba8..d3acb4949e2d 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -505,7 +505,7 @@ GPU Scheduler Overview -------- -.. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler.c +.. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c :doc: Overview Scheduler Function References @@ -514,5 +514,5 @@ Scheduler Function References .. kernel-doc:: include/drm/gpu_scheduler.h :internal: -.. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler.c +.. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c :export: -- cgit v1.2.3 From b33b80710a54bd19f76eff5a327167234a7ee7f8 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 4 Aug 2018 13:10:02 +0200 Subject: dt-bindings: bcm: Add Raspberry Pi CM3 and CM3L This adds the root properties for Raspberry Pi Compute Module 3 and Compute Module 3 Lite. Signed-off-by: Stefan Wahren Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt index 1e3e29a545e2..0dcc3ea5adff 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt @@ -42,6 +42,14 @@ Raspberry Pi Compute Module Required root node properties: compatible = "raspberrypi,compute-module", "brcm,bcm2835"; +Raspberry Pi Compute Module 3 +Required root node properties: +compatible = "raspberrypi,3-compute-module", "brcm,bcm2837"; + +Raspberry Pi Compute Module 3 Lite +Required root node properties: +compatible = "raspberrypi,3-compute-module-lite", "brcm,bcm2837"; + Raspberry Pi Zero Required root node properties: compatible = "raspberrypi,model-zero", "brcm,bcm2835"; -- cgit v1.2.3 From 7473b9aff963007fed591a76b9df0335635c8bcd Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 25 Aug 2018 10:56:17 +0200 Subject: dt-bindings: display: bridge: lvds-transmitter: add ti, ds90c185 Start list of actual chips compatible with "lvds-encoder". Reviewed-by: Laurent Pinchart Reviewed-by: Rob Herring Signed-off-by: Peter Rosin Signed-off-by: Boris Brezillon Link: https://patchwork.freedesktop.org/patch/msgid/20180825085620.10566-2-peda@axentia.se --- .../devicetree/bindings/display/bridge/lvds-transmitter.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-transmitter.txt b/Documentation/devicetree/bindings/display/bridge/lvds-transmitter.txt index fd39ad34c383..50220190c203 100644 --- a/Documentation/devicetree/bindings/display/bridge/lvds-transmitter.txt +++ b/Documentation/devicetree/bindings/display/bridge/lvds-transmitter.txt @@ -22,7 +22,13 @@ among others. Required properties: -- compatible: Must be "lvds-encoder" +- compatible: Must be one or more of the following + - "ti,ds90c185" for the TI DS90C185 FPD-Link Serializer + - "lvds-encoder" for a generic LVDS encoder device + + When compatible with the generic version, nodes must list the + device-specific version corresponding to the device first + followed by the generic version. Required nodes: -- cgit v1.2.3 From 2e7c04aec86758e0adfcad4a24c86593b45807a3 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 25 Aug 2018 10:56:18 +0200 Subject: dt-bindings: display: atmel: optional video-interface of endpoints With bus-type/bus-width properties in the endpoint nodes, the video- interface of the connection can be specified for cases where the heuristic fails to select the correct output mode. This can happen e.g. if not all RGB pins are routed on the PCB; the driver has no way of knowing this, and needs to be told explicitly. This is critical for the devices that have the "conflicting output formats" issue (SAM9N12, SAM9X5, SAMA5D3), since the most significant RGB bits move around depending on the selected output mode. For devices that do not have the "conflicting output formats" issue (SAMA5D2, SAMA5D4), this is completely irrelevant. Acked-by: Boris Brezillon Reviewed-by: Rob Herring Reviewed-by: Jacopo Mondi Signed-off-by: Peter Rosin Signed-off-by: Boris Brezillon Link: https://patchwork.freedesktop.org/patch/msgid/20180825085620.10566-3-peda@axentia.se --- .../devicetree/bindings/display/atmel/hlcdc-dc.txt | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt index 82f2acb3d374..0398aec488ac 100644 --- a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt +++ b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt @@ -15,6 +15,13 @@ Required children nodes: to external devices using the OF graph reprensentation (see ../graph.txt). At least one port node is required. +Optional properties in grandchild nodes: + Any endpoint grandchild node may specify a desired video interface + according to ../../media/video-interfaces.txt, specifically + - bus-width: recognized values are <12>, <16>, <18> and <24>, and + override any output mode selection heuristic, forcing "rgb444", + "rgb565", "rgb666" and "rgb888" respectively. + Example: hlcdc: hlcdc@f0030000 { @@ -50,3 +57,19 @@ Example: #pwm-cells = <3>; }; }; + +Example 2: With a video interface override to force rgb565; as above +but with these changes/additions: + + &hlcdc { + hlcdc-display-controller { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb565>; + + port@0 { + hlcdc_panel_output: endpoint@0 { + bus-width = <16>; + }; + }; + }; + }; -- cgit v1.2.3 From 79a79c3a0ec2043711577750d4499abf4155d216 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 28 Aug 2018 13:22:10 -0700 Subject: Documentation: dt: keystone: ti-sci: Add optional host-id parameter Texas Instrument's System Control Interface (TISCI) permits the ability for OSs running in virtual machines to be able to independently communicate with the firmware without the need going through an hypervisor. The "host-id" in effect is the hardware representation of the host (example: VMs locked to a core) as identified to the System Controller. Hypervisors can either fill in appropriate host-ids in dt used for each VM instance OR may use prebuilt blobs where the host-ids are pre-populated, as appropriate for the OS running in the VMs. This is introduced as an optional parameter to maintain consistency with legacy device tree blobs. Reviewed-by: Rob Herring Signed-off-by: Nishanth Menon Signed-off-by: Santosh Shilimkar --- Documentation/devicetree/bindings/arm/keystone/ti,sci.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt index 31f5f9a104cc..b56a02c10ae6 100644 --- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt +++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt @@ -45,11 +45,15 @@ Optional Properties: debug_messages - Map the Debug message region - reg: register space corresponding to the debug_messages - ti,system-reboot-controller: If system reboot can be triggered by SoC reboot +- ti,host-id: Integer value corresponding to the host ID assigned by Firmware + for identification of host processing entities such as virtual + machines Example (K2G): ------------- pmmc: pmmc { compatible = "ti,k2g-sci"; + ti,host-id = <2>; mbox-names = "rx", "tx"; mboxes= <&msgmgr &msgmgr_proxy_pmmc_rx>, <&msgmgr &msgmgr_proxy_pmmc_tx>; -- cgit v1.2.3 From e0b35c1ab5ac5f0453d1093770e119bd8d63d85c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 24 Jul 2018 18:49:46 +0200 Subject: ARM: exynos: Fix imprecise abort during Exynos5422 suspend to RAM Suspend to RAM on Odroid XU3/XU4/HC1 family (Exynos5422) causes imprecise abort: PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.003 seconds) done. OOM killer disabled. Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done. wake enabled for irq 139 Disabling non-boot CPUs ... IRQ51 no longer affine to CPU1 IRQ52 no longer affine to CPU2 IRQ53 no longer affine to CPU3 IRQ54 no longer affine to CPU4 IRQ55 no longer affine to CPU5 IRQ56 no longer affine to CPU6 cpu cpu4: Dropping the link to regulator.40 IRQ57 no longer affine to CPU7 Unhandled fault: external abort on non-linefetch (0x1008) at 0xf081a028 Internal error: : 1008 [#1] PREEMPT SMP ARM with last call trace in exynos_suspend_enter(). The abort is caused by writing to register in secure part of sysram. Boards booted under secure firmware (e.g. Hardkernel Odroid boards) should access non-secure sysram. Signed-off-by: Krzysztof Kozlowski --- Documentation/arm/Samsung/Bootloader-interface.txt | 1 + arch/arm/mach-exynos/common.h | 1 + arch/arm/mach-exynos/firmware.c | 14 +++++++++++--- arch/arm/mach-exynos/suspend.c | 16 +++++++++++++--- 4 files changed, 26 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/arm/Samsung/Bootloader-interface.txt b/Documentation/arm/Samsung/Bootloader-interface.txt index ed494ac0beb2..d17ed518a7ea 100644 --- a/Documentation/arm/Samsung/Bootloader-interface.txt +++ b/Documentation/arm/Samsung/Bootloader-interface.txt @@ -26,6 +26,7 @@ Offset Value Purpose 0x20 0xfcba0d10 (Magic cookie) AFTR 0x24 exynos_cpu_resume_ns AFTR 0x28 + 4*cpu 0x8 (Magic cookie, Exynos3250) AFTR +0x28 0x0 or last value during resume (Exynos542x) System suspend 2. Secure mode diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index dcd21bb95e3b..f96730cce6e8 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -110,6 +110,7 @@ void exynos_firmware_init(void); #define EXYNOS_SLEEP_MAGIC 0x00000bad #define EXYNOS_AFTR_MAGIC 0xfcba0d10 +bool __init exynos_secure_firmware_available(void); void exynos_set_boot_flag(unsigned int cpu, unsigned int mode); void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode); diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index be1f20fe28f4..d602e3bf3f96 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c @@ -185,7 +185,7 @@ static void exynos_l2_configure(const struct l2x0_regs *regs) exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0); } -void __init exynos_firmware_init(void) +bool __init exynos_secure_firmware_available(void) { struct device_node *nd; const __be32 *addr; @@ -193,14 +193,22 @@ void __init exynos_firmware_init(void) nd = of_find_compatible_node(NULL, NULL, "samsung,secure-firmware"); if (!nd) - return; + return false; addr = of_get_address(nd, 0, NULL, NULL); if (!addr) { pr_err("%s: No address specified.\n", __func__); - return; + return false; } + return true; +} + +void __init exynos_firmware_init(void) +{ + if (!exynos_secure_firmware_available()) + return; + pr_info("Running under secure firmware.\n"); register_firmware_ops(&exynos_firmware_ops); diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 700d8d91ea93..bb8e3985acdb 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -63,6 +63,7 @@ struct exynos_pm_data { struct exynos_pm_state { int cpu_state; unsigned int pmu_spare3; + void __iomem *sysram_base; }; static const struct exynos_pm_data *pm_data __ro_after_init; @@ -261,7 +262,7 @@ static int exynos5420_cpu_suspend(unsigned long arg) unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - writel_relaxed(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE); + writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE); if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) { mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume); @@ -333,7 +334,7 @@ static void exynos5420_pm_prepare(void) * needs to restore it back in case, the primary cpu fails to * suspend for any reason. */ - pm_state.cpu_state = readl_relaxed(sysram_base_addr + + pm_state.cpu_state = readl_relaxed(pm_state.sysram_base + EXYNOS5420_CPU_STATE); exynos_pm_enter_sleep_mode(); @@ -453,7 +454,7 @@ static void exynos5420_pm_resume(void) /* Restore the sysram cpu state register */ writel_relaxed(pm_state.cpu_state, - sysram_base_addr + EXYNOS5420_CPU_STATE); + pm_state.sysram_base + EXYNOS5420_CPU_STATE); pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); @@ -658,4 +659,13 @@ void __init exynos_pm_init(void) register_syscore_ops(&exynos_pm_syscore_ops); suspend_set_ops(&exynos_suspend_ops); + + /* + * Applicable as of now only to Exynos542x. If booted under secure + * firmware, the non-secure region of sysram should be used. + */ + if (exynos_secure_firmware_available()) + pm_state.sysram_base = sysram_ns_base_addr; + else + pm_state.sysram_base = sysram_base_addr; } -- cgit v1.2.3 From f40c467523cb5dd352e669a8bab2411b31db089e Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Mon, 23 Jul 2018 16:56:32 +0530 Subject: dt-bindings: clock: Introduce QCOM Camera clock bindings Add device tree bindings for camera clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,camcc.txt | 18 ++++ include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 +++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt b/Documentation/devicetree/bindings/clock/qcom,camcc.txt new file mode 100644 index 000000000000..c5eb6694fda9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt @@ -0,0 +1,18 @@ +Qualcomm Camera Clock & Reset Controller Binding +------------------------------------------------ + +Required properties : +- compatible : shall contain "qcom,sdm845-camcc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + camcc: clock-controller@ad00000 { + compatible = "qcom,sdm845-camcc"; + reg = <0xad00000 0x10000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h b/include/dt-bindings/clock/qcom,camcc-sdm845.h new file mode 100644 index 000000000000..4f7a2d2320bf --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H + +/* CAM_CC clock registers */ +#define CAM_CC_BPS_AHB_CLK 0 +#define CAM_CC_BPS_AREG_CLK 1 +#define CAM_CC_BPS_AXI_CLK 2 +#define CAM_CC_BPS_CLK 3 +#define CAM_CC_BPS_CLK_SRC 4 +#define CAM_CC_CAMNOC_ATB_CLK 5 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_CLK 7 +#define CAM_CC_CCI_CLK_SRC 8 +#define CAM_CC_CPAS_AHB_CLK 9 +#define CAM_CC_CPHY_RX_CLK_SRC 10 +#define CAM_CC_CSI0PHYTIMER_CLK 11 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 12 +#define CAM_CC_CSI1PHYTIMER_CLK 13 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 14 +#define CAM_CC_CSI2PHYTIMER_CLK 15 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 16 +#define CAM_CC_CSI3PHYTIMER_CLK 17 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 18 +#define CAM_CC_CSIPHY0_CLK 19 +#define CAM_CC_CSIPHY1_CLK 20 +#define CAM_CC_CSIPHY2_CLK 21 +#define CAM_CC_CSIPHY3_CLK 22 +#define CAM_CC_FAST_AHB_CLK_SRC 23 +#define CAM_CC_FD_CORE_CLK 24 +#define CAM_CC_FD_CORE_CLK_SRC 25 +#define CAM_CC_FD_CORE_UAR_CLK 26 +#define CAM_CC_ICP_APB_CLK 27 +#define CAM_CC_ICP_ATB_CLK 28 +#define CAM_CC_ICP_CLK 29 +#define CAM_CC_ICP_CLK_SRC 30 +#define CAM_CC_ICP_CTI_CLK 31 +#define CAM_CC_ICP_TS_CLK 32 +#define CAM_CC_IFE_0_AXI_CLK 33 +#define CAM_CC_IFE_0_CLK 34 +#define CAM_CC_IFE_0_CLK_SRC 35 +#define CAM_CC_IFE_0_CPHY_RX_CLK 36 +#define CAM_CC_IFE_0_CSID_CLK 37 +#define CAM_CC_IFE_0_CSID_CLK_SRC 38 +#define CAM_CC_IFE_0_DSP_CLK 39 +#define CAM_CC_IFE_1_AXI_CLK 40 +#define CAM_CC_IFE_1_CLK 41 +#define CAM_CC_IFE_1_CLK_SRC 42 +#define CAM_CC_IFE_1_CPHY_RX_CLK 43 +#define CAM_CC_IFE_1_CSID_CLK 44 +#define CAM_CC_IFE_1_CSID_CLK_SRC 45 +#define CAM_CC_IFE_1_DSP_CLK 46 +#define CAM_CC_IFE_LITE_CLK 47 +#define CAM_CC_IFE_LITE_CLK_SRC 48 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 49 +#define CAM_CC_IFE_LITE_CSID_CLK 50 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 51 +#define CAM_CC_IPE_0_AHB_CLK 52 +#define CAM_CC_IPE_0_AREG_CLK 53 +#define CAM_CC_IPE_0_AXI_CLK 54 +#define CAM_CC_IPE_0_CLK 55 +#define CAM_CC_IPE_0_CLK_SRC 56 +#define CAM_CC_IPE_1_AHB_CLK 57 +#define CAM_CC_IPE_1_AREG_CLK 58 +#define CAM_CC_IPE_1_AXI_CLK 59 +#define CAM_CC_IPE_1_CLK 60 +#define CAM_CC_IPE_1_CLK_SRC 61 +#define CAM_CC_JPEG_CLK 62 +#define CAM_CC_JPEG_CLK_SRC 63 +#define CAM_CC_LRME_CLK 64 +#define CAM_CC_LRME_CLK_SRC 65 +#define CAM_CC_MCLK0_CLK 66 +#define CAM_CC_MCLK0_CLK_SRC 67 +#define CAM_CC_MCLK1_CLK 68 +#define CAM_CC_MCLK1_CLK_SRC 69 +#define CAM_CC_MCLK2_CLK 70 +#define CAM_CC_MCLK2_CLK_SRC 71 +#define CAM_CC_MCLK3_CLK 72 +#define CAM_CC_MCLK3_CLK_SRC 73 +#define CAM_CC_PLL0 74 +#define CAM_CC_PLL0_OUT_EVEN 75 +#define CAM_CC_PLL1 76 +#define CAM_CC_PLL1_OUT_EVEN 77 +#define CAM_CC_PLL2 78 +#define CAM_CC_PLL2_OUT_EVEN 79 +#define CAM_CC_PLL3 80 +#define CAM_CC_PLL3_OUT_EVEN 81 +#define CAM_CC_SLOW_AHB_CLK_SRC 82 +#define CAM_CC_SOC_AHB_CLK 83 +#define CAM_CC_SYS_TMR_CLK 84 + +/* CAM_CC Resets */ +#define TITAN_CAM_CC_CCI_BCR 0 +#define TITAN_CAM_CC_CPAS_BCR 1 +#define TITAN_CAM_CC_CSI0PHY_BCR 2 +#define TITAN_CAM_CC_CSI1PHY_BCR 3 +#define TITAN_CAM_CC_CSI2PHY_BCR 4 +#define TITAN_CAM_CC_MCLK0_BCR 5 +#define TITAN_CAM_CC_MCLK1_BCR 6 +#define TITAN_CAM_CC_MCLK2_BCR 7 +#define TITAN_CAM_CC_MCLK3_BCR 8 +#define TITAN_CAM_CC_TITAN_TOP_BCR 9 + +/* CAM_CC GDSCRs */ +#define BPS_GDSC 0 +#define IPE_0_GDSC 1 +#define IPE_1_GDSC 2 +#define IFE_0_GDSC 3 +#define IFE_1_GDSC 4 +#define TITAN_TOP_GDSC 5 + +#endif -- cgit v1.2.3 From 21abebf06dc97721238b77cf03d0be8c839a3898 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 21 Aug 2018 02:53:34 -0400 Subject: media: vicodec: rename and use proper fwht prefix for codec The codec source is generic and not vicodec specific. It can be used by other drivers or userspace as well. So rename the source and header to something more generic (codec-fwht.c/h) and prefix the defines, types and functions with fwht_. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-compressed.rst | 2 +- drivers/media/platform/vicodec/Makefile | 2 +- drivers/media/platform/vicodec/codec-fwht.c | 849 +++++++++++++++++++++ drivers/media/platform/vicodec/codec-fwht.h | 125 +++ drivers/media/platform/vicodec/vicodec-codec.c | 835 -------------------- drivers/media/platform/vicodec/vicodec-codec.h | 136 ---- drivers/media/platform/vicodec/vicodec-core.c | 89 +-- 7 files changed, 1021 insertions(+), 1017 deletions(-) create mode 100644 drivers/media/platform/vicodec/codec-fwht.c create mode 100644 drivers/media/platform/vicodec/codec-fwht.h delete mode 100644 drivers/media/platform/vicodec/vicodec-codec.c delete mode 100644 drivers/media/platform/vicodec/vicodec-codec.h (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst index d382e7a5c38e..d04b18adac33 100644 --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst @@ -101,4 +101,4 @@ Compressed Formats - 'FWHT' - Video elementary stream using a codec based on the Fast Walsh Hadamard Transform. This codec is implemented by the vicodec ('Virtual Codec') - driver. See the vicodec-codec.h header for more details. + driver. See the codec-fwht.h header for more details. diff --git a/drivers/media/platform/vicodec/Makefile b/drivers/media/platform/vicodec/Makefile index 197229428953..a27242ff14ad 100644 --- a/drivers/media/platform/vicodec/Makefile +++ b/drivers/media/platform/vicodec/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -vicodec-objs := vicodec-core.o vicodec-codec.o +vicodec-objs := vicodec-core.o codec-fwht.o obj-$(CONFIG_VIDEO_VICODEC) += vicodec.o diff --git a/drivers/media/platform/vicodec/codec-fwht.c b/drivers/media/platform/vicodec/codec-fwht.c new file mode 100644 index 000000000000..f91f90f7e5fc --- /dev/null +++ b/drivers/media/platform/vicodec/codec-fwht.c @@ -0,0 +1,849 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2016 Tom aan de Wiel + * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper: + * + * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms, + * R.D. Brown, 1977 + */ + +#include +#include "codec-fwht.h" + +/* + * Note: bit 0 of the header must always be 0. Otherwise it cannot + * be guaranteed that the magic 8 byte sequence (see below) can + * never occur in the rlc output. + */ +#define PFRAME_BIT BIT(15) +#define DUPS_MASK 0x1ffe + +#define PBLOCK 0 +#define IBLOCK 1 + +#define ALL_ZEROS 15 + +static const uint8_t zigzag[64] = { + 0, + 1, 8, + 2, 9, 16, + 3, 10, 17, 24, + 4, 11, 18, 25, 32, + 5, 12, 19, 26, 33, 40, + 6, 13, 20, 27, 34, 41, 48, + 7, 14, 21, 28, 35, 42, 49, 56, + 15, 22, 29, 36, 43, 50, 57, + 23, 30, 37, 44, 51, 58, + 31, 38, 45, 52, 59, + 39, 46, 53, 60, + 47, 54, 61, + 55, 62, + 63, +}; + + +static int rlc(const s16 *in, __be16 *output, int blocktype) +{ + s16 block[8 * 8]; + s16 *wp = block; + int i = 0; + int x, y; + int ret = 0; + + /* read in block from framebuffer */ + int lastzero_run = 0; + int to_encode; + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + *wp = in[x + y * 8]; + wp++; + } + } + + /* keep track of amount of trailing zeros */ + for (i = 63; i >= 0 && !block[zigzag[i]]; i--) + lastzero_run++; + + *output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0); + ret++; + + to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0); + + i = 0; + while (i < to_encode) { + int cnt = 0; + int tmp; + + /* count leading zeros */ + while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) { + cnt++; + i++; + if (i == to_encode) { + cnt--; + break; + } + } + /* 4 bits for run, 12 for coefficient (quantization by 4) */ + *output++ = htons((cnt | tmp << 4)); + i++; + ret++; + } + if (lastzero_run > 14) { + *output = htons(ALL_ZEROS | 0); + ret++; + } + + return ret; +} + +/* + * This function will worst-case increase rlc_in by 65*2 bytes: + * one s16 value for the header and 8 * 8 coefficients of type s16. + */ +static s16 derlc(const __be16 **rlc_in, s16 *dwht_out) +{ + /* header */ + const __be16 *input = *rlc_in; + s16 ret = ntohs(*input++); + int dec_count = 0; + s16 block[8 * 8 + 16]; + s16 *wp = block; + int i; + + /* + * Now de-compress, it expands one byte to up to 15 bytes + * (or fills the remainder of the 64 bytes with zeroes if it + * is the last byte to expand). + * + * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to + * allow for overflow if the incoming data was malformed. + */ + while (dec_count < 8 * 8) { + s16 in = ntohs(*input++); + int length = in & 0xf; + int coeff = in >> 4; + + /* fill remainder with zeros */ + if (length == 15) { + for (i = 0; i < 64 - dec_count; i++) + *wp++ = 0; + break; + } + + for (i = 0; i < length; i++) + *wp++ = 0; + *wp++ = coeff; + dec_count += length + 1; + } + + wp = block; + + for (i = 0; i < 64; i++) { + int pos = zigzag[i]; + int y = pos / 8; + int x = pos % 8; + + dwht_out[x + y * 8] = *wp++; + } + *rlc_in = input; + return ret; +} + +static const int quant_table[] = { + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, + 2, 2, 2, 2, 2, 2, 3, 6, + 2, 2, 2, 2, 2, 3, 6, 6, + 2, 2, 2, 2, 3, 6, 6, 6, + 2, 2, 2, 3, 6, 6, 6, 6, + 2, 2, 3, 6, 6, 6, 6, 8, +}; + +static const int quant_table_p[] = { + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 6, + 3, 3, 3, 3, 3, 3, 6, 6, + 3, 3, 3, 3, 3, 6, 6, 9, + 3, 3, 3, 3, 6, 6, 9, 9, + 3, 3, 3, 6, 6, 9, 9, 10, +}; + +static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp) +{ + const int *quant = quant_table; + int i, j; + + for (j = 0; j < 8; j++) { + for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { + *coeff >>= *quant; + if (*coeff >= -qp && *coeff <= qp) + *coeff = *de_coeff = 0; + else + *de_coeff = *coeff << *quant; + } + } +} + +static void dequantize_intra(s16 *coeff) +{ + const int *quant = quant_table; + int i, j; + + for (j = 0; j < 8; j++) + for (i = 0; i < 8; i++, quant++, coeff++) + *coeff <<= *quant; +} + +static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp) +{ + const int *quant = quant_table_p; + int i, j; + + for (j = 0; j < 8; j++) { + for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { + *coeff >>= *quant; + if (*coeff >= -qp && *coeff <= qp) + *coeff = *de_coeff = 0; + else + *de_coeff = *coeff << *quant; + } + } +} + +static void dequantize_inter(s16 *coeff) +{ + const int *quant = quant_table_p; + int i, j; + + for (j = 0; j < 8; j++) + for (i = 0; i < 8; i++, quant++, coeff++) + *coeff <<= *quant; +} + +static void fwht(const u8 *block, s16 *output_block, unsigned int stride, + unsigned int input_step, bool intra) +{ + /* we'll need more than 8 bits for the transformed coefficients */ + s32 workspace1[8], workspace2[8]; + const u8 *tmp = block; + s16 *out = output_block; + int add = intra ? 256 : 0; + unsigned int i; + + /* stage 1 */ + stride *= input_step; + + for (i = 0; i < 8; i++, tmp += stride, out += 8) { + switch (input_step) { + case 1: + workspace1[0] = tmp[0] + tmp[1] - add; + workspace1[1] = tmp[0] - tmp[1]; + + workspace1[2] = tmp[2] + tmp[3] - add; + workspace1[3] = tmp[2] - tmp[3]; + + workspace1[4] = tmp[4] + tmp[5] - add; + workspace1[5] = tmp[4] - tmp[5]; + + workspace1[6] = tmp[6] + tmp[7] - add; + workspace1[7] = tmp[6] - tmp[7]; + break; + case 2: + workspace1[0] = tmp[0] + tmp[2] - add; + workspace1[1] = tmp[0] - tmp[2]; + + workspace1[2] = tmp[4] + tmp[6] - add; + workspace1[3] = tmp[4] - tmp[6]; + + workspace1[4] = tmp[8] + tmp[10] - add; + workspace1[5] = tmp[8] - tmp[10]; + + workspace1[6] = tmp[12] + tmp[14] - add; + workspace1[7] = tmp[12] - tmp[14]; + break; + case 3: + workspace1[0] = tmp[0] + tmp[3] - add; + workspace1[1] = tmp[0] - tmp[3]; + + workspace1[2] = tmp[6] + tmp[9] - add; + workspace1[3] = tmp[6] - tmp[9]; + + workspace1[4] = tmp[12] + tmp[15] - add; + workspace1[5] = tmp[12] - tmp[15]; + + workspace1[6] = tmp[18] + tmp[21] - add; + workspace1[7] = tmp[18] - tmp[21]; + break; + default: + workspace1[0] = tmp[0] + tmp[4] - add; + workspace1[1] = tmp[0] - tmp[4]; + + workspace1[2] = tmp[8] + tmp[12] - add; + workspace1[3] = tmp[8] - tmp[12]; + + workspace1[4] = tmp[16] + tmp[20] - add; + workspace1[5] = tmp[16] - tmp[20]; + + workspace1[6] = tmp[24] + tmp[28] - add; + workspace1[7] = tmp[24] - tmp[28]; + break; + } + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + + /* stage 3 */ + out[0] = workspace2[0] + workspace2[4]; + out[1] = workspace2[0] - workspace2[4]; + out[2] = workspace2[1] - workspace2[5]; + out[3] = workspace2[1] + workspace2[5]; + out[4] = workspace2[2] + workspace2[6]; + out[5] = workspace2[2] - workspace2[6]; + out[6] = workspace2[3] - workspace2[7]; + out[7] = workspace2[3] + workspace2[7]; + } + + out = output_block; + + for (i = 0; i < 8; i++, out++) { + /* stage 1 */ + workspace1[0] = out[0] + out[1 * 8]; + workspace1[1] = out[0] - out[1 * 8]; + + workspace1[2] = out[2 * 8] + out[3 * 8]; + workspace1[3] = out[2 * 8] - out[3 * 8]; + + workspace1[4] = out[4 * 8] + out[5 * 8]; + workspace1[5] = out[4 * 8] - out[5 * 8]; + + workspace1[6] = out[6 * 8] + out[7 * 8]; + workspace1[7] = out[6 * 8] - out[7 * 8]; + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + /* stage 3 */ + out[0 * 8] = workspace2[0] + workspace2[4]; + out[1 * 8] = workspace2[0] - workspace2[4]; + out[2 * 8] = workspace2[1] - workspace2[5]; + out[3 * 8] = workspace2[1] + workspace2[5]; + out[4 * 8] = workspace2[2] + workspace2[6]; + out[5 * 8] = workspace2[2] - workspace2[6]; + out[6 * 8] = workspace2[3] - workspace2[7]; + out[7 * 8] = workspace2[3] + workspace2[7]; + } +} + +/* + * Not the nicest way of doing it, but P-blocks get twice the range of + * that of the I-blocks. Therefore we need a type bigger than 8 bits. + * Furthermore values can be negative... This is just a version that + * works with 16 signed data + */ +static void fwht16(const s16 *block, s16 *output_block, int stride, int intra) +{ + /* we'll need more than 8 bits for the transformed coefficients */ + s32 workspace1[8], workspace2[8]; + const s16 *tmp = block; + s16 *out = output_block; + int i; + + for (i = 0; i < 8; i++, tmp += stride, out += 8) { + /* stage 1 */ + workspace1[0] = tmp[0] + tmp[1]; + workspace1[1] = tmp[0] - tmp[1]; + + workspace1[2] = tmp[2] + tmp[3]; + workspace1[3] = tmp[2] - tmp[3]; + + workspace1[4] = tmp[4] + tmp[5]; + workspace1[5] = tmp[4] - tmp[5]; + + workspace1[6] = tmp[6] + tmp[7]; + workspace1[7] = tmp[6] - tmp[7]; + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + + /* stage 3 */ + out[0] = workspace2[0] + workspace2[4]; + out[1] = workspace2[0] - workspace2[4]; + out[2] = workspace2[1] - workspace2[5]; + out[3] = workspace2[1] + workspace2[5]; + out[4] = workspace2[2] + workspace2[6]; + out[5] = workspace2[2] - workspace2[6]; + out[6] = workspace2[3] - workspace2[7]; + out[7] = workspace2[3] + workspace2[7]; + } + + out = output_block; + + for (i = 0; i < 8; i++, out++) { + /* stage 1 */ + workspace1[0] = out[0] + out[1*8]; + workspace1[1] = out[0] - out[1*8]; + + workspace1[2] = out[2*8] + out[3*8]; + workspace1[3] = out[2*8] - out[3*8]; + + workspace1[4] = out[4*8] + out[5*8]; + workspace1[5] = out[4*8] - out[5*8]; + + workspace1[6] = out[6*8] + out[7*8]; + workspace1[7] = out[6*8] - out[7*8]; + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + + /* stage 3 */ + out[0*8] = workspace2[0] + workspace2[4]; + out[1*8] = workspace2[0] - workspace2[4]; + out[2*8] = workspace2[1] - workspace2[5]; + out[3*8] = workspace2[1] + workspace2[5]; + out[4*8] = workspace2[2] + workspace2[6]; + out[5*8] = workspace2[2] - workspace2[6]; + out[6*8] = workspace2[3] - workspace2[7]; + out[7*8] = workspace2[3] + workspace2[7]; + } +} + +static void ifwht(const s16 *block, s16 *output_block, int intra) +{ + /* + * we'll need more than 8 bits for the transformed coefficients + * use native unit of cpu + */ + int workspace1[8], workspace2[8]; + int inter = intra ? 0 : 1; + const s16 *tmp = block; + s16 *out = output_block; + int i; + + for (i = 0; i < 8; i++, tmp += 8, out += 8) { + /* stage 1 */ + workspace1[0] = tmp[0] + tmp[1]; + workspace1[1] = tmp[0] - tmp[1]; + + workspace1[2] = tmp[2] + tmp[3]; + workspace1[3] = tmp[2] - tmp[3]; + + workspace1[4] = tmp[4] + tmp[5]; + workspace1[5] = tmp[4] - tmp[5]; + + workspace1[6] = tmp[6] + tmp[7]; + workspace1[7] = tmp[6] - tmp[7]; + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + + /* stage 3 */ + out[0] = workspace2[0] + workspace2[4]; + out[1] = workspace2[0] - workspace2[4]; + out[2] = workspace2[1] - workspace2[5]; + out[3] = workspace2[1] + workspace2[5]; + out[4] = workspace2[2] + workspace2[6]; + out[5] = workspace2[2] - workspace2[6]; + out[6] = workspace2[3] - workspace2[7]; + out[7] = workspace2[3] + workspace2[7]; + } + + out = output_block; + + for (i = 0; i < 8; i++, out++) { + /* stage 1 */ + workspace1[0] = out[0] + out[1 * 8]; + workspace1[1] = out[0] - out[1 * 8]; + + workspace1[2] = out[2 * 8] + out[3 * 8]; + workspace1[3] = out[2 * 8] - out[3 * 8]; + + workspace1[4] = out[4 * 8] + out[5 * 8]; + workspace1[5] = out[4 * 8] - out[5 * 8]; + + workspace1[6] = out[6 * 8] + out[7 * 8]; + workspace1[7] = out[6 * 8] - out[7 * 8]; + + /* stage 2 */ + workspace2[0] = workspace1[0] + workspace1[2]; + workspace2[1] = workspace1[0] - workspace1[2]; + workspace2[2] = workspace1[1] - workspace1[3]; + workspace2[3] = workspace1[1] + workspace1[3]; + + workspace2[4] = workspace1[4] + workspace1[6]; + workspace2[5] = workspace1[4] - workspace1[6]; + workspace2[6] = workspace1[5] - workspace1[7]; + workspace2[7] = workspace1[5] + workspace1[7]; + + /* stage 3 */ + if (inter) { + int d; + + out[0 * 8] = workspace2[0] + workspace2[4]; + out[1 * 8] = workspace2[0] - workspace2[4]; + out[2 * 8] = workspace2[1] - workspace2[5]; + out[3 * 8] = workspace2[1] + workspace2[5]; + out[4 * 8] = workspace2[2] + workspace2[6]; + out[5 * 8] = workspace2[2] - workspace2[6]; + out[6 * 8] = workspace2[3] - workspace2[7]; + out[7 * 8] = workspace2[3] + workspace2[7]; + + for (d = 0; d < 8; d++) + out[8 * d] >>= 6; + } else { + int d; + + out[0 * 8] = workspace2[0] + workspace2[4]; + out[1 * 8] = workspace2[0] - workspace2[4]; + out[2 * 8] = workspace2[1] - workspace2[5]; + out[3 * 8] = workspace2[1] + workspace2[5]; + out[4 * 8] = workspace2[2] + workspace2[6]; + out[5 * 8] = workspace2[2] - workspace2[6]; + out[6 * 8] = workspace2[3] - workspace2[7]; + out[7 * 8] = workspace2[3] + workspace2[7]; + + for (d = 0; d < 8; d++) { + out[8 * d] >>= 6; + out[8 * d] += 128; + } + } + } +} + +static void fill_encoder_block(const u8 *input, s16 *dst, + unsigned int stride, unsigned int input_step) +{ + int i, j; + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++, input += input_step) + *dst++ = *input; + input += (stride - 8) * input_step; + } +} + +static int var_intra(const s16 *input) +{ + int32_t mean = 0; + int32_t ret = 0; + const s16 *tmp = input; + int i; + + for (i = 0; i < 8 * 8; i++, tmp++) + mean += *tmp; + mean /= 64; + tmp = input; + for (i = 0; i < 8 * 8; i++, tmp++) + ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean); + return ret; +} + +static int var_inter(const s16 *old, const s16 *new) +{ + int32_t ret = 0; + int i; + + for (i = 0; i < 8 * 8; i++, old++, new++) + ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new); + return ret; +} + +static int decide_blocktype(const u8 *cur, const u8 *reference, + s16 *deltablock, unsigned int stride, + unsigned int input_step) +{ + s16 tmp[64]; + s16 old[64]; + s16 *work = tmp; + unsigned int k, l; + int vari; + int vard; + + fill_encoder_block(cur, tmp, stride, input_step); + fill_encoder_block(reference, old, 8, 1); + vari = var_intra(tmp); + + for (k = 0; k < 8; k++) { + for (l = 0; l < 8; l++) { + *deltablock = *work - *reference; + deltablock++; + work++; + reference++; + } + } + deltablock -= 64; + vard = var_inter(old, tmp); + return vari <= vard ? IBLOCK : PBLOCK; +} + +static void fill_decoder_block(u8 *dst, const s16 *input, int stride) +{ + int i, j; + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) + *dst++ = *input++; + dst += stride - 8; + } +} + +static void add_deltas(s16 *deltas, const u8 *ref, int stride) +{ + int k, l; + + for (k = 0; k < 8; k++) { + for (l = 0; l < 8; l++) { + *deltas += *ref++; + /* + * Due to quantizing, it might possible that the + * decoded coefficients are slightly out of range + */ + if (*deltas < 0) + *deltas = 0; + else if (*deltas > 255) + *deltas = 255; + deltas++; + } + ref += stride - 8; + } +} + +static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, + struct fwht_cframe *cf, u32 height, u32 width, + unsigned int input_step, + bool is_intra, bool next_is_intra) +{ + u8 *input_start = input; + __be16 *rlco_start = *rlco; + s16 deltablock[64]; + __be16 pframe_bit = htons(PFRAME_BIT); + u32 encoding = 0; + unsigned int last_size = 0; + unsigned int i, j; + + for (j = 0; j < height / 8; j++) { + for (i = 0; i < width / 8; i++) { + /* intra code, first frame is always intra coded. */ + int blocktype = IBLOCK; + unsigned int size; + + if (!is_intra) + blocktype = decide_blocktype(input, refp, + deltablock, width, input_step); + if (blocktype == IBLOCK) { + fwht(input, cf->coeffs, width, input_step, 1); + quantize_intra(cf->coeffs, cf->de_coeffs, + cf->i_frame_qp); + } else { + /* inter code */ + encoding |= FWHT_FRAME_PCODED; + fwht16(deltablock, cf->coeffs, 8, 0); + quantize_inter(cf->coeffs, cf->de_coeffs, + cf->p_frame_qp); + } + if (!next_is_intra) { + ifwht(cf->de_coeffs, cf->de_fwht, blocktype); + + if (blocktype == PBLOCK) + add_deltas(cf->de_fwht, refp, 8); + fill_decoder_block(refp, cf->de_fwht, 8); + } + + input += 8 * input_step; + refp += 8 * 8; + + size = rlc(cf->coeffs, *rlco, blocktype); + if (last_size == size && + !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) { + __be16 *last_rlco = *rlco - size; + s16 hdr = ntohs(*last_rlco); + + if (!((*last_rlco ^ **rlco) & pframe_bit) && + (hdr & DUPS_MASK) < DUPS_MASK) + *last_rlco = htons(hdr + 2); + else + *rlco += size; + } else { + *rlco += size; + } + if (*rlco >= rlco_max) { + encoding |= FWHT_FRAME_UNENCODED; + goto exit_loop; + } + last_size = size; + } + input += width * 7 * input_step; + } + +exit_loop: + if (encoding & FWHT_FRAME_UNENCODED) { + u8 *out = (u8 *)rlco_start; + + input = input_start; + /* + * The compressed stream should never contain the magic + * header, so when we copy the YUV data we replace 0xff + * by 0xfe. Since YUV is limited range such values + * shouldn't appear anyway. + */ + for (i = 0; i < height * width; i++, input += input_step) + *out++ = (*input == 0xff) ? 0xfe : *input; + *rlco = (__be16 *)out; + encoding &= ~FWHT_FRAME_PCODED; + } + return encoding; +} + +u32 fwht_encode_frame(struct fwht_raw_frame *frm, + struct fwht_raw_frame *ref_frm, + struct fwht_cframe *cf, + bool is_intra, bool next_is_intra) +{ + unsigned int size = frm->height * frm->width; + __be16 *rlco = cf->rlc_data; + __be16 *rlco_max; + u32 encoding; + u32 chroma_h = frm->height / frm->height_div; + u32 chroma_w = frm->width / frm->width_div; + unsigned int chroma_size = chroma_h * chroma_w; + + rlco_max = rlco + size / 2 - 256; + encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf, + frm->height, frm->width, + frm->luma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_LUMA_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + rlco_max = rlco + chroma_size / 2 - 256; + encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf, + chroma_h, chroma_w, + frm->chroma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CB_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + rlco_max = rlco + chroma_size / 2 - 256; + encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf, + chroma_h, chroma_w, + frm->chroma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CR_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + cf->size = (rlco - cf->rlc_data) * sizeof(*rlco); + return encoding; +} + +static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, + u32 height, u32 width, bool uncompressed) +{ + unsigned int copies = 0; + s16 copy[8 * 8]; + s16 stat; + unsigned int i, j; + + if (uncompressed) { + memcpy(ref, *rlco, width * height); + *rlco += width * height / 2; + return; + } + + /* + * When decoding each macroblock the rlco pointer will be increased + * by 65 * 2 bytes worst-case. + * To avoid overflow the buffer has to be 65/64th of the actual raw + * image size, just in case someone feeds it malicious data. + */ + for (j = 0; j < height / 8; j++) { + for (i = 0; i < width / 8; i++) { + u8 *refp = ref + j * 8 * width + i * 8; + + if (copies) { + memcpy(cf->de_fwht, copy, sizeof(copy)); + if (stat & PFRAME_BIT) + add_deltas(cf->de_fwht, refp, width); + fill_decoder_block(refp, cf->de_fwht, width); + copies--; + continue; + } + + stat = derlc(rlco, cf->coeffs); + + if (stat & PFRAME_BIT) + dequantize_inter(cf->coeffs); + else + dequantize_intra(cf->coeffs); + + ifwht(cf->coeffs, cf->de_fwht, + (stat & PFRAME_BIT) ? 0 : 1); + + copies = (stat & DUPS_MASK) >> 1; + if (copies) + memcpy(copy, cf->de_fwht, sizeof(copy)); + if (stat & PFRAME_BIT) + add_deltas(cf->de_fwht, refp, width); + fill_decoder_block(refp, cf->de_fwht, width); + } + } +} + +void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, + u32 hdr_flags) +{ + const __be16 *rlco = cf->rlc_data; + u32 h = cf->height / 2; + u32 w = cf->width / 2; + + if (hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT) + h *= 2; + if (hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH) + w *= 2; + decode_plane(cf, &rlco, ref->luma, cf->height, cf->width, + hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED); + decode_plane(cf, &rlco, ref->cb, h, w, + hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED); + decode_plane(cf, &rlco, ref->cr, h, w, + hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED); +} diff --git a/drivers/media/platform/vicodec/codec-fwht.h b/drivers/media/platform/vicodec/codec-fwht.h new file mode 100644 index 000000000000..1f9e47331197 --- /dev/null +++ b/drivers/media/platform/vicodec/codec-fwht.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2016 Tom aan de Wiel + * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + */ + +#ifndef CODEC_FWHT_H +#define CODEC_FWHT_H + +#include +#include +#include + +/* + * The compressed format consists of a fwht_cframe_hdr struct followed by the + * compressed frame data. The header contains the size of that data. + * Each Y, Cb and Cr plane is compressed separately. If the compressed + * size of each plane becomes larger than the uncompressed size, then + * that plane is stored uncompressed and the corresponding bit is set + * in the flags field of the header. + * + * Each compressed plane consists of macroblocks and each macroblock + * is run-length-encoded. Each macroblock starts with a 16 bit value. + * Bit 15 indicates if this is a P-coded macroblock (1) or not (0). + * P-coded macroblocks contain a delta against the previous frame. + * + * Bits 1-12 contain a number. If non-zero, then this same macroblock + * repeats that number of times. This results in a high degree of + * compression for generated images like colorbars. + * + * Following this macroblock header the MB coefficients are run-length + * encoded: the top 12 bits contain the coefficient, the bottom 4 bits + * tell how many times this coefficient occurs. The value 0xf indicates + * that the remainder of the macroblock should be filled with zeroes. + * + * All 16 and 32 bit values are stored in big-endian (network) order. + * + * Each fwht_cframe_hdr starts with an 8 byte magic header that is + * guaranteed not to occur in the compressed frame data. This header + * can be used to sync to the next frame. + * + * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel + * developed this as part of a university project, specifically for use + * with this driver. His project report can be found here: + * + * https://hverkuil.home.xs4all.nl/fwht.pdf + */ + +/* + * This is a sequence of 8 bytes with the low 4 bits set to 0xf. + * + * This sequence cannot occur in the encoded data + * + * Note that these two magic values are symmetrical so endian issues here. + */ +#define FWHT_MAGIC1 0x4f4f4f4f +#define FWHT_MAGIC2 0xffffffff + +#define FWHT_VERSION 1 + +/* Set if this is an interlaced format */ +#define FWHT_FL_IS_INTERLACED BIT(0) +/* Set if this is a bottom-first (NTSC) interlaced format */ +#define FWHT_FL_IS_BOTTOM_FIRST BIT(1) +/* Set if each 'frame' contains just one field */ +#define FWHT_FL_IS_ALTERNATE BIT(2) +/* + * If FWHT_FL_IS_ALTERNATE was set, then this is set if this + * 'frame' is the bottom field, else it is the top field. + */ +#define FWHT_FL_IS_BOTTOM_FIELD BIT(3) +/* Set if this frame is uncompressed */ +#define FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4) +#define FWHT_FL_CB_IS_UNCOMPRESSED BIT(5) +#define FWHT_FL_CR_IS_UNCOMPRESSED BIT(6) +#define FWHT_FL_CHROMA_FULL_HEIGHT BIT(7) +#define FWHT_FL_CHROMA_FULL_WIDTH BIT(8) + +struct fwht_cframe_hdr { + u32 magic1; + u32 magic2; + __be32 version; + __be32 width, height; + __be32 flags; + __be32 colorspace; + __be32 xfer_func; + __be32 ycbcr_enc; + __be32 quantization; + __be32 size; +}; + +struct fwht_cframe { + unsigned int width, height; + u16 i_frame_qp; + u16 p_frame_qp; + __be16 *rlc_data; + s16 coeffs[8 * 8]; + s16 de_coeffs[8 * 8]; + s16 de_fwht[8 * 8]; + u32 size; +}; + +struct fwht_raw_frame { + unsigned int width, height; + unsigned int width_div; + unsigned int height_div; + unsigned int luma_step; + unsigned int chroma_step; + u8 *luma, *cb, *cr; +}; + +#define FWHT_FRAME_PCODED BIT(0) +#define FWHT_FRAME_UNENCODED BIT(1) +#define FWHT_LUMA_UNENCODED BIT(2) +#define FWHT_CB_UNENCODED BIT(3) +#define FWHT_CR_UNENCODED BIT(4) + +u32 fwht_encode_frame(struct fwht_raw_frame *frm, + struct fwht_raw_frame *ref_frm, + struct fwht_cframe *cf, + bool is_intra, bool next_is_intra); +void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, + u32 hdr_flags); + +#endif diff --git a/drivers/media/platform/vicodec/vicodec-codec.c b/drivers/media/platform/vicodec/vicodec-codec.c deleted file mode 100644 index 3547129c1163..000000000000 --- a/drivers/media/platform/vicodec/vicodec-codec.c +++ /dev/null @@ -1,835 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2016 Tom aan de Wiel - * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper: - * - * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms, - * R.D. Brown, 1977 - */ - -#include -#include "vicodec-codec.h" - -#define ALL_ZEROS 15 - -static const uint8_t zigzag[64] = { - 0, - 1, 8, - 2, 9, 16, - 3, 10, 17, 24, - 4, 11, 18, 25, 32, - 5, 12, 19, 26, 33, 40, - 6, 13, 20, 27, 34, 41, 48, - 7, 14, 21, 28, 35, 42, 49, 56, - 15, 22, 29, 36, 43, 50, 57, - 23, 30, 37, 44, 51, 58, - 31, 38, 45, 52, 59, - 39, 46, 53, 60, - 47, 54, 61, - 55, 62, - 63, -}; - - -static int rlc(const s16 *in, __be16 *output, int blocktype) -{ - s16 block[8 * 8]; - s16 *wp = block; - int i = 0; - int x, y; - int ret = 0; - - /* read in block from framebuffer */ - int lastzero_run = 0; - int to_encode; - - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - *wp = in[x + y * 8]; - wp++; - } - } - - /* keep track of amount of trailing zeros */ - for (i = 63; i >= 0 && !block[zigzag[i]]; i--) - lastzero_run++; - - *output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0); - ret++; - - to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0); - - i = 0; - while (i < to_encode) { - int cnt = 0; - int tmp; - - /* count leading zeros */ - while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) { - cnt++; - i++; - if (i == to_encode) { - cnt--; - break; - } - } - /* 4 bits for run, 12 for coefficient (quantization by 4) */ - *output++ = htons((cnt | tmp << 4)); - i++; - ret++; - } - if (lastzero_run > 14) { - *output = htons(ALL_ZEROS | 0); - ret++; - } - - return ret; -} - -/* - * This function will worst-case increase rlc_in by 65*2 bytes: - * one s16 value for the header and 8 * 8 coefficients of type s16. - */ -static s16 derlc(const __be16 **rlc_in, s16 *dwht_out) -{ - /* header */ - const __be16 *input = *rlc_in; - s16 ret = ntohs(*input++); - int dec_count = 0; - s16 block[8 * 8 + 16]; - s16 *wp = block; - int i; - - /* - * Now de-compress, it expands one byte to up to 15 bytes - * (or fills the remainder of the 64 bytes with zeroes if it - * is the last byte to expand). - * - * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to - * allow for overflow if the incoming data was malformed. - */ - while (dec_count < 8 * 8) { - s16 in = ntohs(*input++); - int length = in & 0xf; - int coeff = in >> 4; - - /* fill remainder with zeros */ - if (length == 15) { - for (i = 0; i < 64 - dec_count; i++) - *wp++ = 0; - break; - } - - for (i = 0; i < length; i++) - *wp++ = 0; - *wp++ = coeff; - dec_count += length + 1; - } - - wp = block; - - for (i = 0; i < 64; i++) { - int pos = zigzag[i]; - int y = pos / 8; - int x = pos % 8; - - dwht_out[x + y * 8] = *wp++; - } - *rlc_in = input; - return ret; -} - -static const int quant_table[] = { - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, - 2, 2, 2, 2, 2, 2, 3, 6, - 2, 2, 2, 2, 2, 3, 6, 6, - 2, 2, 2, 2, 3, 6, 6, 6, - 2, 2, 2, 3, 6, 6, 6, 6, - 2, 2, 3, 6, 6, 6, 6, 8, -}; - -static const int quant_table_p[] = { - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 6, - 3, 3, 3, 3, 3, 3, 6, 6, - 3, 3, 3, 3, 3, 6, 6, 9, - 3, 3, 3, 3, 6, 6, 9, 9, - 3, 3, 3, 6, 6, 9, 9, 10, -}; - -static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp) -{ - const int *quant = quant_table; - int i, j; - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { - *coeff >>= *quant; - if (*coeff >= -qp && *coeff <= qp) - *coeff = *de_coeff = 0; - else - *de_coeff = *coeff << *quant; - } - } -} - -static void dequantize_intra(s16 *coeff) -{ - const int *quant = quant_table; - int i, j; - - for (j = 0; j < 8; j++) - for (i = 0; i < 8; i++, quant++, coeff++) - *coeff <<= *quant; -} - -static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp) -{ - const int *quant = quant_table_p; - int i, j; - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { - *coeff >>= *quant; - if (*coeff >= -qp && *coeff <= qp) - *coeff = *de_coeff = 0; - else - *de_coeff = *coeff << *quant; - } - } -} - -static void dequantize_inter(s16 *coeff) -{ - const int *quant = quant_table_p; - int i, j; - - for (j = 0; j < 8; j++) - for (i = 0; i < 8; i++, quant++, coeff++) - *coeff <<= *quant; -} - -static void fwht(const u8 *block, s16 *output_block, unsigned int stride, - unsigned int input_step, bool intra) -{ - /* we'll need more than 8 bits for the transformed coefficients */ - s32 workspace1[8], workspace2[8]; - const u8 *tmp = block; - s16 *out = output_block; - int add = intra ? 256 : 0; - unsigned int i; - - /* stage 1 */ - stride *= input_step; - - for (i = 0; i < 8; i++, tmp += stride, out += 8) { - switch (input_step) { - case 1: - workspace1[0] = tmp[0] + tmp[1] - add; - workspace1[1] = tmp[0] - tmp[1]; - - workspace1[2] = tmp[2] + tmp[3] - add; - workspace1[3] = tmp[2] - tmp[3]; - - workspace1[4] = tmp[4] + tmp[5] - add; - workspace1[5] = tmp[4] - tmp[5]; - - workspace1[6] = tmp[6] + tmp[7] - add; - workspace1[7] = tmp[6] - tmp[7]; - break; - case 2: - workspace1[0] = tmp[0] + tmp[2] - add; - workspace1[1] = tmp[0] - tmp[2]; - - workspace1[2] = tmp[4] + tmp[6] - add; - workspace1[3] = tmp[4] - tmp[6]; - - workspace1[4] = tmp[8] + tmp[10] - add; - workspace1[5] = tmp[8] - tmp[10]; - - workspace1[6] = tmp[12] + tmp[14] - add; - workspace1[7] = tmp[12] - tmp[14]; - break; - case 3: - workspace1[0] = tmp[0] + tmp[3] - add; - workspace1[1] = tmp[0] - tmp[3]; - - workspace1[2] = tmp[6] + tmp[9] - add; - workspace1[3] = tmp[6] - tmp[9]; - - workspace1[4] = tmp[12] + tmp[15] - add; - workspace1[5] = tmp[12] - tmp[15]; - - workspace1[6] = tmp[18] + tmp[21] - add; - workspace1[7] = tmp[18] - tmp[21]; - break; - default: - workspace1[0] = tmp[0] + tmp[4] - add; - workspace1[1] = tmp[0] - tmp[4]; - - workspace1[2] = tmp[8] + tmp[12] - add; - workspace1[3] = tmp[8] - tmp[12]; - - workspace1[4] = tmp[16] + tmp[20] - add; - workspace1[5] = tmp[16] - tmp[20]; - - workspace1[6] = tmp[24] + tmp[28] - add; - workspace1[7] = tmp[24] - tmp[28]; - break; - } - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - - /* stage 3 */ - out[0] = workspace2[0] + workspace2[4]; - out[1] = workspace2[0] - workspace2[4]; - out[2] = workspace2[1] - workspace2[5]; - out[3] = workspace2[1] + workspace2[5]; - out[4] = workspace2[2] + workspace2[6]; - out[5] = workspace2[2] - workspace2[6]; - out[6] = workspace2[3] - workspace2[7]; - out[7] = workspace2[3] + workspace2[7]; - } - - out = output_block; - - for (i = 0; i < 8; i++, out++) { - /* stage 1 */ - workspace1[0] = out[0] + out[1 * 8]; - workspace1[1] = out[0] - out[1 * 8]; - - workspace1[2] = out[2 * 8] + out[3 * 8]; - workspace1[3] = out[2 * 8] - out[3 * 8]; - - workspace1[4] = out[4 * 8] + out[5 * 8]; - workspace1[5] = out[4 * 8] - out[5 * 8]; - - workspace1[6] = out[6 * 8] + out[7 * 8]; - workspace1[7] = out[6 * 8] - out[7 * 8]; - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - /* stage 3 */ - out[0 * 8] = workspace2[0] + workspace2[4]; - out[1 * 8] = workspace2[0] - workspace2[4]; - out[2 * 8] = workspace2[1] - workspace2[5]; - out[3 * 8] = workspace2[1] + workspace2[5]; - out[4 * 8] = workspace2[2] + workspace2[6]; - out[5 * 8] = workspace2[2] - workspace2[6]; - out[6 * 8] = workspace2[3] - workspace2[7]; - out[7 * 8] = workspace2[3] + workspace2[7]; - } -} - -/* - * Not the nicest way of doing it, but P-blocks get twice the range of - * that of the I-blocks. Therefore we need a type bigger than 8 bits. - * Furthermore values can be negative... This is just a version that - * works with 16 signed data - */ -static void fwht16(const s16 *block, s16 *output_block, int stride, int intra) -{ - /* we'll need more than 8 bits for the transformed coefficients */ - s32 workspace1[8], workspace2[8]; - const s16 *tmp = block; - s16 *out = output_block; - int i; - - for (i = 0; i < 8; i++, tmp += stride, out += 8) { - /* stage 1 */ - workspace1[0] = tmp[0] + tmp[1]; - workspace1[1] = tmp[0] - tmp[1]; - - workspace1[2] = tmp[2] + tmp[3]; - workspace1[3] = tmp[2] - tmp[3]; - - workspace1[4] = tmp[4] + tmp[5]; - workspace1[5] = tmp[4] - tmp[5]; - - workspace1[6] = tmp[6] + tmp[7]; - workspace1[7] = tmp[6] - tmp[7]; - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - - /* stage 3 */ - out[0] = workspace2[0] + workspace2[4]; - out[1] = workspace2[0] - workspace2[4]; - out[2] = workspace2[1] - workspace2[5]; - out[3] = workspace2[1] + workspace2[5]; - out[4] = workspace2[2] + workspace2[6]; - out[5] = workspace2[2] - workspace2[6]; - out[6] = workspace2[3] - workspace2[7]; - out[7] = workspace2[3] + workspace2[7]; - } - - out = output_block; - - for (i = 0; i < 8; i++, out++) { - /* stage 1 */ - workspace1[0] = out[0] + out[1*8]; - workspace1[1] = out[0] - out[1*8]; - - workspace1[2] = out[2*8] + out[3*8]; - workspace1[3] = out[2*8] - out[3*8]; - - workspace1[4] = out[4*8] + out[5*8]; - workspace1[5] = out[4*8] - out[5*8]; - - workspace1[6] = out[6*8] + out[7*8]; - workspace1[7] = out[6*8] - out[7*8]; - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - - /* stage 3 */ - out[0*8] = workspace2[0] + workspace2[4]; - out[1*8] = workspace2[0] - workspace2[4]; - out[2*8] = workspace2[1] - workspace2[5]; - out[3*8] = workspace2[1] + workspace2[5]; - out[4*8] = workspace2[2] + workspace2[6]; - out[5*8] = workspace2[2] - workspace2[6]; - out[6*8] = workspace2[3] - workspace2[7]; - out[7*8] = workspace2[3] + workspace2[7]; - } -} - -static void ifwht(const s16 *block, s16 *output_block, int intra) -{ - /* - * we'll need more than 8 bits for the transformed coefficients - * use native unit of cpu - */ - int workspace1[8], workspace2[8]; - int inter = intra ? 0 : 1; - const s16 *tmp = block; - s16 *out = output_block; - int i; - - for (i = 0; i < 8; i++, tmp += 8, out += 8) { - /* stage 1 */ - workspace1[0] = tmp[0] + tmp[1]; - workspace1[1] = tmp[0] - tmp[1]; - - workspace1[2] = tmp[2] + tmp[3]; - workspace1[3] = tmp[2] - tmp[3]; - - workspace1[4] = tmp[4] + tmp[5]; - workspace1[5] = tmp[4] - tmp[5]; - - workspace1[6] = tmp[6] + tmp[7]; - workspace1[7] = tmp[6] - tmp[7]; - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - - /* stage 3 */ - out[0] = workspace2[0] + workspace2[4]; - out[1] = workspace2[0] - workspace2[4]; - out[2] = workspace2[1] - workspace2[5]; - out[3] = workspace2[1] + workspace2[5]; - out[4] = workspace2[2] + workspace2[6]; - out[5] = workspace2[2] - workspace2[6]; - out[6] = workspace2[3] - workspace2[7]; - out[7] = workspace2[3] + workspace2[7]; - } - - out = output_block; - - for (i = 0; i < 8; i++, out++) { - /* stage 1 */ - workspace1[0] = out[0] + out[1 * 8]; - workspace1[1] = out[0] - out[1 * 8]; - - workspace1[2] = out[2 * 8] + out[3 * 8]; - workspace1[3] = out[2 * 8] - out[3 * 8]; - - workspace1[4] = out[4 * 8] + out[5 * 8]; - workspace1[5] = out[4 * 8] - out[5 * 8]; - - workspace1[6] = out[6 * 8] + out[7 * 8]; - workspace1[7] = out[6 * 8] - out[7 * 8]; - - /* stage 2 */ - workspace2[0] = workspace1[0] + workspace1[2]; - workspace2[1] = workspace1[0] - workspace1[2]; - workspace2[2] = workspace1[1] - workspace1[3]; - workspace2[3] = workspace1[1] + workspace1[3]; - - workspace2[4] = workspace1[4] + workspace1[6]; - workspace2[5] = workspace1[4] - workspace1[6]; - workspace2[6] = workspace1[5] - workspace1[7]; - workspace2[7] = workspace1[5] + workspace1[7]; - - /* stage 3 */ - if (inter) { - int d; - - out[0 * 8] = workspace2[0] + workspace2[4]; - out[1 * 8] = workspace2[0] - workspace2[4]; - out[2 * 8] = workspace2[1] - workspace2[5]; - out[3 * 8] = workspace2[1] + workspace2[5]; - out[4 * 8] = workspace2[2] + workspace2[6]; - out[5 * 8] = workspace2[2] - workspace2[6]; - out[6 * 8] = workspace2[3] - workspace2[7]; - out[7 * 8] = workspace2[3] + workspace2[7]; - - for (d = 0; d < 8; d++) - out[8 * d] >>= 6; - } else { - int d; - - out[0 * 8] = workspace2[0] + workspace2[4]; - out[1 * 8] = workspace2[0] - workspace2[4]; - out[2 * 8] = workspace2[1] - workspace2[5]; - out[3 * 8] = workspace2[1] + workspace2[5]; - out[4 * 8] = workspace2[2] + workspace2[6]; - out[5 * 8] = workspace2[2] - workspace2[6]; - out[6 * 8] = workspace2[3] - workspace2[7]; - out[7 * 8] = workspace2[3] + workspace2[7]; - - for (d = 0; d < 8; d++) { - out[8 * d] >>= 6; - out[8 * d] += 128; - } - } - } -} - -static void fill_encoder_block(const u8 *input, s16 *dst, - unsigned int stride, unsigned int input_step) -{ - int i, j; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++, input += input_step) - *dst++ = *input; - input += (stride - 8) * input_step; - } -} - -static int var_intra(const s16 *input) -{ - int32_t mean = 0; - int32_t ret = 0; - const s16 *tmp = input; - int i; - - for (i = 0; i < 8 * 8; i++, tmp++) - mean += *tmp; - mean /= 64; - tmp = input; - for (i = 0; i < 8 * 8; i++, tmp++) - ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean); - return ret; -} - -static int var_inter(const s16 *old, const s16 *new) -{ - int32_t ret = 0; - int i; - - for (i = 0; i < 8 * 8; i++, old++, new++) - ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new); - return ret; -} - -static int decide_blocktype(const u8 *cur, const u8 *reference, - s16 *deltablock, unsigned int stride, - unsigned int input_step) -{ - s16 tmp[64]; - s16 old[64]; - s16 *work = tmp; - unsigned int k, l; - int vari; - int vard; - - fill_encoder_block(cur, tmp, stride, input_step); - fill_encoder_block(reference, old, 8, 1); - vari = var_intra(tmp); - - for (k = 0; k < 8; k++) { - for (l = 0; l < 8; l++) { - *deltablock = *work - *reference; - deltablock++; - work++; - reference++; - } - } - deltablock -= 64; - vard = var_inter(old, tmp); - return vari <= vard ? IBLOCK : PBLOCK; -} - -static void fill_decoder_block(u8 *dst, const s16 *input, int stride) -{ - int i, j; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) - *dst++ = *input++; - dst += stride - 8; - } -} - -static void add_deltas(s16 *deltas, const u8 *ref, int stride) -{ - int k, l; - - for (k = 0; k < 8; k++) { - for (l = 0; l < 8; l++) { - *deltas += *ref++; - /* - * Due to quantizing, it might possible that the - * decoded coefficients are slightly out of range - */ - if (*deltas < 0) - *deltas = 0; - else if (*deltas > 255) - *deltas = 255; - deltas++; - } - ref += stride - 8; - } -} - -static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, - struct cframe *cf, u32 height, u32 width, - unsigned int input_step, - bool is_intra, bool next_is_intra) -{ - u8 *input_start = input; - __be16 *rlco_start = *rlco; - s16 deltablock[64]; - __be16 pframe_bit = htons(PFRAME_BIT); - u32 encoding = 0; - unsigned int last_size = 0; - unsigned int i, j; - - for (j = 0; j < height / 8; j++) { - for (i = 0; i < width / 8; i++) { - /* intra code, first frame is always intra coded. */ - int blocktype = IBLOCK; - unsigned int size; - - if (!is_intra) - blocktype = decide_blocktype(input, refp, - deltablock, width, input_step); - if (blocktype == IBLOCK) { - fwht(input, cf->coeffs, width, input_step, 1); - quantize_intra(cf->coeffs, cf->de_coeffs, - cf->i_frame_qp); - } else { - /* inter code */ - encoding |= FRAME_PCODED; - fwht16(deltablock, cf->coeffs, 8, 0); - quantize_inter(cf->coeffs, cf->de_coeffs, - cf->p_frame_qp); - } - if (!next_is_intra) { - ifwht(cf->de_coeffs, cf->de_fwht, blocktype); - - if (blocktype == PBLOCK) - add_deltas(cf->de_fwht, refp, 8); - fill_decoder_block(refp, cf->de_fwht, 8); - } - - input += 8 * input_step; - refp += 8 * 8; - - size = rlc(cf->coeffs, *rlco, blocktype); - if (last_size == size && - !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) { - __be16 *last_rlco = *rlco - size; - s16 hdr = ntohs(*last_rlco); - - if (!((*last_rlco ^ **rlco) & pframe_bit) && - (hdr & DUPS_MASK) < DUPS_MASK) - *last_rlco = htons(hdr + 2); - else - *rlco += size; - } else { - *rlco += size; - } - if (*rlco >= rlco_max) { - encoding |= FRAME_UNENCODED; - goto exit_loop; - } - last_size = size; - } - input += width * 7 * input_step; - } - -exit_loop: - if (encoding & FRAME_UNENCODED) { - u8 *out = (u8 *)rlco_start; - - input = input_start; - /* - * The compressed stream should never contain the magic - * header, so when we copy the YUV data we replace 0xff - * by 0xfe. Since YUV is limited range such values - * shouldn't appear anyway. - */ - for (i = 0; i < height * width; i++, input += input_step) - *out++ = (*input == 0xff) ? 0xfe : *input; - *rlco = (__be16 *)out; - encoding &= ~FRAME_PCODED; - } - return encoding; -} - -u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm, - struct cframe *cf, bool is_intra, bool next_is_intra) -{ - unsigned int size = frm->height * frm->width; - __be16 *rlco = cf->rlc_data; - __be16 *rlco_max; - u32 encoding; - u32 chroma_h = frm->height / frm->height_div; - u32 chroma_w = frm->width / frm->width_div; - unsigned int chroma_size = chroma_h * chroma_w; - - rlco_max = rlco + size / 2 - 256; - encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf, - frm->height, frm->width, - frm->luma_step, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= LUMA_UNENCODED; - encoding &= ~FRAME_UNENCODED; - rlco_max = rlco + chroma_size / 2 - 256; - encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf, - chroma_h, chroma_w, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= CB_UNENCODED; - encoding &= ~FRAME_UNENCODED; - rlco_max = rlco + chroma_size / 2 - 256; - encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf, - chroma_h, chroma_w, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= CR_UNENCODED; - encoding &= ~FRAME_UNENCODED; - cf->size = (rlco - cf->rlc_data) * sizeof(*rlco); - return encoding; -} - -static void decode_plane(struct cframe *cf, const __be16 **rlco, u8 *ref, - u32 height, u32 width, bool uncompressed) -{ - unsigned int copies = 0; - s16 copy[8 * 8]; - s16 stat; - unsigned int i, j; - - if (uncompressed) { - memcpy(ref, *rlco, width * height); - *rlco += width * height / 2; - return; - } - - /* - * When decoding each macroblock the rlco pointer will be increased - * by 65 * 2 bytes worst-case. - * To avoid overflow the buffer has to be 65/64th of the actual raw - * image size, just in case someone feeds it malicious data. - */ - for (j = 0; j < height / 8; j++) { - for (i = 0; i < width / 8; i++) { - u8 *refp = ref + j * 8 * width + i * 8; - - if (copies) { - memcpy(cf->de_fwht, copy, sizeof(copy)); - if (stat & PFRAME_BIT) - add_deltas(cf->de_fwht, refp, width); - fill_decoder_block(refp, cf->de_fwht, width); - copies--; - continue; - } - - stat = derlc(rlco, cf->coeffs); - - if (stat & PFRAME_BIT) - dequantize_inter(cf->coeffs); - else - dequantize_intra(cf->coeffs); - - ifwht(cf->coeffs, cf->de_fwht, - (stat & PFRAME_BIT) ? 0 : 1); - - copies = (stat & DUPS_MASK) >> 1; - if (copies) - memcpy(copy, cf->de_fwht, sizeof(copy)); - if (stat & PFRAME_BIT) - add_deltas(cf->de_fwht, refp, width); - fill_decoder_block(refp, cf->de_fwht, width); - } - } -} - -void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags) -{ - const __be16 *rlco = cf->rlc_data; - u32 h = cf->height / 2; - u32 w = cf->width / 2; - - if (hdr_flags & VICODEC_FL_CHROMA_FULL_HEIGHT) - h *= 2; - if (hdr_flags & VICODEC_FL_CHROMA_FULL_WIDTH) - w *= 2; - decode_plane(cf, &rlco, ref->luma, cf->height, cf->width, - hdr_flags & VICODEC_FL_LUMA_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cb, h, w, - hdr_flags & VICODEC_FL_CB_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cr, h, w, - hdr_flags & VICODEC_FL_CR_IS_UNCOMPRESSED); -} diff --git a/drivers/media/platform/vicodec/vicodec-codec.h b/drivers/media/platform/vicodec/vicodec-codec.h deleted file mode 100644 index ff69d9297ef4..000000000000 --- a/drivers/media/platform/vicodec/vicodec-codec.h +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2016 Tom aan de Wiel - * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - */ - -#ifndef VICODEC_RLC_H -#define VICODEC_RLC_H - -#include -#include -#include - -/* - * The compressed format consists of a cframe_hdr struct followed by the - * compressed frame data. The header contains the size of that data. - * Each Y, Cb and Cr plane is compressed separately. If the compressed - * size of each plane becomes larger than the uncompressed size, then - * that plane is stored uncompressed and the corresponding bit is set - * in the flags field of the header. - * - * Each compressed plane consists of macroblocks and each macroblock - * is run-length-encoded. Each macroblock starts with a 16 bit value. - * Bit 15 indicates if this is a P-coded macroblock (1) or not (0). - * P-coded macroblocks contain a delta against the previous frame. - * - * Bits 1-12 contain a number. If non-zero, then this same macroblock - * repeats that number of times. This results in a high degree of - * compression for generated images like colorbars. - * - * Following this macroblock header the MB coefficients are run-length - * encoded: the top 12 bits contain the coefficient, the bottom 4 bits - * tell how many times this coefficient occurs. The value 0xf indicates - * that the remainder of the macroblock should be filled with zeroes. - * - * All 16 and 32 bit values are stored in big-endian (network) order. - * - * Each cframe_hdr starts with an 8 byte magic header that is - * guaranteed not to occur in the compressed frame data. This header - * can be used to sync to the next frame. - * - * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel - * developed this as part of a university project, specifically for use - * with this driver. His project report can be found here: - * - * https://hverkuil.home.xs4all.nl/fwht.pdf - */ - -/* - * Note: bit 0 of the header must always be 0. Otherwise it cannot - * be guaranteed that the magic 8 byte sequence (see below) can - * never occur in the rlc output. - */ -#define PFRAME_BIT (1 << 15) -#define DUPS_MASK 0x1ffe - -/* - * This is a sequence of 8 bytes with the low 4 bits set to 0xf. - * - * This sequence cannot occur in the encoded data - */ -#define VICODEC_MAGIC1 0x4f4f4f4f -#define VICODEC_MAGIC2 0xffffffff - -#define VICODEC_VERSION 1 - -#define VICODEC_MAX_WIDTH 3840 -#define VICODEC_MAX_HEIGHT 2160 -#define VICODEC_MIN_WIDTH 640 -#define VICODEC_MIN_HEIGHT 480 - -#define PBLOCK 0 -#define IBLOCK 1 - -/* Set if this is an interlaced format */ -#define VICODEC_FL_IS_INTERLACED BIT(0) -/* Set if this is a bottom-first (NTSC) interlaced format */ -#define VICODEC_FL_IS_BOTTOM_FIRST BIT(1) -/* Set if each 'frame' contains just one field */ -#define VICODEC_FL_IS_ALTERNATE BIT(2) -/* - * If VICODEC_FL_IS_ALTERNATE was set, then this is set if this - * 'frame' is the bottom field, else it is the top field. - */ -#define VICODEC_FL_IS_BOTTOM_FIELD BIT(3) -/* Set if this frame is uncompressed */ -#define VICODEC_FL_LUMA_IS_UNCOMPRESSED BIT(4) -#define VICODEC_FL_CB_IS_UNCOMPRESSED BIT(5) -#define VICODEC_FL_CR_IS_UNCOMPRESSED BIT(6) -#define VICODEC_FL_CHROMA_FULL_HEIGHT BIT(7) -#define VICODEC_FL_CHROMA_FULL_WIDTH BIT(8) - -struct cframe_hdr { - u32 magic1; - u32 magic2; - __be32 version; - __be32 width, height; - __be32 flags; - __be32 colorspace; - __be32 xfer_func; - __be32 ycbcr_enc; - __be32 quantization; - __be32 size; -}; - -struct cframe { - unsigned int width, height; - u16 i_frame_qp; - u16 p_frame_qp; - __be16 *rlc_data; - s16 coeffs[8 * 8]; - s16 de_coeffs[8 * 8]; - s16 de_fwht[8 * 8]; - u32 size; -}; - -struct raw_frame { - unsigned int width, height; - unsigned int width_div; - unsigned int height_div; - unsigned int luma_step; - unsigned int chroma_step; - u8 *luma, *cb, *cr; -}; - -#define FRAME_PCODED BIT(0) -#define FRAME_UNENCODED BIT(1) -#define LUMA_UNENCODED BIT(2) -#define CB_UNENCODED BIT(3) -#define CR_UNENCODED BIT(4) - -u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm, - struct cframe *cf, bool is_intra, bool next_is_intra); -void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags); - -#endif diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index caff521d94c6..4f2c35533e08 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c @@ -23,7 +23,7 @@ #include #include -#include "vicodec-codec.h" +#include "codec-fwht.h" MODULE_DESCRIPTION("Virtual codec device"); MODULE_AUTHOR("Hans Verkuil "); @@ -152,7 +152,7 @@ struct vicodec_ctx { /* Source and destination queue data */ struct vicodec_q_data q_data[2]; - struct raw_frame ref_frame; + struct fwht_raw_frame ref_frame; u8 *compressed_frame; u32 cur_buf_offset; u32 comp_max_size; @@ -191,9 +191,9 @@ static void encode(struct vicodec_ctx *ctx, { unsigned int size = q_data->width * q_data->height; const struct pixfmt_info *info = q_data->info; - struct cframe_hdr *p_hdr; - struct cframe cf; - struct raw_frame rf; + struct fwht_cframe_hdr *p_hdr; + struct fwht_cframe cf; + struct fwht_raw_frame rf; u32 encoding; rf.width = q_data->width; @@ -279,29 +279,29 @@ static void encode(struct vicodec_ctx *ctx, cf.p_frame_qp = ctx->p_frame_qp; cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr)); - encoding = encode_frame(&rf, &ctx->ref_frame, &cf, !ctx->gop_cnt, - ctx->gop_cnt == ctx->gop_size - 1); - if (!(encoding & FRAME_PCODED)) + encoding = fwht_encode_frame(&rf, &ctx->ref_frame, &cf, !ctx->gop_cnt, + ctx->gop_cnt == ctx->gop_size - 1); + if (!(encoding & FWHT_FRAME_PCODED)) ctx->gop_cnt = 0; if (++ctx->gop_cnt >= ctx->gop_size) ctx->gop_cnt = 0; - p_hdr = (struct cframe_hdr *)p_out; - p_hdr->magic1 = VICODEC_MAGIC1; - p_hdr->magic2 = VICODEC_MAGIC2; - p_hdr->version = htonl(VICODEC_VERSION); + p_hdr = (struct fwht_cframe_hdr *)p_out; + p_hdr->magic1 = FWHT_MAGIC1; + p_hdr->magic2 = FWHT_MAGIC2; + p_hdr->version = htonl(FWHT_VERSION); p_hdr->width = htonl(cf.width); p_hdr->height = htonl(cf.height); - if (encoding & LUMA_UNENCODED) - flags |= VICODEC_FL_LUMA_IS_UNCOMPRESSED; - if (encoding & CB_UNENCODED) - flags |= VICODEC_FL_CB_IS_UNCOMPRESSED; - if (encoding & CR_UNENCODED) - flags |= VICODEC_FL_CR_IS_UNCOMPRESSED; + if (encoding & FWHT_LUMA_UNENCODED) + flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED; + if (encoding & FWHT_CB_UNENCODED) + flags |= FWHT_FL_CB_IS_UNCOMPRESSED; + if (encoding & FWHT_CR_UNENCODED) + flags |= FWHT_FL_CR_IS_UNCOMPRESSED; if (rf.height_div == 1) - flags |= VICODEC_FL_CHROMA_FULL_HEIGHT; + flags |= FWHT_FL_CHROMA_FULL_HEIGHT; if (rf.width_div == 1) - flags |= VICODEC_FL_CHROMA_FULL_WIDTH; + flags |= FWHT_FL_CHROMA_FULL_WIDTH; p_hdr->flags = htonl(flags); p_hdr->colorspace = htonl(ctx->colorspace); p_hdr->xfer_func = htonl(ctx->xfer_func); @@ -320,11 +320,11 @@ static int decode(struct vicodec_ctx *ctx, unsigned int chroma_size = size; unsigned int i; u32 flags; - struct cframe_hdr *p_hdr; - struct cframe cf; + struct fwht_cframe_hdr *p_hdr; + struct fwht_cframe cf; u8 *p; - p_hdr = (struct cframe_hdr *)p_in; + p_hdr = (struct fwht_cframe_hdr *)p_in; cf.width = ntohl(p_hdr->width); cf.height = ntohl(p_hdr->height); flags = ntohl(p_hdr->flags); @@ -334,13 +334,13 @@ static int decode(struct vicodec_ctx *ctx, ctx->quantization = ntohl(p_hdr->quantization); cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr)); - if (p_hdr->magic1 != VICODEC_MAGIC1 || - p_hdr->magic2 != VICODEC_MAGIC2 || - ntohl(p_hdr->version) != VICODEC_VERSION || - cf.width < VICODEC_MIN_WIDTH || - cf.width > VICODEC_MAX_WIDTH || - cf.height < VICODEC_MIN_HEIGHT || - cf.height > VICODEC_MAX_HEIGHT || + if (p_hdr->magic1 != FWHT_MAGIC1 || + p_hdr->magic2 != FWHT_MAGIC2 || + ntohl(p_hdr->version) != FWHT_VERSION || + cf.width < MIN_WIDTH || + cf.width > MAX_WIDTH || + cf.height < MIN_HEIGHT || + cf.height > MAX_HEIGHT || (cf.width & 7) || (cf.height & 7)) return -EINVAL; @@ -348,12 +348,12 @@ static int decode(struct vicodec_ctx *ctx, if (cf.width != q_data->width || cf.height != q_data->height) return -EINVAL; - if (!(flags & VICODEC_FL_CHROMA_FULL_WIDTH)) + if (!(flags & FWHT_FL_CHROMA_FULL_WIDTH)) chroma_size /= 2; - if (!(flags & VICODEC_FL_CHROMA_FULL_HEIGHT)) + if (!(flags & FWHT_FL_CHROMA_FULL_HEIGHT)) chroma_size /= 2; - decode_frame(&cf, &ctx->ref_frame, flags); + fwht_decode_frame(&cf, &ctx->ref_frame, flags); switch (q_data->info->id) { case V4L2_PIX_FMT_YUV420: @@ -484,7 +484,7 @@ static int device_process(struct vicodec_ctx *ctx, } if (ctx->is_enc) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)p_out; + struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p_out; encode(ctx, q_out, p_in, p_out, 0); vb2_set_plane_payload(&out_vb->vb2_buf, 0, @@ -635,9 +635,10 @@ restart: } ctx->comp_size = sizeof(magic); } - if (ctx->comp_size < sizeof(struct cframe_hdr)) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)ctx->compressed_frame; - u32 copy = sizeof(struct cframe_hdr) - ctx->comp_size; + if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) { + struct fwht_cframe_hdr *p_hdr = + (struct fwht_cframe_hdr *)ctx->compressed_frame; + u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->comp_size; if (copy > p_out + sz - p) copy = p_out + sz - p; @@ -645,7 +646,7 @@ restart: p, copy); p += copy; ctx->comp_size += copy; - if (ctx->comp_size < sizeof(struct cframe_hdr)) { + if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) { job_remove_out_buf(ctx, state); goto restart; } @@ -670,8 +671,8 @@ restart: ctx->cur_buf_offset = p - p_out; ctx->comp_has_frame = true; ctx->comp_has_next_frame = false; - if (sz - ctx->cur_buf_offset >= sizeof(struct cframe_hdr)) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)p; + if (sz - ctx->cur_buf_offset >= sizeof(struct fwht_cframe_hdr)) { + struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p; u32 frame_size = ntohl(p_hdr->size); u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr); @@ -845,7 +846,7 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) pix->sizeimage = pix->width * pix->height * info->sizeimage_mult / info->sizeimage_div; if (pix->pixelformat == V4L2_PIX_FMT_FWHT) - pix->sizeimage += sizeof(struct cframe_hdr); + pix->sizeimage += sizeof(struct fwht_cframe_hdr); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: @@ -863,7 +864,7 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) plane->sizeimage = pix_mp->width * pix_mp->height * info->sizeimage_mult / info->sizeimage_div; if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) - plane->sizeimage += sizeof(struct cframe_hdr); + plane->sizeimage += sizeof(struct fwht_cframe_hdr); memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); memset(plane->reserved, 0, sizeof(plane->reserved)); break; @@ -1308,7 +1309,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, ctx->ref_frame.width = ctx->ref_frame.height = 0; ctx->ref_frame.luma = kvmalloc(size + 2 * size / chroma_div, GFP_KERNEL); ctx->comp_max_size = size + 2 * size / chroma_div + - sizeof(struct cframe_hdr); + sizeof(struct fwht_cframe_hdr); ctx->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL); if (!ctx->ref_frame.luma || !ctx->compressed_frame) { kvfree(ctx->ref_frame.luma); @@ -1493,7 +1494,7 @@ static int vicodec_open(struct file *file) ctx->q_data[V4L2_M2M_DST].sizeimage = size; ctx->colorspace = V4L2_COLORSPACE_REC709; - size += sizeof(struct cframe_hdr); + size += sizeof(struct fwht_cframe_hdr); if (ctx->is_enc) { ctx->q_data[V4L2_M2M_DST].sizeimage = size; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->enc_dev, ctx, -- cgit v1.2.3 From a125385c9b17de4e555cc2057593ab11da5edc70 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 15 Aug 2018 09:10:59 -0400 Subject: media: vidioc-g-dv-timings.rst: document V4L2_DV_FL_CAN_DETECT_REDUCED_FPS Document the new V4L2_DV_FL_CAN_DETECT_REDUCED_FPS flag and update the V4L2_DV_FL_REDUCED_FPS description since it can now also be used with receivers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/v4l/vidioc-g-dv-timings.rst | 27 +++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst index 1a034e825161..35cba2c8d459 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst @@ -257,14 +257,19 @@ EBUSY will also be cleared. This is a read-only flag, applications must not set this. * - ``V4L2_DV_FL_REDUCED_FPS`` - - CEA-861 specific: only valid for video transmitters, the flag is - cleared by receivers. It is also only valid for formats with the - ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other formats the - flag will be cleared by the driver. If the application sets this - flag, then the pixelclock used to set up the transmitter is - divided by 1.001 to make it compatible with NTSC framerates. If - the transmitter can't generate such frequencies, then the flag - will also be cleared. + - CEA-861 specific: only valid for video transmitters or video + receivers that have the ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS`` + set. This flag is cleared otherwise. It is also only valid for + formats with the ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other + formats the flag will be cleared by the driver. + + If the application sets this flag for a transmitter, then the + pixelclock used to set up the transmitter is divided by 1.001 to + make it compatible with NTSC framerates. If the transmitter can't + generate such frequencies, then the flag will be cleared. + + If a video receiver detects that the format uses a reduced framerate, + then it will set this flag to signal this to the application. * - ``V4L2_DV_FL_HALF_LINE`` - Specific to interlaced formats: if set, then the vertical backporch of field 1 (aka the odd field) is really one half-line @@ -294,3 +299,9 @@ EBUSY - If set, then the hdmi_vic field is valid and contains the Video Identification Code as per the HDMI standard (HDMI Vendor Specific InfoFrame). + * - ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS`` + - CEA-861 specific: only valid for video receivers, the flag is + cleared by transmitters. + If set, then the hardware can detect the difference between + regular framerates and framerates reduced by 1000/1001. E.g.: + 60 vs 59.94 Hz, 30 vs 29.97 Hz or 24 vs 23.976 Hz. -- cgit v1.2.3 From cbb6a7f52b148dea0fed434b629aedddf7804d14 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Mon, 21 May 2018 04:54:54 -0400 Subject: media: Documentation: v4l: document request API Document the request API for V4L2 devices, and amend the documentation of system calls influenced by it. Signed-off-by: Alexandre Courbot Signed-off-by: Hans Verkuil Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/mediactl/media-controller.rst | 1 + Documentation/media/uapi/mediactl/media-funcs.rst | 6 + .../uapi/mediactl/media-ioc-request-alloc.rst | 65 ++++++ .../uapi/mediactl/media-request-ioc-queue.rst | 82 +++++++ .../uapi/mediactl/media-request-ioc-reinit.rst | 51 +++++ Documentation/media/uapi/mediactl/request-api.rst | 245 +++++++++++++++++++++ .../media/uapi/mediactl/request-func-close.rst | 48 ++++ .../media/uapi/mediactl/request-func-ioctl.rst | 67 ++++++ .../media/uapi/mediactl/request-func-poll.rst | 77 +++++++ Documentation/media/uapi/v4l/buffer.rst | 21 +- .../media/uapi/v4l/vidioc-g-ext-ctrls.rst | 53 ++++- Documentation/media/uapi/v4l/vidioc-qbuf.rst | 32 ++- Documentation/media/videodev2.h.rst.exceptions | 1 + 13 files changed, 739 insertions(+), 10 deletions(-) create mode 100644 Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst create mode 100644 Documentation/media/uapi/mediactl/media-request-ioc-queue.rst create mode 100644 Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst create mode 100644 Documentation/media/uapi/mediactl/request-api.rst create mode 100644 Documentation/media/uapi/mediactl/request-func-close.rst create mode 100644 Documentation/media/uapi/mediactl/request-func-ioctl.rst create mode 100644 Documentation/media/uapi/mediactl/request-func-poll.rst (limited to 'Documentation') diff --git a/Documentation/media/uapi/mediactl/media-controller.rst b/Documentation/media/uapi/mediactl/media-controller.rst index 0eea4f9a07d5..66aff38cd499 100644 --- a/Documentation/media/uapi/mediactl/media-controller.rst +++ b/Documentation/media/uapi/mediactl/media-controller.rst @@ -21,6 +21,7 @@ Part IV - Media Controller API media-controller-intro media-controller-model media-types + request-api media-funcs media-header diff --git a/Documentation/media/uapi/mediactl/media-funcs.rst b/Documentation/media/uapi/mediactl/media-funcs.rst index 076856501cdb..260f9dcadcde 100644 --- a/Documentation/media/uapi/mediactl/media-funcs.rst +++ b/Documentation/media/uapi/mediactl/media-funcs.rst @@ -16,3 +16,9 @@ Function Reference media-ioc-enum-entities media-ioc-enum-links media-ioc-setup-link + media-ioc-request-alloc + request-func-close + request-func-ioctl + request-func-poll + media-request-ioc-queue + media-request-ioc-reinit diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst new file mode 100644 index 000000000000..34434e2b3918 --- /dev/null +++ b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst @@ -0,0 +1,65 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _media_ioc_request_alloc: + +***************************** +ioctl MEDIA_IOC_REQUEST_ALLOC +***************************** + +Name +==== + +MEDIA_IOC_REQUEST_ALLOC - Allocate a request + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, MEDIA_IOC_REQUEST_ALLOC, int *argp ) + :name: MEDIA_IOC_REQUEST_ALLOC + + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``argp`` + Pointer to an integer. + + +Description +=========== + +If the media device supports :ref:`requests `, then +this ioctl can be used to allocate a request. If it is not supported, then +``errno`` is set to ``ENOTTY``. A request is accessed through a file descriptor +that is returned in ``*argp``. + +If the request was successfully allocated, then the request file descriptor +can be passed to the :ref:`VIDIOC_QBUF `, +:ref:`VIDIOC_G_EXT_CTRLS `, +:ref:`VIDIOC_S_EXT_CTRLS ` and +:ref:`VIDIOC_TRY_EXT_CTRLS ` ioctls. + +In addition, the request can be queued by calling +:ref:`MEDIA_REQUEST_IOC_QUEUE` and re-initialized by calling +:ref:`MEDIA_REQUEST_IOC_REINIT`. + +Finally, the file descriptor can be :ref:`polled ` to wait +for the request to complete. + +The request will remain allocated until all the file descriptors associated +with it are closed by :ref:`close() ` and the driver no +longer uses the request internally. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +ENOTTY + The driver has no support for requests. diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst new file mode 100644 index 000000000000..d4f8119e0643 --- /dev/null +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst @@ -0,0 +1,82 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _media_request_ioc_queue: + +***************************** +ioctl MEDIA_REQUEST_IOC_QUEUE +***************************** + +Name +==== + +MEDIA_REQUEST_IOC_QUEUE - Queue a request + + +Synopsis +======== + +.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_QUEUE ) + :name: MEDIA_REQUEST_IOC_QUEUE + + +Arguments +========= + +``request_fd`` + File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`. + + +Description +=========== + +If the media device supports :ref:`requests `, then +this request ioctl can be used to queue a previously allocated request. + +If the request was successfully queued, then the file descriptor can be +:ref:`polled ` to wait for the request to complete. + +If the request was already queued before, then ``EBUSY`` is returned. +Other errors can be returned if the contents of the request contained +invalid or inconsistent data, see the next section for a list of +common error codes. On error both the request and driver state are unchanged. + +Typically if you get an error here, then that means that the application +did something wrong and you have to fix the application. + +Once a request is queued, then the driver is required to gracefully handle +errors that occur when the request is applied to the hardware. The +exception is the ``EIO`` error which signals a fatal error that requires +the application to stop streaming to reset the hardware state. + +It is not allowed to mix queuing requests with queuing buffers directly +(without a request). ``EPERM`` will be returned if the first buffer was +queued directly and you next try to queue a request, or vice versa. + +A request must contain at least one buffer, otherwise this ioctl will +return an ``ENOENT`` error. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +EBUSY + The request was already queued. +EPERM + The application queued the first buffer directly, but later attempted + to use a request. It is not permitted to mix the two APIs. +ENOENT + The request did not contain any buffers. All requests are required + to have at least one buffer. This can also be returned if required + controls are missing. +ENOMEM + Out of memory when allocating internal data structures for this + request. +EINVAL + The request has invalid data. +EIO + The hardware is in a bad state. To recover, the application needs to + stop streaming to reset the hardware state and then try to restart + streaming. diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst new file mode 100644 index 000000000000..febe888494c8 --- /dev/null +++ b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst @@ -0,0 +1,51 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _media_request_ioc_reinit: + +****************************** +ioctl MEDIA_REQUEST_IOC_REINIT +****************************** + +Name +==== + +MEDIA_REQUEST_IOC_REINIT - Re-initialize a request + + +Synopsis +======== + +.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_REINIT ) + :name: MEDIA_REQUEST_IOC_REINIT + + +Arguments +========= + +``request_fd`` + File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`. + +Description +=========== + +If the media device supports :ref:`requests `, then +this request ioctl can be used to re-initialize a previously allocated +request. + +Re-initializing a request will clear any existing data from the request. +This avoids having to :ref:`close() ` a completed +request and allocate a new request. Instead the completed request can just +be re-initialized and it is ready to be used again. + +A request can only be re-initialized if it either has not been queued +yet, or if it was queued and completed. Otherwise it will set ``errno`` +to ``EBUSY``. No other error codes can be returned. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. + +EBUSY + The request is queued but not yet completed. diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst new file mode 100644 index 000000000000..0b9da58b01e3 --- /dev/null +++ b/Documentation/media/uapi/mediactl/request-api.rst @@ -0,0 +1,245 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _media-request-api: + +Request API +=========== + +The Request API has been designed to allow V4L2 to deal with requirements of +modern devices (stateless codecs, complex camera pipelines, ...) and APIs +(Android Codec v2). One such requirement is the ability for devices belonging to +the same pipeline to reconfigure and collaborate closely on a per-frame basis. +Another is support of stateless codecs, which require controls to be applied +to specific frames (aka 'per-frame controls') in order to be used efficiently. + +Supporting these features without the Request API is not always possible and if +it is, it is terribly inefficient: user-space would have to flush all activity +on the media pipeline, reconfigure it for the next frame, queue the buffers to +be processed with that configuration, and wait until they are all available for +dequeuing before considering the next frame. This defeats the purpose of having +buffer queues since in practice only one buffer would be queued at a time. + +The Request API allows a specific configuration of the pipeline (media +controller topology + controls for each media entity) to be associated with +specific buffers. The parameters are applied by each participating device as +buffers associated to a request flow in. This allows user-space to schedule +several tasks ("requests") with different parameters in advance, knowing that +the parameters will be applied when needed to get the expected result. Control +values at the time of request completion are also available for reading. + +Usage +===== + +The Request API is used on top of standard media controller and V4L2 calls, +which are augmented with an extra ``request_fd`` parameter. Requests themselves +are allocated from the supporting media controller node. + +Request Allocation +------------------ + +User-space allocates requests using :ref:`MEDIA_IOC_REQUEST_ALLOC` +for the media device node. This returns a file descriptor representing the +request. Typically, several such requests will be allocated. + +Request Preparation +------------------- + +Standard V4L2 ioctls can then receive a request file descriptor to express the +fact that the ioctl is part of said request, and is not to be applied +immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that +support this. Controls set with a ``request_fd`` parameter are stored instead +of being immediately applied, and buffers queued to a request do not enter the +regular buffer queue until the request itself is queued. + +Request Submission +------------------ + +Once the parameters and buffers of the request are specified, it can be +queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor. +A request must contain at least one buffer, otherwise ``ENOENT`` is returned. +This will make the buffers associated to the request available to their driver, +which can then apply the associated controls as buffers are processed. A queued +request cannot be modified anymore. + +.. caution:: + For :ref:`memory-to-memory devices ` you can use requests only for + output buffers, not for capture buffers. Attempting to add a capture buffer + to a request will result in an ``EPERM`` error. + +If the request contains parameters for multiple entities, individual drivers may +synchronize so the requested pipeline's topology is applied before the buffers +are processed. Media controller drivers do a best effort implementation since +perfect atomicity may not be possible due to hardware limitations. + +.. caution:: + + It is not allowed to mix queuing requests with directly queuing buffers: + whichever method is used first locks this in place until + :ref:`VIDIOC_STREAMOFF ` is called or the device is + :ref:`closed `. Attempts to directly queue a buffer when earlier + a buffer was queued via a request or vice versa will result in an ``EPERM`` + error. + +Controls can still be set without a request and are applied immediately, +regardless of whether a request is in use or not. + +.. caution:: + + Setting the same control through a request and also directly can lead to + undefined behavior! + +User-space can :ref:`poll() ` a request file descriptor in +order to wait until the request completes. A request is considered complete +once all its associated buffers are available for dequeuing and all the +associated controls have been updated with the values at the time of completion. +Note that user-space does not need to wait for the request to complete to +dequeue its buffers: buffers that are available halfway through a request can +be dequeued independently of the request's state. + +A completed request contains the state of the request at the time of the +request completion. User-space can query that state by calling +:ref:`ioctl VIDIOC_G_EXT_CTRLS ` with the request file +descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS ` for a +request that has been queued but not yet completed will return ``EBUSY`` +since the control values might be changed at any time by the driver while the +request is in flight. + +Recycling and Destruction +------------------------- + +Finally, a completed request can either be discarded or be reused. Calling +:ref:`close() ` on a request file descriptor will make +that file descriptor unusable and the request will be freed once it is no +longer in use by the kernel. That is, if the request is queued and then the +file descriptor is closed, then it won't be freed until the driver completed +the request. + +The :ref:`MEDIA_REQUEST_IOC_REINIT` will clear a request's state and make it +available again. No state is retained by this operation: the request is as +if it had just been allocated. + +Example for a Codec Device +-------------------------- + +For use-cases such as :ref:`codecs `, the request API can be used +to associate specific controls to +be applied by the driver for the OUTPUT buffer, allowing user-space +to queue many such buffers in advance. It can also take advantage of requests' +ability to capture the state of controls when the request completes to read back +information that may be subject to change. + +Put into code, after obtaining a request, user-space can assign controls and one +OUTPUT buffer to it: + +.. code-block:: c + + struct v4l2_buffer buf; + struct v4l2_ext_controls ctrls; + int req_fd; + ... + if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd)) + return errno; + ... + ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL; + ctrls.request_fd = req_fd; + if (ioctl(codec_fd, VIDIOC_S_EXT_CTRLS, &ctrls)) + return errno; + ... + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf.flags |= V4L2_BUF_FLAG_REQUEST_FD; + buf.request_fd = req_fd; + if (ioctl(codec_fd, VIDIOC_QBUF, &buf)) + return errno; + +Note that it is not allowed to use the Request API for CAPTURE buffers +since there are no per-frame settings to report there. + +Once the request is fully prepared, it can be queued to the driver: + +.. code-block:: c + + if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE)) + return errno; + +User-space can then either wait for the request to complete by calling poll() on +its file descriptor, or start dequeuing CAPTURE buffers. Most likely, it will +want to get CAPTURE buffers as soon as possible and this can be done using a +regular :ref:`VIDIOC_DQBUF `: + +.. code-block:: c + + struct v4l2_buffer buf; + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(codec_fd, VIDIOC_DQBUF, &buf)) + return errno; + +Note that this example assumes for simplicity that for every OUTPUT buffer +there will be one CAPTURE buffer, but this does not have to be the case. + +We can then, after ensuring that the request is completed via polling the +request file descriptor, query control values at the time of its completion via +a call to :ref:`VIDIOC_G_EXT_CTRLS `. +This is particularly useful for volatile controls for which we want to +query values as soon as the capture buffer is produced. + +.. code-block:: c + + struct pollfd pfd = { .events = POLLPRI, .fd = req_fd }; + poll(&pfd, 1, -1); + ... + ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL; + ctrls.request_fd = req_fd; + if (ioctl(codec_fd, VIDIOC_G_EXT_CTRLS, &ctrls)) + return errno; + +Once we don't need the request anymore, we can either recycle it for reuse with +:ref:`MEDIA_REQUEST_IOC_REINIT`... + +.. code-block:: c + + if (ioctl(req_fd, MEDIA_REQUEST_IOC_REINIT)) + return errno; + +... or close its file descriptor to completely dispose of it. + +.. code-block:: c + + close(req_fd); + +Example for a Simple Capture Device +----------------------------------- + +With a simple capture device, requests can be used to specify controls to apply +for a given CAPTURE buffer. + +.. code-block:: c + + struct v4l2_buffer buf; + struct v4l2_ext_controls ctrls; + int req_fd; + ... + if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd)) + return errno; + ... + ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL; + ctrls.request_fd = req_fd; + if (ioctl(camera_fd, VIDIOC_S_EXT_CTRLS, &ctrls)) + return errno; + ... + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.flags |= V4L2_BUF_FLAG_REQUEST_FD; + buf.request_fd = req_fd; + if (ioctl(camera_fd, VIDIOC_QBUF, &buf)) + return errno; + +Once the request is fully prepared, it can be queued to the driver: + +.. code-block:: c + + if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE)) + return errno; + +User-space can then dequeue buffers, wait for the request completion, query +controls and recycle the request as in the M2M example above. diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst new file mode 100644 index 000000000000..b5c78683840b --- /dev/null +++ b/Documentation/media/uapi/mediactl/request-func-close.rst @@ -0,0 +1,48 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _request-func-close: + +*************** +request close() +*************** + +Name +==== + +request-close - Close a request file descriptor + + +Synopsis +======== + +.. code-block:: c + + #include + + +.. c:function:: int close( int fd ) + :name: req-close + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`. + + +Description +=========== + +Closes the request file descriptor. Resources associated with the request +are freed once all file descriptors associated with the request are closed +and the driver has completed the request. + + +Return Value +============ + +:ref:`close() ` returns 0 on success. On error, -1 is +returned, and ``errno`` is set appropriately. Possible error codes are: + +EBADF + ``fd`` is not a valid open file descriptor. diff --git a/Documentation/media/uapi/mediactl/request-func-ioctl.rst b/Documentation/media/uapi/mediactl/request-func-ioctl.rst new file mode 100644 index 000000000000..ff7b072a6999 --- /dev/null +++ b/Documentation/media/uapi/mediactl/request-func-ioctl.rst @@ -0,0 +1,67 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _request-func-ioctl: + +*************** +request ioctl() +*************** + +Name +==== + +request-ioctl - Control a request file descriptor + + +Synopsis +======== + +.. code-block:: c + + #include + + +.. c:function:: int ioctl( int fd, int cmd, void *argp ) + :name: req-ioctl + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`. + +``cmd`` + The request ioctl command code as defined in the media.h header file, for + example :ref:`MEDIA_REQUEST_IOC_QUEUE`. + +``argp`` + Pointer to a request-specific structure. + + +Description +=========== + +The :ref:`ioctl() ` function manipulates request +parameters. The argument ``fd`` must be an open file descriptor. + +The ioctl ``cmd`` code specifies the request function to be called. It +has encoded in it whether the argument is an input, output or read/write +parameter, and the size of the argument ``argp`` in bytes. + +Macros and structures definitions specifying request ioctl commands and +their parameters are located in the media.h header file. All request ioctl +commands, their respective function and parameters are specified in +:ref:`media-user-func`. + + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +Command-specific error codes are listed in the individual command +descriptions. + +When an ioctl that takes an output or read/write parameter fails, the +parameter remains unmodified. diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst new file mode 100644 index 000000000000..70cc9d406a9f --- /dev/null +++ b/Documentation/media/uapi/mediactl/request-func-poll.rst @@ -0,0 +1,77 @@ +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections + +.. _request-func-poll: + +************** +request poll() +************** + +Name +==== + +request-poll - Wait for some event on a file descriptor + + +Synopsis +======== + +.. code-block:: c + + #include + + +.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout ) + :name: request-poll + +Arguments +========= + +``ufds`` + List of file descriptor events to be watched + +``nfds`` + Number of file descriptor events at the \*ufds array + +``timeout`` + Timeout to wait for events + + +Description +=========== + +With the :c:func:`poll() ` function applications can wait +for a request to complete. + +On success :c:func:`poll() ` returns the number of file +descriptors that have been selected (that is, file descriptors for which the +``revents`` field of the respective struct :c:type:`pollfd` +is non-zero). Request file descriptor set the ``POLLPRI`` flag in ``revents`` +when the request was completed. When the function times out it returns +a value of zero, on failure it returns -1 and the ``errno`` variable is +set appropriately. + +Attempting to poll for a request that is completed or not yet queued will +set the ``POLLERR`` flag in ``revents``. + + +Return Value +============ + +On success, :c:func:`poll() ` returns the number of +structures which have non-zero ``revents`` fields, or zero if the call +timed out. On error -1 is returned, and the ``errno`` variable is set +appropriately: + +``EBADF`` + One or more of the ``ufds`` members specify an invalid file + descriptor. + +``EFAULT`` + ``ufds`` references an inaccessible memory area. + +``EINTR`` + The call was interrupted by a signal. + +``EINVAL`` + The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use + ``getrlimit()`` to obtain this value. diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index e2c85ddc990b..dd0065a95ea0 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst @@ -306,10 +306,15 @@ struct v4l2_buffer - A place holder for future extensions. Drivers and applications must set this to 0. * - __u32 - - ``reserved`` + - ``request_fd`` - - - A place holder for future extensions. Drivers and applications - must set this to 0. + - The file descriptor of the request to queue the buffer to. If specified + and flag ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be + queued to that request. This is set by the user when calling + :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls. + If the device does not support requests, then ``EPERM`` will be returned. + If requests are supported but an invalid request FD is given, then + ``ENOENT`` will be returned. @@ -514,6 +519,11 @@ Buffer Flags streaming may continue as normal and the buffer may be reused normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is called. + * .. _`V4L2-BUF-FLAG-IN-REQUEST`: + + - ``V4L2_BUF_FLAG_IN_REQUEST`` + - 0x00000080 + - This buffer is part of a request that hasn't been queued yet. * .. _`V4L2-BUF-FLAG-KEYFRAME`: - ``V4L2_BUF_FLAG_KEYFRAME`` @@ -589,6 +599,11 @@ Buffer Flags the format. Any Any subsequent call to the :ref:`VIDIOC_DQBUF ` ioctl will not block anymore, but return an ``EPIPE`` error code. + * .. _`V4L2-BUF-FLAG-REQUEST-FD`: + + - ``V4L2_BUF_FLAG_REQUEST_FD`` + - 0x00800000 + - The ``request_fd`` field contains a valid file descriptor. * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`: - ``V4L2_BUF_FLAG_TIMESTAMP_MASK`` diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 2011c2b2ee67..771fd1161277 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -95,6 +95,26 @@ appropriate. In the first case the new value is set in struct is inappropriate (e.g. the given menu index is not supported by the menu control), then this will also result in an ``EINVAL`` error code error. +If ``request_fd`` is set to a not-yet-queued :ref:`request ` +file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``, +then the controls are not applied immediately when calling +:ref:`VIDIOC_S_EXT_CTRLS `, but instead are applied by +the driver for the buffer associated with the same request. +If the device does not support requests, then ``EPERM`` will be returned. +If requests are supported but an invalid request FD is given, then +``ENOENT`` will be returned. + +An attempt to call :ref:`VIDIOC_S_EXT_CTRLS ` for a +request that has already been queued will result in an ``EBUSY`` error. + +If ``request_fd`` is specified and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` +during a call to :ref:`VIDIOC_G_EXT_CTRLS `, then the +returned values will be the values currently set for the request (or the +hardware value if none is set) if the request has not yet been queued, or the +values of the controls at the time of request completion if it has already +completed. Attempting to get controls while the request has been queued but +not yet completed will result in an ``EBUSY`` error. + The driver will only set/get these controls if all control values are correct. This prevents the situation where only some of the controls were set/get. Only low-level errors (e. g. a failed i2c command) can @@ -209,13 +229,17 @@ still cause this situation. - ``which`` - Which value of the control to get/set/try. ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the - control and ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default - value of the control. + control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default + value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that + these controls have to be retrieved from a request or tried/set for + a request. In the latter case the ``request_fd`` field contains the + file descriptor of the request that should be used. If the device + does not support requests, then ``EPERM`` will be returned. .. note:: - You can only get the default value of the control, - you cannot set or try it. + When using ``V4L2_CTRL_WHICH_DEF_VAL`` note that You can only + get the default value of the control, you cannot set or try it. For backwards compatibility you can also use a control class here (see :ref:`ctrl-class`). In that case all controls have to @@ -272,8 +296,15 @@ still cause this situation. then you can call :ref:`VIDIOC_TRY_EXT_CTRLS ` to try to discover the actual control that failed the validation step. Unfortunately, there is no ``TRY`` equivalent for :ref:`VIDIOC_G_EXT_CTRLS `. + * - __s32 + - ``request_fd`` + - File descriptor of the request to be used by this operation. Only + valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``. + If the device does not support requests, then ``EPERM`` will be returned. + If requests are supported but an invalid request FD is given, then + ``ENOENT`` will be returned. * - __u32 - - ``reserved``\ [2] + - ``reserved``\ [1] - Reserved for future extensions. Drivers and applications must set the array to zero. @@ -362,7 +393,9 @@ ERANGE EBUSY The control is temporarily not changeable, possibly because another applications took over control of the device function this control - belongs to. + belongs to, or (if the ``which`` field was set to + ``V4L2_CTRL_WHICH_REQUEST_VAL``) the request was queued but not yet + completed. ENOSPC The space reserved for the control's payload is insufficient. The @@ -372,3 +405,11 @@ ENOSPC EACCES Attempt to try or set a read-only control or to get a write-only control. + +EPERM + The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the + device does not support requests. + +ENOENT + The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the + the given ``request_fd`` was invalid. diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index 9e448a4aa3aa..0e415f2551b2 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -65,7 +65,7 @@ To enqueue a :ref:`memory mapped ` buffer applications set the with a pointer to this structure the driver sets the ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an -EINVAL error code. +``EINVAL`` error code. To enqueue a :ref:`user pointer ` buffer applications set the ``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to @@ -98,6 +98,25 @@ dequeued, until the :ref:`VIDIOC_STREAMOFF ` or :ref:`VIDIOC_REQBUFS` ioctl is called, or until the device is closed. +The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify +the file descriptor of a :ref:`request `, if requests are +in use. Setting it means that the buffer will not be passed to the driver +until the request itself is queued. Also, the driver will apply any +settings associated with the request for this buffer. This field will +be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set. +If the device does not support requests, then ``EPERM`` will be returned. +If requests are supported but an invalid request FD is given, then +``ENOENT`` will be returned. + +.. caution:: + It is not allowed to mix queuing requests with queuing buffers directly. + ``EPERM`` will be returned if the first buffer was queued directly and + then the application tries to queue a request, or vice versa. + + For :ref:`memory-to-memory devices ` you can specify the + ``request_fd`` only for output buffers, not for capture buffers. Attempting + to specify this for a capture buffer will result in an ``EPERM`` error. + Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled (capturing) or displayed (output) buffer from the driver's outgoing queue. They just set the ``type``, ``memory`` and ``reserved`` fields of @@ -153,3 +172,14 @@ EPIPE ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already dequeued and no new buffers are expected to become available. + +EPERM + The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not + support requests. Or the first buffer was queued via a request, but + the application now tries to queue it directly, or vice versa (it is + not permitted to mix the two APIs). Or an attempt is made to queue a + CAPTURE buffer to a request for a :ref:`memory-to-memory device `. + +ENOENT + The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the the given + ``request_fd`` was invalid. diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index ca9f0edc579e..99256a2c003e 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -514,6 +514,7 @@ ignore define V4L2_CTRL_DRIVER_PRIV ignore define V4L2_CTRL_MAX_DIMS ignore define V4L2_CTRL_WHICH_CUR_VAL ignore define V4L2_CTRL_WHICH_DEF_VAL +ignore define V4L2_CTRL_WHICH_REQUEST_VAL ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS ignore define V4L2_CID_MAX_CTRLS -- cgit v1.2.3 From 496f6f4d8a84421b70c4fb629656cb4730cbcd61 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 21 May 2018 04:54:33 -0400 Subject: media: doc: Add media-request.h header to documentation build media-request.h has been recently added; add it to the documentation build as well. Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/mc-core.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/media/kapi/mc-core.rst b/Documentation/media/kapi/mc-core.rst index 0c05503eaf1f..69362b3135c2 100644 --- a/Documentation/media/kapi/mc-core.rst +++ b/Documentation/media/kapi/mc-core.rst @@ -262,3 +262,5 @@ in the end provide a way to use driver-specific callbacks. .. kernel-doc:: include/media/media-devnode.h .. kernel-doc:: include/media/media-entity.h + +.. kernel-doc:: include/media/media-request.h -- cgit v1.2.3 From 8ba0dbfd07a3587aedb952a95292e41d70dbf16e Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Wed, 29 Aug 2018 14:04:05 +0800 Subject: iio: adc: sc27xx: Add ADC scale calibration This patch adds support to read calibration values from the eFuse controller to calibrate the ADC channel scales, which can make ADC sample data more accurate. Signed-off-by: Baolin Wang Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/sprd,sc27xx-adc.txt | 4 ++ drivers/iio/adc/sc27xx_adc.c | 74 +++++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt index 8aad960de50b..b4daa15dcf15 100644 --- a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt @@ -12,6 +12,8 @@ Required properties: - interrupts: The interrupt number for the ADC device. - #io-channel-cells: Number of cells in an IIO specifier. - hwlocks: Reference to a phandle of a hwlock provider node. +- nvmem-cells: A phandle to the calibration cells provided by eFuse device. +- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib". Example: @@ -32,5 +34,7 @@ Example: interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; #io-channel-cells = <1>; hwlocks = <&hwlock 4>; + nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; + nvmem-cell-names = "big_scale_calib", "small_scale_calib"; }; }; diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index 153c31104d4e..7940b23dcad9 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -5,10 +5,12 @@ #include #include #include +#include #include #include #include #include +#include /* PMIC global registers definition */ #define SC27XX_MODULE_EN 0xc08 @@ -87,16 +89,73 @@ struct sc27xx_adc_linear_graph { * should use the small-scale graph, and if more than 1.2v, we should use the * big-scale graph. */ -static const struct sc27xx_adc_linear_graph big_scale_graph = { +static struct sc27xx_adc_linear_graph big_scale_graph = { 4200, 3310, 3600, 2832, }; -static const struct sc27xx_adc_linear_graph small_scale_graph = { +static struct sc27xx_adc_linear_graph small_scale_graph = { 1000, 3413, 100, 341, }; +static const struct sc27xx_adc_linear_graph big_scale_graph_calib = { + 4200, 856, + 3600, 733, +}; + +static const struct sc27xx_adc_linear_graph small_scale_graph_calib = { + 1000, 833, + 100, 80, +}; + +static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc) +{ + return ((calib_data & 0xff) + calib_adc - 128) * 4; +} + +static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data, + bool big_scale) +{ + const struct sc27xx_adc_linear_graph *calib_graph; + struct sc27xx_adc_linear_graph *graph; + struct nvmem_cell *cell; + const char *cell_name; + u32 calib_data = 0; + void *buf; + size_t len; + + if (big_scale) { + calib_graph = &big_scale_graph_calib; + graph = &big_scale_graph; + cell_name = "big_scale_calib"; + } else { + calib_graph = &small_scale_graph_calib; + graph = &small_scale_graph; + cell_name = "small_scale_calib"; + } + + cell = nvmem_cell_get(data->dev, cell_name); + if (IS_ERR(cell)) + return PTR_ERR(cell); + + buf = nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); + + if (IS_ERR(buf)) + return PTR_ERR(buf); + + memcpy(&calib_data, buf, min(len, sizeof(u32))); + + /* Only need to calibrate the adc values in the linear graph. */ + graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_graph->adc0); + graph->adc1 = sc27xx_adc_get_calib_data(calib_data >> 8, + calib_graph->adc1); + + kfree(buf); + return 0; +} + static int sc27xx_adc_get_ratio(int channel, int scale) { switch (channel) { @@ -209,7 +268,7 @@ static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, *div_denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK; } -static int sc27xx_adc_to_volt(const struct sc27xx_adc_linear_graph *graph, +static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph, int raw_adc) { int tmp; @@ -390,6 +449,15 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data) if (ret) goto disable_clk; + /* ADC channel scales' calibration from nvmem device */ + ret = sc27xx_adc_scale_calibration(data, true); + if (ret) + goto disable_clk; + + ret = sc27xx_adc_scale_calibration(data, false); + if (ret) + goto disable_clk; + return 0; disable_clk: -- cgit v1.2.3 From 21eab7861688aa4c69fcb88440cc0c4a422bdcd6 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 28 Aug 2018 13:30:34 +0300 Subject: iio: fix position relative kernel version Position relative channel type was added in 4.19 kernel version Fixes: "3055a6cfa04ba" ("iio: Add channel for Position Relative") Signed-off-by: Eugen Hristev Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index a5b4f223641d..8127a08e366d 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -199,7 +199,7 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/in_positionrelative_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_positionrelative_y_raw -KernelVersion: 4.18 +KernelVersion: 4.19 Contact: linux-iio@vger.kernel.org Description: Relative position in direction x or y on a pad (may be -- cgit v1.2.3 From ff5059302642d349596a7ebc3282a978a78144bd Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Wed, 29 Aug 2018 17:58:42 +0300 Subject: iio: dac: ad5758: Add support for hard reset The ad5758 has a hardware reset active low input pin. This patch adds a devicetree entry for a reset GPIO and a new ad5758_reset() function. During initialization, it is checked if the reset property is specified and the the GPIO is being asserted, therefore the device will become active. When the reset function is called, if the gpio_reset var is set, then the GPIO will be toggled, otherwise a software reset is performed. Signed-off-by: Stefan Popa Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/ad5758.txt | 5 +++++ drivers/iio/dac/ad5758.c | 26 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/ad5758.txt b/Documentation/devicetree/bindings/iio/dac/ad5758.txt index bba01a5cab1b..2f607f41f9d3 100644 --- a/Documentation/devicetree/bindings/iio/dac/ad5758.txt +++ b/Documentation/devicetree/bindings/iio/dac/ad5758.txt @@ -50,6 +50,9 @@ Required properties: Optional properties: + - reset-gpios : GPIO spec for the RESET pin. If specified, it will be + asserted during driver probe. + - adi,dc-dc-ilim-microamp: The dc-to-dc converter current limit The following values are currently supported [uA]: * 150000 @@ -71,6 +74,8 @@ AD5758 Example: spi-max-frequency = <1000000>; spi-cpha; + reset-gpios = <&gpio 22 0>; + adi,dc-dc-mode = <2>; adi,range-microvolt = <0 10000000>; adi,dc-dc-ilim-microamp = <200000>; diff --git a/drivers/iio/dac/ad5758.c b/drivers/iio/dac/ad5758.c index bd36333257af..ef41f12bf262 100644 --- a/drivers/iio/dac/ad5758.c +++ b/drivers/iio/dac/ad5758.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -108,6 +109,7 @@ struct ad5758_range { struct ad5758_state { struct spi_device *spi; struct mutex lock; + struct gpio_desc *gpio_reset; struct ad5758_range out_range; unsigned int dc_dc_mode; unsigned int dc_dc_ilim; @@ -474,6 +476,21 @@ static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable) AD5758_CAL_MEM_UNREFRESHED_MSK); } +static int ad5758_reset(struct ad5758_state *st) +{ + if (st->gpio_reset) { + gpiod_set_value(st->gpio_reset, 0); + usleep_range(100, 1000); + gpiod_set_value(st->gpio_reset, 1); + usleep_range(100, 1000); + + return 0; + } else { + /* Perform a software reset */ + return ad5758_soft_reset(st); + } +} + static int ad5758_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, @@ -768,13 +785,18 @@ static int ad5758_init(struct ad5758_state *st) { int regval, ret; + st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(st->gpio_reset)) + return PTR_ERR(st->gpio_reset); + /* Disable CRC checks */ ret = ad5758_crc_disable(st); if (ret < 0) return ret; - /* Perform a software reset */ - ret = ad5758_soft_reset(st); + /* Perform a reset */ + ret = ad5758_reset(st); if (ret < 0) return ret; -- cgit v1.2.3 From ffbc01bff2ef98430e4ab486b878f04fe7bb7c29 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 31 Aug 2018 17:11:11 +0200 Subject: dt-bindings: i2c: designware: document MSCC Ocelot bindings Document bindings for the Microsemi Ocelot integration of the Designware I2C controller. Reviewed-by: Rob Herring Signed-off-by: Alexandre Belloni Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-designware.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-designware.txt b/Documentation/devicetree/bindings/i2c/i2c-designware.txt index fbb0a6d8b964..3e4bcc2fb6f7 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-designware.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-designware.txt @@ -3,6 +3,7 @@ Required properties : - compatible : should be "snps,designware-i2c" + or "mscc,ocelot-i2c" with "snps,designware-i2c" for fallback - reg : Offset and length of the register set for the device - interrupts : where IRQ is the interrupt number. @@ -11,8 +12,12 @@ Recommended properties : - clock-frequency : desired I2C bus clock frequency in Hz. Optional properties : + - reg : for "mscc,ocelot-i2c", a second register set to configure the SDA hold + time, named ICPU_CFG:TWI_DELAY in the datasheet. + - i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds. - This option is only supported in hardware blocks version 1.11a or newer. + This option is only supported in hardware blocks version 1.11a or newer and + on Microsemi SoCs ("mscc,ocelot-i2c" compatible). - i2c-scl-falling-time-ns : should contain the SCL falling time in nanoseconds. This value which is by default 300ns is used to compute the tLOW period. -- cgit v1.2.3 From 66ba345ba8a613cbe50f00743256c470c756b1c7 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 23 Aug 2018 16:41:14 +0800 Subject: dt-bindings: arm: add missing compatible for i.MX boards This patch adds missing compatible for i.MX boards. Signed-off-by: Anson Huang Reviewed-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.txt | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index 8a1baa2b9723..968f238c0801 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -57,6 +57,46 @@ i.MX6SLL EVK board Required root node properties: - compatible = "fsl,imx6sll-evk", "fsl,imx6sll"; +i.MX6 Quad Plus SABRE Smart Device Board +Required root node properties: + - compatible = "fsl,imx6qp-sabresd", "fsl,imx6qp"; + +i.MX6 Quad Plus SABRE Automotive Board +Required root node properties: + - compatible = "fsl,imx6qp-sabreauto", "fsl,imx6qp"; + +i.MX6 DualLite SABRE Smart Device Board +Required root node properties: + - compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl"; + +i.MX6 DualLite/Solo SABRE Automotive Board +Required root node properties: + - compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl"; + +i.MX6 SoloLite EVK Board +Required root node properties: + - compatible = "fsl,imx6sl-evk", "fsl,imx6sl"; + +i.MX6 UltraLite 14x14 EVK Board +Required root node properties: + - compatible = "fsl,imx6ul-14x14-evk", "fsl,imx6ul"; + +i.MX6 UltraLiteLite 14x14 EVK Board +Required root node properties: + - compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull"; + +i.MX6 SoloX SDB Board +Required root node properties: + - compatible = "fsl,imx6sx-sdb", "fsl,imx6sx"; + +i.MX6 SoloX Sabre Auto Board +Required root node properties: + - compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx"; + +i.MX7 SabreSD Board +Required root node properties: + - compatible = "fsl,imx7d-sdb", "fsl,imx7d"; + Generic i.MX boards ------------------- -- cgit v1.2.3 From fbb0de795078190a9834b3409e4b009cfb18a6d4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 27 Aug 2018 11:34:44 +0200 Subject: Add udmabuf misc device A driver to let userspace turn memfd regions into dma-bufs. Use case: Allows qemu create dmabufs for the vga framebuffer or virtio-gpu ressources. Then they can be passed around to display those guest things on the host. To spice client for classic full framebuffer display, and hopefully some day to wayland server for seamless guest window display. qemu test branch: https://git.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf Cc: David Airlie Cc: Tomeu Vizoso Cc: Laurent Pinchart Cc: Daniel Vetter Signed-off-by: Gerd Hoffmann Acked-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20180827093444.23623-1-kraxel@redhat.com --- Documentation/ioctl/ioctl-number.txt | 1 + MAINTAINERS | 8 + drivers/dma-buf/Kconfig | 8 + drivers/dma-buf/Makefile | 1 + drivers/dma-buf/udmabuf.c | 287 ++++++++++++++++++++++ include/uapi/linux/udmabuf.h | 33 +++ tools/testing/selftests/drivers/dma-buf/Makefile | 5 + tools/testing/selftests/drivers/dma-buf/udmabuf.c | 96 ++++++++ 8 files changed, 439 insertions(+) create mode 100644 drivers/dma-buf/udmabuf.c create mode 100644 include/uapi/linux/udmabuf.h create mode 100644 tools/testing/selftests/drivers/dma-buf/Makefile create mode 100644 tools/testing/selftests/drivers/dma-buf/udmabuf.c (limited to 'Documentation') diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 13a7c999c04a..f2ac672eb766 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -272,6 +272,7 @@ Code Seq#(hex) Include File Comments 't' 90-91 linux/toshiba.h toshiba and toshiba_acpi SMM 'u' 00-1F linux/smb_fs.h gone 'u' 20-3F linux/uvcvideo.h USB video class host driver +'u' 40-4f linux/udmabuf.h userspace dma-buf misc device 'v' 00-1F linux/ext2_fs.h conflict! 'v' 00-1F linux/fs.h conflict! 'v' 00-0F linux/sonypi.h conflict! diff --git a/MAINTAINERS b/MAINTAINERS index a5b256b25905..9d9068ed4ee5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15343,6 +15343,14 @@ F: arch/x86/um/ F: fs/hostfs/ F: fs/hppfs/ +USERSPACE DMA BUFFER DRIVER +M: Gerd Hoffmann +S: Maintained +L: dri-devel@lists.freedesktop.org +F: drivers/dma-buf/udmabuf.c +F: include/uapi/linux/udmabuf.h +T: git git://anongit.freedesktop.org/drm/drm-misc + USERSPACE I/O (UIO) M: Greg Kroah-Hartman S: Maintained diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index ed3b785bae37..338129eb126f 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -30,4 +30,12 @@ config SW_SYNC WARNING: improper use of this can result in deadlocking kernel drivers from userspace. Intended for test and debug only. +config UDMABUF + bool "userspace dmabuf misc driver" + default n + depends on DMA_SHARED_BUFFER + help + A driver to let userspace turn memfd regions into dma-bufs. + Qemu can use this to create host dmabufs for guest framebuffers. + endmenu diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index c33bf8863147..0913a6ccab5a 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,3 +1,4 @@ obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o obj-$(CONFIG_SYNC_FILE) += sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o +obj-$(CONFIG_UDMABUF) += udmabuf.o diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c new file mode 100644 index 000000000000..8e24204526cc --- /dev/null +++ b/drivers/dma-buf/udmabuf.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct udmabuf { + u32 pagecount; + struct page **pages; +}; + +static int udmabuf_vm_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct udmabuf *ubuf = vma->vm_private_data; + + if (WARN_ON(vmf->pgoff >= ubuf->pagecount)) + return VM_FAULT_SIGBUS; + + vmf->page = ubuf->pages[vmf->pgoff]; + get_page(vmf->page); + return 0; +} + +static const struct vm_operations_struct udmabuf_vm_ops = { + .fault = udmabuf_vm_fault, +}; + +static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) +{ + struct udmabuf *ubuf = buf->priv; + + if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) + return -EINVAL; + + vma->vm_ops = &udmabuf_vm_ops; + vma->vm_private_data = ubuf; + return 0; +} + +static struct sg_table *map_udmabuf(struct dma_buf_attachment *at, + enum dma_data_direction direction) +{ + struct udmabuf *ubuf = at->dmabuf->priv; + struct sg_table *sg; + + sg = kzalloc(sizeof(*sg), GFP_KERNEL); + if (!sg) + goto err1; + if (sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount, + 0, ubuf->pagecount << PAGE_SHIFT, + GFP_KERNEL) < 0) + goto err2; + if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) + goto err3; + + return sg; + +err3: + sg_free_table(sg); +err2: + kfree(sg); +err1: + return ERR_PTR(-ENOMEM); +} + +static void unmap_udmabuf(struct dma_buf_attachment *at, + struct sg_table *sg, + enum dma_data_direction direction) +{ + sg_free_table(sg); + kfree(sg); +} + +static void release_udmabuf(struct dma_buf *buf) +{ + struct udmabuf *ubuf = buf->priv; + pgoff_t pg; + + for (pg = 0; pg < ubuf->pagecount; pg++) + put_page(ubuf->pages[pg]); + kfree(ubuf->pages); + kfree(ubuf); +} + +static void *kmap_udmabuf(struct dma_buf *buf, unsigned long page_num) +{ + struct udmabuf *ubuf = buf->priv; + struct page *page = ubuf->pages[page_num]; + + return kmap(page); +} + +static void kunmap_udmabuf(struct dma_buf *buf, unsigned long page_num, + void *vaddr) +{ + kunmap(vaddr); +} + +static struct dma_buf_ops udmabuf_ops = { + .map_dma_buf = map_udmabuf, + .unmap_dma_buf = unmap_udmabuf, + .release = release_udmabuf, + .map = kmap_udmabuf, + .unmap = kunmap_udmabuf, + .mmap = mmap_udmabuf, +}; + +#define SEALS_WANTED (F_SEAL_SHRINK) +#define SEALS_DENIED (F_SEAL_WRITE) + +static long udmabuf_create(struct udmabuf_create_list *head, + struct udmabuf_create_item *list) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct file *memfd = NULL; + struct udmabuf *ubuf; + struct dma_buf *buf; + pgoff_t pgoff, pgcnt, pgidx, pgbuf; + struct page *page; + int seals, ret = -EINVAL; + u32 i, flags; + + ubuf = kzalloc(sizeof(struct udmabuf), GFP_KERNEL); + if (!ubuf) + return -ENOMEM; + + for (i = 0; i < head->count; i++) { + if (!IS_ALIGNED(list[i].offset, PAGE_SIZE)) + goto err_free_ubuf; + if (!IS_ALIGNED(list[i].size, PAGE_SIZE)) + goto err_free_ubuf; + ubuf->pagecount += list[i].size >> PAGE_SHIFT; + } + ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(struct page *), + GFP_KERNEL); + if (!ubuf->pages) { + ret = -ENOMEM; + goto err_free_ubuf; + } + + pgbuf = 0; + for (i = 0; i < head->count; i++) { + memfd = fget(list[i].memfd); + if (!memfd) + goto err_put_pages; + if (!shmem_mapping(file_inode(memfd)->i_mapping)) + goto err_put_pages; + seals = memfd_fcntl(memfd, F_GET_SEALS, 0); + if (seals == -EINVAL || + (seals & SEALS_WANTED) != SEALS_WANTED || + (seals & SEALS_DENIED) != 0) + goto err_put_pages; + pgoff = list[i].offset >> PAGE_SHIFT; + pgcnt = list[i].size >> PAGE_SHIFT; + for (pgidx = 0; pgidx < pgcnt; pgidx++) { + page = shmem_read_mapping_page( + file_inode(memfd)->i_mapping, pgoff + pgidx); + if (IS_ERR(page)) { + ret = PTR_ERR(page); + goto err_put_pages; + } + ubuf->pages[pgbuf++] = page; + } + fput(memfd); + } + memfd = NULL; + + exp_info.ops = &udmabuf_ops; + exp_info.size = ubuf->pagecount << PAGE_SHIFT; + exp_info.priv = ubuf; + + buf = dma_buf_export(&exp_info); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); + goto err_put_pages; + } + + flags = 0; + if (head->flags & UDMABUF_FLAGS_CLOEXEC) + flags |= O_CLOEXEC; + return dma_buf_fd(buf, flags); + +err_put_pages: + while (pgbuf > 0) + put_page(ubuf->pages[--pgbuf]); +err_free_ubuf: + fput(memfd); + kfree(ubuf->pages); + kfree(ubuf); + return ret; +} + +static long udmabuf_ioctl_create(struct file *filp, unsigned long arg) +{ + struct udmabuf_create create; + struct udmabuf_create_list head; + struct udmabuf_create_item list; + + if (copy_from_user(&create, (void __user *)arg, + sizeof(struct udmabuf_create))) + return -EFAULT; + + head.flags = create.flags; + head.count = 1; + list.memfd = create.memfd; + list.offset = create.offset; + list.size = create.size; + + return udmabuf_create(&head, &list); +} + +static long udmabuf_ioctl_create_list(struct file *filp, unsigned long arg) +{ + struct udmabuf_create_list head; + struct udmabuf_create_item *list; + int ret = -EINVAL; + u32 lsize; + + if (copy_from_user(&head, (void __user *)arg, sizeof(head))) + return -EFAULT; + if (head.count > 1024) + return -EINVAL; + lsize = sizeof(struct udmabuf_create_item) * head.count; + list = memdup_user((void __user *)(arg + sizeof(head)), lsize); + if (IS_ERR(list)) + return PTR_ERR(list); + + ret = udmabuf_create(&head, list); + kfree(list); + return ret; +} + +static long udmabuf_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + long ret; + + switch (ioctl) { + case UDMABUF_CREATE: + ret = udmabuf_ioctl_create(filp, arg); + break; + case UDMABUF_CREATE_LIST: + ret = udmabuf_ioctl_create_list(filp, arg); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static const struct file_operations udmabuf_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = udmabuf_ioctl, +}; + +static struct miscdevice udmabuf_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "udmabuf", + .fops = &udmabuf_fops, +}; + +static int __init udmabuf_dev_init(void) +{ + return misc_register(&udmabuf_misc); +} + +static void __exit udmabuf_dev_exit(void) +{ + misc_deregister(&udmabuf_misc); +} + +module_init(udmabuf_dev_init) +module_exit(udmabuf_dev_exit) + +MODULE_AUTHOR("Gerd Hoffmann "); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h new file mode 100644 index 000000000000..46b6532ed855 --- /dev/null +++ b/include/uapi/linux/udmabuf.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_UDMABUF_H +#define _UAPI_LINUX_UDMABUF_H + +#include +#include + +#define UDMABUF_FLAGS_CLOEXEC 0x01 + +struct udmabuf_create { + __u32 memfd; + __u32 flags; + __u64 offset; + __u64 size; +}; + +struct udmabuf_create_item { + __u32 memfd; + __u32 __pad; + __u64 offset; + __u64 size; +}; + +struct udmabuf_create_list { + __u32 flags; + __u32 count; + struct udmabuf_create_item list[]; +}; + +#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create) +#define UDMABUF_CREATE_LIST _IOW('u', 0x43, struct udmabuf_create_list) + +#endif /* _UAPI_LINUX_UDMABUF_H */ diff --git a/tools/testing/selftests/drivers/dma-buf/Makefile b/tools/testing/selftests/drivers/dma-buf/Makefile new file mode 100644 index 000000000000..4154c3d7aa58 --- /dev/null +++ b/tools/testing/selftests/drivers/dma-buf/Makefile @@ -0,0 +1,5 @@ +CFLAGS += -I../../../../../usr/include/ + +TEST_GEN_PROGS := udmabuf + +include ../../lib.mk diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c b/tools/testing/selftests/drivers/dma-buf/udmabuf.c new file mode 100644 index 000000000000..376b1d6730bd --- /dev/null +++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define TEST_PREFIX "drivers/dma-buf/udmabuf" +#define NUM_PAGES 4 + +static int memfd_create(const char *name, unsigned int flags) +{ + return syscall(__NR_memfd_create, name, flags); +} + +int main(int argc, char *argv[]) +{ + struct udmabuf_create create; + int devfd, memfd, buf, ret; + off_t size; + void *mem; + + devfd = open("/dev/udmabuf", O_RDWR); + if (devfd < 0) { + printf("%s: [skip,no-udmabuf]\n", TEST_PREFIX); + exit(77); + } + + memfd = memfd_create("udmabuf-test", MFD_CLOEXEC); + if (memfd < 0) { + printf("%s: [skip,no-memfd]\n", TEST_PREFIX); + exit(77); + } + + size = getpagesize() * NUM_PAGES; + ret = ftruncate(memfd, size); + if (ret == -1) { + printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX); + exit(1); + } + + memset(&create, 0, sizeof(create)); + + /* should fail (offset not page aligned) */ + create.memfd = memfd; + create.offset = getpagesize()/2; + create.size = getpagesize(); + buf = ioctl(devfd, UDMABUF_CREATE, &create); + if (buf >= 0) { + printf("%s: [FAIL,test-1]\n", TEST_PREFIX); + exit(1); + } + + /* should fail (size not multiple of page) */ + create.memfd = memfd; + create.offset = 0; + create.size = getpagesize()/2; + buf = ioctl(devfd, UDMABUF_CREATE, &create); + if (buf >= 0) { + printf("%s: [FAIL,test-2]\n", TEST_PREFIX); + exit(1); + } + + /* should fail (not memfd) */ + create.memfd = 0; /* stdin */ + create.offset = 0; + create.size = size; + buf = ioctl(devfd, UDMABUF_CREATE, &create); + if (buf >= 0) { + printf("%s: [FAIL,test-3]\n", TEST_PREFIX); + exit(1); + } + + /* should work */ + create.memfd = memfd; + create.offset = 0; + create.size = size; + buf = ioctl(devfd, UDMABUF_CREATE, &create); + if (buf < 0) { + printf("%s: [FAIL,test-4]\n", TEST_PREFIX); + exit(1); + } + + fprintf(stderr, "%s: ok\n", TEST_PREFIX); + close(buf); + close(memfd); + close(devfd); + return 0; +} -- cgit v1.2.3 From b9a40816fef79a6053b9d601f50e852acdaafebd Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Tue, 4 Sep 2018 09:45:05 +0530 Subject: Document/gpu: Use new vm_fault_t type We have introduce new return type vm_fault_t for fault handler. Update the document for the same. Signed-off-by: Souptick Joarder Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180904041505.GA2712@jordon-HP-15-Notebook-PC --- Documentation/gpu/drm-mm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 21b6b72a9ba8..c3ae888b92ef 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -297,7 +297,7 @@ made up of several fields, the more interesting ones being: struct vm_operations_struct { void (*open)(struct vm_area_struct * area); void (*close)(struct vm_area_struct * area); - int (*fault)(struct vm_fault *vmf); + vm_fault_t (*fault)(struct vm_fault *vmf); }; -- cgit v1.2.3 From 69517c1798f31232f91d9b4f3d07540f9aea6a07 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 4 Sep 2018 12:40:45 +0800 Subject: dt-bindings: display: Add compatible for A64 DE2 display pipeline Allwinner A64 has a DE2 display pipeline. The TCONs are similar to the ones in A83T, but the mixers are new (similar to the later R40 SoC). This patch adds dt-binding documentation for A64 DE2 display pipeline. Signed-off-by: Jagan Teki Reviewed-by: Rob Herring [Icenowy: Refactor and also cover TCON1] Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180904044053.15425-4-icenowy@aosc.io --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index f8773ecb7525..7b79c5e3dffc 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -151,6 +151,8 @@ Required properties: * allwinner,sun8i-v3s-tcon * allwinner,sun9i-a80-tcon-lcd * allwinner,sun9i-a80-tcon-tv + * "allwinner,sun50i-a64-tcon-lcd", "allwinner,sun8i-a83t-tcon-lcd" + * "allwinner,sun50i-a64-tcon-tv", "allwinner,sun8i-a83t-tcon-tv" - reg: base address and size of memory-mapped region - interrupts: interrupt associated to this IP - clocks: phandles to the clocks feeding the TCON. @@ -370,6 +372,8 @@ Required properties: * allwinner,sun8i-a83t-de2-mixer-1 * allwinner,sun8i-h3-de2-mixer-0 * allwinner,sun8i-v3s-de2-mixer + * allwinner,sun50i-a64-de2-mixer-0 + * allwinner,sun50i-a64-de2-mixer-1 - reg: base address and size of the memory-mapped region. - clocks: phandles to the clocks feeding the mixer * bus: the mixer interface clock @@ -403,6 +407,7 @@ Required properties: * allwinner,sun8i-r40-display-engine * allwinner,sun8i-v3s-display-engine * allwinner,sun9i-a80-display-engine + * allwinner,sun50i-a64-display-engine - allwinner,pipelines: list of phandle to the display engine frontends (DE 1.0) or mixers (DE 2.0) available. -- cgit v1.2.3 From d9ac59978d0dab5c4e2141cd7d62edcbd79434ce Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 4 Sep 2018 12:40:48 +0800 Subject: dt-bindings: display: Add compatible for A64 HDMI The HDMI controller on Allwinner A64 is similar on the one on H3/H5/A83T (although the PHY is different with A83T). Add A64 compatible and append A83T compatible as fallback. Signed-off-by: Jagan Teki Reviewed-by: Rob Herring [Icenowy: refactor commit log] Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180904044053.15425-7-icenowy@aosc.io --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index 7b79c5e3dffc..fdb8fb29033f 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -78,6 +78,7 @@ Required properties: - compatible: value must be one of: * "allwinner,sun8i-a83t-dw-hdmi" + * "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi" - reg: base address and size of memory-mapped region - reg-io-width: See dw_hdmi.txt. Shall be 1. - interrupts: HDMI interrupt number -- cgit v1.2.3 From 50414b954ba647693db655fb753811dc895e8cbe Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 4 Sep 2018 12:40:51 +0800 Subject: dt-bindings: sun4i-drm: add HDMI VCC supply property for sun8i-dw-hdmi Allwiner SoCs with DesignWare HDMI controller all come with a "HVCC" pin, which is the VCC of HDMI part. Add a supply property to specify HVCC's regulator in the device tree. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180904044053.15425-10-icenowy@aosc.io --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index fdb8fb29033f..0bbb5d47f228 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -97,6 +97,9 @@ Required properties: first port should be the input endpoint. The second should be the output, usually to an HDMI connector. +Optional properties: + - hvcc-supply: the VCC power supply of the controller + DWC HDMI PHY ------------ -- cgit v1.2.3 From 428e15cc41e3603942edd4a1aa991127ce9eccea Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 30 Aug 2018 13:09:37 +0200 Subject: drm/rockchip: vop: add rk3188 vop definitions The rk3188 has 2 vops not using iommus which only output directly to a rgb interface per vop. So all other output modes like hdmi are provided by external brige chips. Signed-off-by: Heiko Stuebner Reviewed-by: Sandy Huang Acked-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20180830110937.1739-1-heiko@sntech.de --- .../bindings/display/rockchip/rockchip-vop.txt | 1 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 89 ++++++++++++++++++++++ drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 25 ++++++ 3 files changed, 115 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index 5de2a0f0d1f4..b79e5769f0ae 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt @@ -10,6 +10,7 @@ Required properties: "rockchip,rk3126-vop"; "rockchip,px30-vop-lit"; "rockchip,px30-vop-big"; + "rockchip,rk3188-vop"; "rockchip,rk3288-vop"; "rockchip,rk3368-vop"; "rockchip,rk3366-vop"; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 09910d3b01ce..a6db3cd5544b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -299,6 +299,93 @@ static const struct vop_data px30_vop_lit = { .win_size = ARRAY_SIZE(px30_vop_lit_win_data), }; +static const struct vop_scl_regs rk3188_win_scl = { + .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), + .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), + .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), + .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16), +}; + +static const struct vop_win_phy rk3188_win0_data = { + .scl = &rk3188_win_scl, + .data_formats = formats_win_full, + .nformats = ARRAY_SIZE(formats_win_full), + .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0), + .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3), + .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15), + .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0), + .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0), + .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0), +}; + +static const struct vop_win_phy rk3188_win1_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1), + .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6), + .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19), + /* no act_info on window1 */ + .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0), + .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0), + .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0), + .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16), +}; + +static const struct vop_modeset rk3188_modeset = { + .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), + .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0), + .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), + .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0), +}; + +static const struct vop_output rk3188_output = { + .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4), +}; + +static const struct vop_common rk3188_common = { + .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31), + .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30), + .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0), + .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0), + .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), +}; + +static const struct vop_win_data rk3188_vop_win_data[] = { + { .base = 0x00, .phy = &rk3188_win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = &rk3188_win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const int rk3188_vop_intrs[] = { + 0, + FS_INTR, + LINE_FLAG_INTR, + BUS_ERROR_INTR, +}; + +static const struct vop_intr rk3188_vop_intr = { + .intrs = rk3188_vop_intrs, + .nintrs = ARRAY_SIZE(rk3188_vop_intrs), + .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12), + .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0), + .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4), + .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8), +}; + +static const struct vop_data rk3188_vop = { + .intr = &rk3188_vop_intr, + .common = &rk3188_common, + .modeset = &rk3188_modeset, + .output = &rk3188_output, + .win = rk3188_vop_win_data, + .win_size = ARRAY_SIZE(rk3188_vop_win_data), + .feature = VOP_FEATURE_INTERNAL_RGB, +}; + static const struct vop_scl_extension rk3288_win_full_scl_ext = { .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), @@ -667,6 +754,8 @@ static const struct of_device_id vop_driver_dt_match[] = { .data = &px30_vop_big }, { .compatible = "rockchip,px30-vop-lit", .data = &px30_vop_lit }, + { .compatible = "rockchip,rk3188-vop", + .data = &rk3188_vop }, { .compatible = "rockchip,rk3288-vop", .data = &rk3288_vop }, { .compatible = "rockchip,rk3368-vop", diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index 71527cb73295..7348c68352ed 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -958,4 +958,29 @@ #define PX30_GAMMA_LUT_ADDR 0x00a00 /* px30 register definition end */ +/* rk3188 register definition */ +#define RK3188_SYS_CTRL 0x00 +#define RK3188_DSP_CTRL0 0x04 +#define RK3188_DSP_CTRL1 0x08 +#define RK3188_INT_STATUS 0x10 +#define RK3188_WIN0_YRGB_MST0 0x20 +#define RK3188_WIN0_CBR_MST0 0x24 +#define RK3188_WIN0_YRGB_MST1 0x28 +#define RK3188_WIN0_CBR_MST1 0x2c +#define RK3188_WIN_VIR 0x30 +#define RK3188_WIN0_ACT_INFO 0x34 +#define RK3188_WIN0_DSP_INFO 0x38 +#define RK3188_WIN0_DSP_ST 0x3c +#define RK3188_WIN0_SCL_FACTOR_YRGB 0x40 +#define RK3188_WIN0_SCL_FACTOR_CBR 0x44 +#define RK3188_WIN1_MST 0x4c +#define RK3188_WIN1_DSP_INFO 0x50 +#define RK3188_WIN1_DSP_ST 0x54 +#define RK3188_DSP_HTOTAL_HS_END 0x6c +#define RK3188_DSP_HACT_ST_END 0x70 +#define RK3188_DSP_VTOTAL_VS_END 0x74 +#define RK3188_DSP_VACT_ST_END 0x78 +#define RK3188_REG_CFG_DONE 0x90 +/* rk3188 register definition end */ + #endif /* _ROCKCHIP_VOP_REG_H */ -- cgit v1.2.3 From 3b0d1b65c19f6650dce40d0d188df415cd0b62d7 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 28 Aug 2018 00:14:58 -0700 Subject: remoteproc: qcom: adsp: Add SDM845 ADSP and CDSP support Add support for booting the Audio and Compute DSPs found in Qualcomm's SDM845 platform. As with the previous platforms the power rail handling needs to be updated once the appropriate support lands upstream. Acked-by: Rob Herring Tested-by: Sibi Sankar Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt | 2 ++ drivers/remoteproc/qcom_adsp_pil.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt index 728e4193f7a6..b7d058228185 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt @@ -10,6 +10,8 @@ on the Qualcomm ADSP Hexagon core. "qcom,msm8974-adsp-pil" "qcom,msm8996-adsp-pil" "qcom,msm8996-slpi-pil" + "qcom,sdm845-adsp-pas" + "qcom,sdm845-cdsp-pas" - interrupts-extended: Usage: required diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c index d4339a6da616..da2254ea1135 100644 --- a/drivers/remoteproc/qcom_adsp_pil.c +++ b/drivers/remoteproc/qcom_adsp_pil.c @@ -342,6 +342,16 @@ static const struct adsp_data adsp_resource_init = { .ssctl_id = 0x14, }; +static const struct adsp_data cdsp_resource_init = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", + .pas_id = 18, + .has_aggre2_clk = false, + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, +}; + static const struct adsp_data slpi_resource_init = { .crash_reason_smem = 424, .firmware_name = "slpi.mdt", @@ -356,6 +366,8 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init}, + { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init}, + { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, { }, }; MODULE_DEVICE_TABLE(of, adsp_of_match); -- cgit v1.2.3 From 897be9c0a747d32ec1c74742f3362d5db660318d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 30 Aug 2018 22:52:59 +0200 Subject: dt-bindings: iio: imu: st_lsm6dsx: add LSM6DSO device bindings Signed-off-by: Lorenzo Bianconi Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt index ef8a8566c63f..858a2898908a 100644 --- a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt @@ -7,6 +7,7 @@ Required properties: "st,lsm6dsl" "st,lsm6dsm" "st,ism330dlc" + "st,lsm6dso" - reg: i2c address of the sensor / spi cs line Optional properties: -- cgit v1.2.3 From 7ac346823bbb284e9e66a3d4044c108b99c7149c Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Thu, 6 Sep 2018 14:04:52 -0700 Subject: dt-bindings: iio: vadc: Fix documentation of 'reg' The documentation of Qualcomm's SPMI PMIC voltage ADC claims that the 'reg' property consists of two values, the SPMI address and the length of the controller's registers. However the SPMI bus to which it is added specifies "#size-cells = <0>;". Remove the controller register length from the documentation of the field and the example. Signed-off-by: Matthias Kaehlcke Reviewed-by: Douglas Anderson Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt index 8498f11d06cd..b3c86f4ac7cd 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt @@ -17,7 +17,7 @@ VADC node: - reg: Usage: required Value type: - Definition: VADC base address and length in the SPMI PMIC register map. + Definition: VADC base address in the SPMI PMIC register map. - #address-cells: Usage: required @@ -143,7 +143,7 @@ Example: /* VADC node */ pmic_vadc: vadc@3100 { compatible = "qcom,spmi-vadc"; - reg = <0x3100 0x100>; + reg = <0x3100>; interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3 From c0f87b3335100108ce80cda3e09f11c3a82f081a Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Tue, 4 Sep 2018 17:13:14 +0300 Subject: dt-bindings: adxl372: Document the adxl372 I2C bindings The adxl372 is designed to communicate in either SPI or I2C protocol. This patch adds the documentation of device tree bindings for adxl372 I2C. Signed-off-by: Stefan Popa Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/accel/adxl372.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/accel/adxl372.txt b/Documentation/devicetree/bindings/iio/accel/adxl372.txt index 9409984719e9..a289964756a7 100644 --- a/Documentation/devicetree/bindings/iio/accel/adxl372.txt +++ b/Documentation/devicetree/bindings/iio/accel/adxl372.txt @@ -4,14 +4,25 @@ http://www.analog.com/media/en/technical-documentation/data-sheets/adxl372.pdf Required properties: - compatible : should be "adi,adxl372" - - reg: SPI chip select number for the device + - reg: the I2C address or SPI chip select number for the device + +Required properties for SPI bus usage: - spi-max-frequency: Max SPI frequency to use Optional properties: - interrupts: interrupt mapping for IRQ as documented in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt -Example: +Example for a I2C device node: + + accelerometer@53 { + compatible = "adi,adxl372"; + reg = <0x53>; + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + }; + +Example for a SPI device node: accelerometer@0 { compatible = "adi,adxl372"; -- cgit v1.2.3 From d86552efe10a321a78ab3d093bbe9b8ecf778c4e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Sep 2018 15:57:09 +0200 Subject: drm/atomic: trim driver interface/docs Remove the kerneldoc and EXPORT_SYMBOL which aren't used and really shouldn't ever be used by drivers directly. Unfortunately this means we need to move the set_writeback_fb function around to avoid a forward decl. Acked-by: Heiko Stuebner Signed-off-by: Daniel Vetter Cc: David Airlie Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20180905135711.28370-5-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms.rst | 3 - drivers/gpu/drm/drm_atomic.c | 219 +++++++----------------------------------- include/drm/drm_atomic.h | 6 -- 3 files changed, 34 insertions(+), 194 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index f8f5bf11a6ca..3a9dd68b97c9 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -287,9 +287,6 @@ Atomic Mode Setting Function Reference .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :internal: - CRTC Abstraction ================ diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d0478abc01bd..f2c505d8ea57 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -464,30 +464,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, } EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); -/** - * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it - * @dev: DRM device - * @blob: a pointer to the member blob to be replaced - * @blob_id: ID of the new blob - * @expected_size: total expected size of the blob data (in bytes) - * @expected_elem_size: expected element size of the blob data (in bytes) - * @replaced: did the blob get replaced? - * - * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero - * @blob becomes NULL. - * - * If @expected_size is positive the new blob length is expected to be equal - * to @expected_size bytes. If @expected_elem_size is positive the new blob - * length is expected to be a multiple of @expected_elem_size bytes. Otherwise - * an error is returned. - * - * @replaced will indicate to the caller whether the blob was replaced or not. - * If the old and new blobs were in fact the same blob @replaced will be false - * otherwise it will be true. - * - * RETURNS: - * Zero on success, error code on failure. - */ static int drm_atomic_replace_property_blob_from_id(struct drm_device *dev, struct drm_property_blob **blob, @@ -521,22 +497,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev, return 0; } -/** - * drm_atomic_crtc_set_property - set property on CRTC - * @crtc: the drm CRTC to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_crtc_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ -int drm_atomic_crtc_set_property(struct drm_crtc *crtc, +static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, struct drm_crtc_state *state, struct drm_property *property, uint64_t val) { @@ -598,23 +559,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, return 0; } -EXPORT_SYMBOL(drm_atomic_crtc_set_property); -/** - * drm_atomic_crtc_get_property - get property value from CRTC state - * @crtc: the drm CRTC to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_crtc_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_crtc_get_property(struct drm_crtc *crtc, const struct drm_crtc_state *state, @@ -643,16 +588,6 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, return 0; } -/** - * drm_atomic_crtc_check - check crtc state - * @crtc: crtc to check - * @state: crtc state to check - * - * Provides core sanity checks for crtc state. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -728,16 +663,6 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, crtc->funcs->atomic_print_state(p, state); } -/** - * drm_atomic_connector_check - check connector state - * @connector: connector to check - * @state: connector state to check - * - * Provides core sanity checks for connector state. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_connector_check(struct drm_connector *connector, struct drm_connector_state *state) { @@ -923,21 +848,6 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, return 0; } -/** - * drm_atomic_plane_get_property - get property value from plane state - * @plane: the drm plane to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_plane_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_plane_get_property(struct drm_plane *plane, const struct drm_plane_state *state, @@ -1328,21 +1238,39 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_connector_state); -/** - * drm_atomic_connector_set_property - set property on connector. - * @connector: the drm connector to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_connector_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ +static struct drm_writeback_job * +drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) +{ + WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); + + if (!conn_state->writeback_job) + conn_state->writeback_job = + kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); + + return conn_state->writeback_job; +} + +static int drm_atomic_set_writeback_fb_for_connector( + struct drm_connector_state *conn_state, + struct drm_framebuffer *fb) +{ + struct drm_writeback_job *job = + drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + drm_framebuffer_assign(&job->fb, fb); + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", + fb->base.id, conn_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", + conn_state); + + return 0; +} + static int drm_atomic_connector_set_property(struct drm_connector *connector, struct drm_connector_state *state, struct drm_property *property, uint64_t val) @@ -1449,21 +1377,6 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, connector->funcs->atomic_print_state(p, state); } -/** - * drm_atomic_connector_get_property - get property value from connector state - * @connector: the drm connector to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_connector_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_connector_get_property(struct drm_connector *connector, const struct drm_connector_state *state, @@ -1739,70 +1652,6 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, } EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); -/* - * drm_atomic_get_writeback_job - return or allocate a writeback job - * @conn_state: Connector state to get the job for - * - * Writeback jobs have a different lifetime to the atomic state they are - * associated with. This convenience function takes care of allocating a job - * if there isn't yet one associated with the connector state, otherwise - * it just returns the existing job. - * - * Returns: The writeback job for the given connector state - */ -static struct drm_writeback_job * -drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) -{ - WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); - - if (!conn_state->writeback_job) - conn_state->writeback_job = - kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); - - return conn_state->writeback_job; -} - -/** - * drm_atomic_set_writeback_fb_for_connector - set writeback framebuffer - * @conn_state: atomic state object for the connector - * @fb: fb to use for the connector - * - * This is used to set the framebuffer for a writeback connector, which outputs - * to a buffer instead of an actual physical connector. - * Changing the assigned framebuffer requires us to grab a reference to the new - * fb and drop the reference to the old fb, if there is one. This function - * takes care of all these details besides updating the pointer in the - * state object itself. - * - * Note: The only way conn_state can already have an fb set is if the commit - * sets the property more than once. - * - * See also: drm_writeback_connector_init() - * - * Returns: 0 on success - */ -int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb) -{ - struct drm_writeback_job *job = - drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - drm_framebuffer_assign(&job->fb, fb); - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", - fb->base.id, conn_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", - conn_state); - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_writeback_fb_for_connector); - /** * drm_atomic_add_affected_connectors - add connectors for crtc * @state: atomic state diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index d621232a469a..93d29af34024 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -374,9 +374,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state); struct drm_crtc_state * __must_check drm_atomic_get_crtc_state(struct drm_atomic_state *state, struct drm_crtc *crtc); -int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - struct drm_crtc_state *state, struct drm_property *property, - uint64_t val); struct drm_plane_state * __must_check drm_atomic_get_plane_state(struct drm_atomic_state *state, struct drm_plane *plane); @@ -603,9 +600,6 @@ void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, int __must_check drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc); -int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb); int __must_check drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc); -- cgit v1.2.3 From 2ec04b33a96fe954701ceecfd0b489978f667b34 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Sep 2018 20:15:09 +0200 Subject: drm: Update todo.rst - drmP.h is now fully split up. - vkms is happening (and will gain its own todo and docs under a new vkms.rst file real soon) - legacy cruft is completely hidden now, drm_vblank.c is split out from drm_irq.c now. I've decided to drop the task to split out drm_legacy.ko, partially because Dave already rejected a patch to hide the old dri1 drivers better. Current state feels good enough to me. - best_encoder atomic cleanup is done (it's now the default, not even exported anymore) - bunch of smaller things v2: - Explain why the drm_legacy.ko task is dropped (Emil). - typos (Sam). v3: Fix typo (Ilia) Reviewed-by: Emil Velikov Reviewed-by: Heiko Stuebner Cc: Ilia Mirkin Cc: Sam Ravnborg Cc: Emil Velikov Signed-off-by: Daniel Vetter Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: David Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20180905181509.19530-1-daniel.vetter@ffwll.ch --- Documentation/gpu/todo.rst | 68 +++++++--------------------------------------- 1 file changed, 10 insertions(+), 58 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index a7c150d6b63f..4c7c3ab60089 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -127,7 +127,8 @@ interfaces to fix these issues: the acquire context explicitly on stack and then also pass it down into drivers explicitly so that the legacy-on-atomic functions can use them. - Except for some driver code this is done. + Except for some driver code this is done. This task should be finished by + adding WARN_ON(!drm_drv_uses_atomic_modeset) in drm_modeset_lock_all(). * A bunch of the vtable hooks are now in the wrong place: DRM has a split between core vfunc tables (named ``drm_foo_funcs``), which are used to @@ -137,13 +138,6 @@ interfaces to fix these issues: ``_helper_funcs`` since they are not part of the core ABI. There's a ``FIXME`` comment in the kerneldoc for each such case in ``drm_crtc.h``. -* There's a new helper ``drm_atomic_helper_best_encoder()`` which could be - used by all atomic drivers which don't select the encoder for a given - connector at runtime. That's almost all of them, and would allow us to get - rid of a lot of ``best_encoder`` boilerplate in drivers. - - This was almost done, but new drivers added a few more cases again. - Contact: Daniel Vetter Get rid of dev->struct_mutex from GEM drivers @@ -164,9 +158,8 @@ private lock. The tricky part is the BO free functions, since those can't reliably take that lock any more. Instead state needs to be protected with suitable subordinate locks or some cleanup work pushed to a worker thread. For performance-critical drivers it might also be better to go with a more -fine-grained per-buffer object and per-context lockings scheme. Currently the -following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and -``udl``. +fine-grained per-buffer object and per-context lockings scheme. Currently only the +``msm`` driver still use ``struct_mutex``. Contact: Daniel Vetter, respective driver maintainers @@ -190,7 +183,8 @@ Convert drivers to use simple modeset suspend/resume Most drivers (except i915 and nouveau) that use drm_atomic_helper_suspend/resume() can probably be converted to use -drm_mode_config_helper_suspend/resume(). +drm_mode_config_helper_suspend/resume(). Also there's still open-coded version +of the atomic suspend/resume code in older atomic modeset drivers. Contact: Maintainer of the driver you plan to convert @@ -246,20 +240,10 @@ Core refactorings Clean up the DRM header mess ---------------------------- -Currently the DRM subsystem has only one global header, ``drmP.h``. This is -used both for functions exported to helper libraries and drivers and functions -only used internally in the ``drm.ko`` module. The goal would be to move all -header declarations not needed outside of ``drm.ko`` into -``drivers/gpu/drm/drm_*_internal.h`` header files. ``EXPORT_SYMBOL`` also -needs to be dropped for these functions. - -This would nicely tie in with the below task to create kerneldoc after the API -is cleaned up. Or with the "hide legacy cruft better" task. - -Note that this is well in progress, but ``drmP.h`` is still huge. The updated -plan is to switch to per-file driver API headers, which will also structure -the kerneldoc better. This should also allow more fine-grained ``#include`` -directives. +The DRM subsystem originally had only one huge global header, ``drmP.h``. This +is now split up, but many source files still include it. The remaining part of +the cleanup work here is to replace any ``#include `` by only the +headers needed (and fixing up any missing pre-declarations in the headers). In the end no .c file should need to include ``drmP.h`` anymore. @@ -278,26 +262,6 @@ See https://dri.freedesktop.org/docs/drm/ for what's there already. Contact: Daniel Vetter -Hide legacy cruft better ------------------------- - -Way back DRM supported only drivers which shadow-attached to PCI devices with -userspace or fbdev drivers setting up outputs. Modern DRM drivers take charge -of the entire device, you can spot them with the DRIVER_MODESET flag. - -Unfortunately there's still large piles of legacy code around which needs to -be hidden so that driver writers don't accidentally end up using it. And to -prevent security issues in those legacy IOCTLs from being exploited on modern -drivers. This has multiple possible subtasks: - -* Extract support code for legacy features into a ``drm-legacy.ko`` kernel - module and compile it only when one of the legacy drivers is enabled. - -This is mostly done, the only thing left is to split up ``drm_irq.c`` into -legacy cruft and the parts needed by modern KMS drivers. - -Contact: Daniel Vetter - Make panic handling work ------------------------ @@ -398,18 +362,6 @@ the non-i915 specific modeset tests. Contact: Daniel Vetter -Create a virtual KMS driver for testing (vkms) ----------------------------------------------- - -With all the latest helpers it should be fairly simple to create a virtual KMS -driver useful for testing, or for running X or similar on headless machines -(to be able to still use the GPU). This would be similar to vgem, but aimed at -the modeset side. - -Once the basics are there there's tons of possibilities to extend it. - -Contact: Daniel Vetter - Driver Specific =============== -- cgit v1.2.3 From 72fdb40c1a4b48f5fa6f6083ea7419b94639ed57 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Sep 2018 15:57:11 +0200 Subject: drm: extract drm_atomic_uapi.c This leaves all the commit/check and state handling in drm_atomic.c, while pulling all the uapi glue and the huge ioctl itself into a seprate file. This seems to almost perfectly split the rather big drm_atomic.c file into 2 equal sizes. Also adjust the kerneldoc and type a very terse overview text. v2: Rebase. v3: Fix tiny typo. v4: - Fixup armada, newly converted atomic driver hooray! - Fixup msm/dpu1, newly added too. Signed-off-by: Daniel Vetter Cc: David Airlie Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Rob Clark Cc: Eric Anholt Cc: intel-gfx@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Acked-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180905135711.28370-7-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms.rst | 11 +- drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/drm_atomic.c | 1359 +------------------------ drivers/gpu/drm/drm_atomic_helper.c | 1 + drivers/gpu/drm/drm_atomic_uapi.c | 1393 ++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_helper.c | 1 + drivers/gpu/drm/drm_crtc_internal.h | 5 + drivers/gpu/drm/drm_framebuffer.c | 1 + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 1 + drivers/gpu/drm/drm_plane_helper.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 + drivers/gpu/drm/msm/msm_atomic.c | 2 + drivers/gpu/drm/vc4/vc4_crtc.c | 1 + drivers/gpu/drm/vc4/vc4_plane.c | 1 + include/drm/drm_atomic.h | 16 - include/drm/drm_atomic_uapi.h | 58 ++ 18 files changed, 1483 insertions(+), 1375 deletions(-) create mode 100644 drivers/gpu/drm/drm_atomic_uapi.c create mode 100644 include/drm/drm_atomic_uapi.h (limited to 'Documentation') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 3a9dd68b97c9..4b1501b4835b 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -287,6 +287,15 @@ Atomic Mode Setting Function Reference .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: +Atomic Mode Setting IOCTL and UAPI Functions +-------------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c + :export: + CRTC Abstraction ================ @@ -563,7 +572,7 @@ Tile Group Property Explicit Fencing Properties --------------------------- -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c :doc: explicit fencing properties Existing KMS Properties diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index a6771cef85e2..bc6a16a3c36e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -18,7 +18,8 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_encoder.o drm_mode_object.o drm_property.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ - drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o + drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ + drm_atomic_uapi.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index eb7dfb65ef47..8d770641fcc4 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -8,6 +8,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f2c505d8ea57..7ada75919756 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -309,285 +310,6 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_crtc_state); -static void set_out_fence_for_crtc(struct drm_atomic_state *state, - struct drm_crtc *crtc, s32 __user *fence_ptr) -{ - state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr; -} - -static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state, - struct drm_crtc *crtc) -{ - s32 __user *fence_ptr; - - fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr; - state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL; - - return fence_ptr; -} - -static int set_out_fence_for_connector(struct drm_atomic_state *state, - struct drm_connector *connector, - s32 __user *fence_ptr) -{ - unsigned int index = drm_connector_index(connector); - - if (!fence_ptr) - return 0; - - if (put_user(-1, fence_ptr)) - return -EFAULT; - - state->connectors[index].out_fence_ptr = fence_ptr; - - return 0; -} - -static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state, - struct drm_connector *connector) -{ - unsigned int index = drm_connector_index(connector); - s32 __user *fence_ptr; - - fence_ptr = state->connectors[index].out_fence_ptr; - state->connectors[index].out_fence_ptr = NULL; - - return fence_ptr; -} - -/** - * drm_atomic_set_mode_for_crtc - set mode for CRTC - * @state: the CRTC whose incoming state to update - * @mode: kernel-internal mode to use for the CRTC, or NULL to disable - * - * Set a mode (originating from the kernel) on the desired CRTC state and update - * the enable property. - * - * RETURNS: - * Zero on success, error code on failure. Cannot return -EDEADLK. - */ -int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, - const struct drm_display_mode *mode) -{ - struct drm_crtc *crtc = state->crtc; - struct drm_mode_modeinfo umode; - - /* Early return for no change. */ - if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) - return 0; - - drm_property_blob_put(state->mode_blob); - state->mode_blob = NULL; - - if (mode) { - drm_mode_convert_to_umode(&umode, mode); - state->mode_blob = - drm_property_create_blob(state->crtc->dev, - sizeof(umode), - &umode); - if (IS_ERR(state->mode_blob)) - return PTR_ERR(state->mode_blob); - - drm_mode_copy(&state->mode, mode); - state->enable = true; - DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", - mode->name, crtc->base.id, crtc->name, state); - } else { - memset(&state->mode, 0, sizeof(state->mode)); - state->enable = false; - DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", - crtc->base.id, crtc->name, state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); - -/** - * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC - * @state: the CRTC whose incoming state to update - * @blob: pointer to blob property to use for mode - * - * Set a mode (originating from a blob property) on the desired CRTC state. - * This function will take a reference on the blob property for the CRTC state, - * and release the reference held on the state's existing mode property, if any - * was set. - * - * RETURNS: - * Zero on success, error code on failure. Cannot return -EDEADLK. - */ -int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, - struct drm_property_blob *blob) -{ - struct drm_crtc *crtc = state->crtc; - - if (blob == state->mode_blob) - return 0; - - drm_property_blob_put(state->mode_blob); - state->mode_blob = NULL; - - memset(&state->mode, 0, sizeof(state->mode)); - - if (blob) { - int ret; - - if (blob->length != sizeof(struct drm_mode_modeinfo)) { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] bad mode blob length: %zu\n", - crtc->base.id, crtc->name, - blob->length); - return -EINVAL; - } - - ret = drm_mode_convert_umode(crtc->dev, - &state->mode, blob->data); - if (ret) { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] invalid mode (ret=%d, status=%s):\n", - crtc->base.id, crtc->name, - ret, drm_get_mode_status_name(state->mode.status)); - drm_mode_debug_printmodeline(&state->mode); - return -EINVAL; - } - - state->mode_blob = drm_property_blob_get(blob); - state->enable = true; - DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", - state->mode.name, crtc->base.id, crtc->name, - state); - } else { - state->enable = false; - DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", - crtc->base.id, crtc->name, state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); - -static int -drm_atomic_replace_property_blob_from_id(struct drm_device *dev, - struct drm_property_blob **blob, - uint64_t blob_id, - ssize_t expected_size, - ssize_t expected_elem_size, - bool *replaced) -{ - struct drm_property_blob *new_blob = NULL; - - if (blob_id != 0) { - new_blob = drm_property_lookup_blob(dev, blob_id); - if (new_blob == NULL) - return -EINVAL; - - if (expected_size > 0 && - new_blob->length != expected_size) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - if (expected_elem_size > 0 && - new_blob->length % expected_elem_size != 0) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - } - - *replaced |= drm_property_replace_blob(blob, new_blob); - drm_property_blob_put(new_blob); - - return 0; -} - -static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - struct drm_crtc_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *config = &dev->mode_config; - bool replaced = false; - int ret; - - if (property == config->prop_active) - state->active = val; - else if (property == config->prop_mode_id) { - struct drm_property_blob *mode = - drm_property_lookup_blob(dev, val); - ret = drm_atomic_set_mode_prop_for_crtc(state, mode); - drm_property_blob_put(mode); - return ret; - } else if (property == config->degamma_lut_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->degamma_lut, - val, - -1, sizeof(struct drm_color_lut), - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->ctm_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->ctm, - val, - sizeof(struct drm_color_ctm), -1, - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->gamma_lut_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->gamma_lut, - val, - -1, sizeof(struct drm_color_lut), - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->prop_out_fence_ptr) { - s32 __user *fence_ptr = u64_to_user_ptr(val); - - if (!fence_ptr) - return 0; - - if (put_user(-1, fence_ptr)) - return -EFAULT; - - set_out_fence_for_crtc(state->state, crtc, fence_ptr); - } else if (crtc->funcs->atomic_set_property) { - return crtc->funcs->atomic_set_property(crtc, state, property, val); - } else { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n", - crtc->base.id, crtc->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - -static int -drm_atomic_crtc_get_property(struct drm_crtc *crtc, - const struct drm_crtc_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_active) - *val = state->active; - else if (property == config->prop_mode_id) - *val = (state->mode_blob) ? state->mode_blob->base.id : 0; - else if (property == config->degamma_lut_property) - *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; - else if (property == config->ctm_property) - *val = (state->ctm) ? state->ctm->base.id : 0; - else if (property == config->gamma_lut_property) - *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; - else if (property == config->prop_out_fence_ptr) - *val = 0; - else if (crtc->funcs->atomic_get_property) - return crtc->funcs->atomic_get_property(crtc, state, property, val); - else - return -EINVAL; - - return 0; -} - static int drm_atomic_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -761,144 +483,6 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_plane_state); -/** - * drm_atomic_plane_set_property - set property on plane - * @plane: the drm plane to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_plane_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ -static int drm_atomic_plane_set_property(struct drm_plane *plane, - struct drm_plane_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = plane->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_fb_id) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); - drm_atomic_set_fb_for_plane(state, fb); - if (fb) - drm_framebuffer_put(fb); - } else if (property == config->prop_in_fence_fd) { - if (state->fence) - return -EINVAL; - - if (U642I64(val) == -1) - return 0; - - state->fence = sync_file_get_fence(val); - if (!state->fence) - return -EINVAL; - - } else if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); - return drm_atomic_set_crtc_for_plane(state, crtc); - } else if (property == config->prop_crtc_x) { - state->crtc_x = U642I64(val); - } else if (property == config->prop_crtc_y) { - state->crtc_y = U642I64(val); - } else if (property == config->prop_crtc_w) { - state->crtc_w = val; - } else if (property == config->prop_crtc_h) { - state->crtc_h = val; - } else if (property == config->prop_src_x) { - state->src_x = val; - } else if (property == config->prop_src_y) { - state->src_y = val; - } else if (property == config->prop_src_w) { - state->src_w = val; - } else if (property == config->prop_src_h) { - state->src_h = val; - } else if (property == plane->alpha_property) { - state->alpha = val; - } else if (property == plane->blend_mode_property) { - state->pixel_blend_mode = val; - } else if (property == plane->rotation_property) { - if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) { - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 0x%llx\n", - plane->base.id, plane->name, val); - return -EINVAL; - } - state->rotation = val; - } else if (property == plane->zpos_property) { - state->zpos = val; - } else if (property == plane->color_encoding_property) { - state->color_encoding = val; - } else if (property == plane->color_range_property) { - state->color_range = val; - } else if (plane->funcs->atomic_set_property) { - return plane->funcs->atomic_set_property(plane, state, - property, val); - } else { - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", - plane->base.id, plane->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - -static int -drm_atomic_plane_get_property(struct drm_plane *plane, - const struct drm_plane_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = plane->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_fb_id) { - *val = (state->fb) ? state->fb->base.id : 0; - } else if (property == config->prop_in_fence_fd) { - *val = -1; - } else if (property == config->prop_crtc_id) { - *val = (state->crtc) ? state->crtc->base.id : 0; - } else if (property == config->prop_crtc_x) { - *val = I642U64(state->crtc_x); - } else if (property == config->prop_crtc_y) { - *val = I642U64(state->crtc_y); - } else if (property == config->prop_crtc_w) { - *val = state->crtc_w; - } else if (property == config->prop_crtc_h) { - *val = state->crtc_h; - } else if (property == config->prop_src_x) { - *val = state->src_x; - } else if (property == config->prop_src_y) { - *val = state->src_y; - } else if (property == config->prop_src_w) { - *val = state->src_w; - } else if (property == config->prop_src_h) { - *val = state->src_h; - } else if (property == plane->alpha_property) { - *val = state->alpha; - } else if (property == plane->blend_mode_property) { - *val = state->pixel_blend_mode; - } else if (property == plane->rotation_property) { - *val = state->rotation; - } else if (property == plane->zpos_property) { - *val = state->zpos; - } else if (property == plane->color_encoding_property) { - *val = state->color_encoding; - } else if (property == plane->color_range_property) { - *val = state->color_range; - } else if (plane->funcs->atomic_get_property) { - return plane->funcs->atomic_get_property(plane, state, property, val); - } else { - return -EINVAL; - } - - return 0; -} - static bool plane_switching_crtc(struct drm_atomic_state *state, struct drm_plane *plane, @@ -1238,129 +822,6 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_connector_state); -static struct drm_writeback_job * -drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) -{ - WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); - - if (!conn_state->writeback_job) - conn_state->writeback_job = - kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); - - return conn_state->writeback_job; -} - -static int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb) -{ - struct drm_writeback_job *job = - drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - drm_framebuffer_assign(&job->fb, fb); - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", - fb->base.id, conn_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", - conn_state); - - return 0; -} - -static int drm_atomic_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = connector->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); - return drm_atomic_set_crtc_for_connector(state, crtc); - } else if (property == config->dpms_property) { - /* setting DPMS property requires special handling, which - * is done in legacy setprop path for us. Disallow (for - * now?) atomic writes to DPMS property: - */ - return -EINVAL; - } else if (property == config->tv_select_subconnector_property) { - state->tv.subconnector = val; - } else if (property == config->tv_left_margin_property) { - state->tv.margins.left = val; - } else if (property == config->tv_right_margin_property) { - state->tv.margins.right = val; - } else if (property == config->tv_top_margin_property) { - state->tv.margins.top = val; - } else if (property == config->tv_bottom_margin_property) { - state->tv.margins.bottom = val; - } else if (property == config->tv_mode_property) { - state->tv.mode = val; - } else if (property == config->tv_brightness_property) { - state->tv.brightness = val; - } else if (property == config->tv_contrast_property) { - state->tv.contrast = val; - } else if (property == config->tv_flicker_reduction_property) { - state->tv.flicker_reduction = val; - } else if (property == config->tv_overscan_property) { - state->tv.overscan = val; - } else if (property == config->tv_saturation_property) { - state->tv.saturation = val; - } else if (property == config->tv_hue_property) { - state->tv.hue = val; - } else if (property == config->link_status_property) { - /* Never downgrade from GOOD to BAD on userspace's request here, - * only hw issues can do that. - * - * For an atomic property the userspace doesn't need to be able - * to understand all the properties, but needs to be able to - * restore the state it wants on VT switch. So if the userspace - * tries to change the link_status from GOOD to BAD, driver - * silently rejects it and returns a 0. This prevents userspace - * from accidently breaking the display when it restores the - * state. - */ - if (state->link_status != DRM_LINK_STATUS_GOOD) - state->link_status = val; - } else if (property == config->aspect_ratio_property) { - state->picture_aspect_ratio = val; - } else if (property == config->content_type_property) { - state->content_type = val; - } else if (property == connector->scaling_mode_property) { - state->scaling_mode = val; - } else if (property == connector->content_protection_property) { - if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); - return -EINVAL; - } - state->content_protection = val; - } else if (property == config->writeback_fb_id_property) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); - int ret = drm_atomic_set_writeback_fb_for_connector(state, fb); - if (fb) - drm_framebuffer_put(fb); - return ret; - } else if (property == config->writeback_out_fence_ptr_property) { - s32 __user *fence_ptr = u64_to_user_ptr(val); - - return set_out_fence_for_connector(state->state, connector, - fence_ptr); - } else if (connector->funcs->atomic_set_property) { - return connector->funcs->atomic_set_property(connector, - state, property, val); - } else { - DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]]\n", - connector->base.id, connector->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - static void drm_atomic_connector_print_state(struct drm_printer *p, const struct drm_connector_state *state) { @@ -1377,281 +838,6 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, connector->funcs->atomic_print_state(p, state); } -static int -drm_atomic_connector_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = connector->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_crtc_id) { - *val = (state->crtc) ? state->crtc->base.id : 0; - } else if (property == config->dpms_property) { - *val = connector->dpms; - } else if (property == config->tv_select_subconnector_property) { - *val = state->tv.subconnector; - } else if (property == config->tv_left_margin_property) { - *val = state->tv.margins.left; - } else if (property == config->tv_right_margin_property) { - *val = state->tv.margins.right; - } else if (property == config->tv_top_margin_property) { - *val = state->tv.margins.top; - } else if (property == config->tv_bottom_margin_property) { - *val = state->tv.margins.bottom; - } else if (property == config->tv_mode_property) { - *val = state->tv.mode; - } else if (property == config->tv_brightness_property) { - *val = state->tv.brightness; - } else if (property == config->tv_contrast_property) { - *val = state->tv.contrast; - } else if (property == config->tv_flicker_reduction_property) { - *val = state->tv.flicker_reduction; - } else if (property == config->tv_overscan_property) { - *val = state->tv.overscan; - } else if (property == config->tv_saturation_property) { - *val = state->tv.saturation; - } else if (property == config->tv_hue_property) { - *val = state->tv.hue; - } else if (property == config->link_status_property) { - *val = state->link_status; - } else if (property == config->aspect_ratio_property) { - *val = state->picture_aspect_ratio; - } else if (property == config->content_type_property) { - *val = state->content_type; - } else if (property == connector->scaling_mode_property) { - *val = state->scaling_mode; - } else if (property == connector->content_protection_property) { - *val = state->content_protection; - } else if (property == config->writeback_fb_id_property) { - /* Writeback framebuffer is one-shot, write and forget */ - *val = 0; - } else if (property == config->writeback_out_fence_ptr_property) { - *val = 0; - } else if (connector->funcs->atomic_get_property) { - return connector->funcs->atomic_get_property(connector, - state, property, val); - } else { - return -EINVAL; - } - - return 0; -} - -int drm_atomic_get_property(struct drm_mode_object *obj, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = property->dev; - int ret; - - switch (obj->type) { - case DRM_MODE_OBJECT_CONNECTOR: { - struct drm_connector *connector = obj_to_connector(obj); - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - ret = drm_atomic_connector_get_property(connector, - connector->state, property, val); - break; - } - case DRM_MODE_OBJECT_CRTC: { - struct drm_crtc *crtc = obj_to_crtc(obj); - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - ret = drm_atomic_crtc_get_property(crtc, - crtc->state, property, val); - break; - } - case DRM_MODE_OBJECT_PLANE: { - struct drm_plane *plane = obj_to_plane(obj); - WARN_ON(!drm_modeset_is_locked(&plane->mutex)); - ret = drm_atomic_plane_get_property(plane, - plane->state, property, val); - break; - } - default: - ret = -EINVAL; - break; - } - - return ret; -} - -/** - * drm_atomic_set_crtc_for_plane - set crtc for plane - * @plane_state: the plane whose incoming state to update - * @crtc: crtc to use for the plane - * - * Changing the assigned crtc for a plane requires us to grab the lock and state - * for the new crtc, as needed. This function takes care of all these details - * besides updating the pointer in the state object itself. - * - * Returns: - * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK - * then the w/w mutex code has detected a deadlock and the entire atomic - * sequence must be restarted. All other errors are fatal. - */ -int -drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, - struct drm_crtc *crtc) -{ - struct drm_plane *plane = plane_state->plane; - struct drm_crtc_state *crtc_state; - /* Nothing to do for same crtc*/ - if (plane_state->crtc == crtc) - return 0; - if (plane_state->crtc) { - crtc_state = drm_atomic_get_crtc_state(plane_state->state, - plane_state->crtc); - if (WARN_ON(IS_ERR(crtc_state))) - return PTR_ERR(crtc_state); - - crtc_state->plane_mask &= ~drm_plane_mask(plane); - } - - plane_state->crtc = crtc; - - if (crtc) { - crtc_state = drm_atomic_get_crtc_state(plane_state->state, - crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - crtc_state->plane_mask |= drm_plane_mask(plane); - } - - if (crtc) - DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [CRTC:%d:%s]\n", - plane->base.id, plane->name, plane_state, - crtc->base.id, crtc->name); - else - DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [NOCRTC]\n", - plane->base.id, plane->name, plane_state); - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane); - -/** - * drm_atomic_set_fb_for_plane - set framebuffer for plane - * @plane_state: atomic state object for the plane - * @fb: fb to use for the plane - * - * Changing the assigned framebuffer for a plane requires us to grab a reference - * to the new fb and drop the reference to the old fb, if there is one. This - * function takes care of all these details besides updating the pointer in the - * state object itself. - */ -void -drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, - struct drm_framebuffer *fb) -{ - struct drm_plane *plane = plane_state->plane; - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for [PLANE:%d:%s] state %p\n", - fb->base.id, plane->base.id, plane->name, - plane_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for [PLANE:%d:%s] state %p\n", - plane->base.id, plane->name, plane_state); - - drm_framebuffer_assign(&plane_state->fb, fb); -} -EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); - -/** - * drm_atomic_set_fence_for_plane - set fence for plane - * @plane_state: atomic state object for the plane - * @fence: dma_fence to use for the plane - * - * Helper to setup the plane_state fence in case it is not set yet. - * By using this drivers doesn't need to worry if the user choose - * implicit or explicit fencing. - * - * This function will not set the fence to the state if it was set - * via explicit fencing interfaces on the atomic ioctl. In that case it will - * drop the reference to the fence as we are not storing it anywhere. - * Otherwise, if &drm_plane_state.fence is not set this function we just set it - * with the received implicit fence. In both cases this function consumes a - * reference for @fence. - * - * This way explicit fencing can be used to overrule implicit fencing, which is - * important to make explicit fencing use-cases work: One example is using one - * buffer for 2 screens with different refresh rates. Implicit fencing will - * clamp rendering to the refresh rate of the slower screen, whereas explicit - * fence allows 2 independent render and display loops on a single buffer. If a - * driver allows obeys both implicit and explicit fences for plane updates, then - * it will break all the benefits of explicit fencing. - */ -void -drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, - struct dma_fence *fence) -{ - if (plane_state->fence) { - dma_fence_put(fence); - return; - } - - plane_state->fence = fence; -} -EXPORT_SYMBOL(drm_atomic_set_fence_for_plane); - -/** - * drm_atomic_set_crtc_for_connector - set crtc for connector - * @conn_state: atomic state object for the connector - * @crtc: crtc to use for the connector - * - * Changing the assigned crtc for a connector requires us to grab the lock and - * state for the new crtc, as needed. This function takes care of all these - * details besides updating the pointer in the state object itself. - * - * Returns: - * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK - * then the w/w mutex code has detected a deadlock and the entire atomic - * sequence must be restarted. All other errors are fatal. - */ -int -drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, - struct drm_crtc *crtc) -{ - struct drm_connector *connector = conn_state->connector; - struct drm_crtc_state *crtc_state; - - if (conn_state->crtc == crtc) - return 0; - - if (conn_state->crtc) { - crtc_state = drm_atomic_get_new_crtc_state(conn_state->state, - conn_state->crtc); - - crtc_state->connector_mask &= - ~drm_connector_mask(conn_state->connector); - - drm_connector_put(conn_state->connector); - conn_state->crtc = NULL; - } - - if (crtc) { - crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - - crtc_state->connector_mask |= - drm_connector_mask(conn_state->connector); - - drm_connector_get(conn_state->connector); - conn_state->crtc = crtc; - - DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [CRTC:%d:%s]\n", - connector->base.id, connector->name, - conn_state, crtc->base.id, crtc->name); - } else { - DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [NOCRTC]\n", - connector->base.id, connector->name, - conn_state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); - /** * drm_atomic_add_affected_connectors - add connectors for crtc * @state: atomic state @@ -1888,7 +1074,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state) } EXPORT_SYMBOL(drm_atomic_nonblocking_commit); -static void drm_atomic_print_state(const struct drm_atomic_state *state) +void drm_atomic_print_state(const struct drm_atomic_state *state) { struct drm_printer p = drm_info_printer(state->dev->dev); struct drm_plane *plane; @@ -1995,544 +1181,3 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) } #endif -/* - * The big monster ioctl - */ - -static struct drm_pending_vblank_event *create_vblank_event( - struct drm_crtc *crtc, uint64_t user_data) -{ - struct drm_pending_vblank_event *e = NULL; - - e = kzalloc(sizeof *e, GFP_KERNEL); - if (!e) - return NULL; - - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof(e->event); - e->event.vbl.crtc_id = crtc->base.id; - e->event.vbl.user_data = user_data; - - return e; -} - -int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, - struct drm_connector *connector, - int mode) -{ - struct drm_connector *tmp_connector; - struct drm_connector_state *new_conn_state; - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - int i, ret, old_mode = connector->dpms; - bool active = false; - - ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, - state->acquire_ctx); - if (ret) - return ret; - - if (mode != DRM_MODE_DPMS_ON) - mode = DRM_MODE_DPMS_OFF; - connector->dpms = mode; - - crtc = connector->state->crtc; - if (!crtc) - goto out; - ret = drm_atomic_add_affected_connectors(state, crtc); - if (ret) - goto out; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret = PTR_ERR(crtc_state); - goto out; - } - - for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) { - if (new_conn_state->crtc != crtc) - continue; - if (tmp_connector->dpms == DRM_MODE_DPMS_ON) { - active = true; - break; - } - } - - crtc_state->active = active; - ret = drm_atomic_commit(state); -out: - if (ret != 0) - connector->dpms = old_mode; - return ret; -} - -int drm_atomic_set_property(struct drm_atomic_state *state, - struct drm_mode_object *obj, - struct drm_property *prop, - uint64_t prop_value) -{ - struct drm_mode_object *ref; - int ret; - - if (!drm_property_change_valid_get(prop, prop_value, &ref)) - return -EINVAL; - - switch (obj->type) { - case DRM_MODE_OBJECT_CONNECTOR: { - struct drm_connector *connector = obj_to_connector(obj); - struct drm_connector_state *connector_state; - - connector_state = drm_atomic_get_connector_state(state, connector); - if (IS_ERR(connector_state)) { - ret = PTR_ERR(connector_state); - break; - } - - ret = drm_atomic_connector_set_property(connector, - connector_state, prop, prop_value); - break; - } - case DRM_MODE_OBJECT_CRTC: { - struct drm_crtc *crtc = obj_to_crtc(obj); - struct drm_crtc_state *crtc_state; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret = PTR_ERR(crtc_state); - break; - } - - ret = drm_atomic_crtc_set_property(crtc, - crtc_state, prop, prop_value); - break; - } - case DRM_MODE_OBJECT_PLANE: { - struct drm_plane *plane = obj_to_plane(obj); - struct drm_plane_state *plane_state; - - plane_state = drm_atomic_get_plane_state(state, plane); - if (IS_ERR(plane_state)) { - ret = PTR_ERR(plane_state); - break; - } - - ret = drm_atomic_plane_set_property(plane, - plane_state, prop, prop_value); - break; - } - default: - ret = -EINVAL; - break; - } - - drm_property_change_valid_put(prop, ref); - return ret; -} - -/** - * DOC: explicit fencing properties - * - * Explicit fencing allows userspace to control the buffer synchronization - * between devices. A Fence or a group of fences are transfered to/from - * userspace using Sync File fds and there are two DRM properties for that. - * IN_FENCE_FD on each DRM Plane to send fences to the kernel and - * OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel. - * - * As a contrast, with implicit fencing the kernel keeps track of any - * ongoing rendering, and automatically ensures that the atomic update waits - * for any pending rendering to complete. For shared buffers represented with - * a &struct dma_buf this is tracked in &struct reservation_object. - * Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), - * whereas explicit fencing is what Android wants. - * - * "IN_FENCE_FD”: - * Use this property to pass a fence that DRM should wait on before - * proceeding with the Atomic Commit request and show the framebuffer for - * the plane on the screen. The fence can be either a normal fence or a - * merged one, the sync_file framework will handle both cases and use a - * fence_array if a merged fence is received. Passing -1 here means no - * fences to wait on. - * - * If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag - * it will only check if the Sync File is a valid one. - * - * On the driver side the fence is stored on the @fence parameter of - * &struct drm_plane_state. Drivers which also support implicit fencing - * should set the implicit fence using drm_atomic_set_fence_for_plane(), - * to make sure there's consistent behaviour between drivers in precedence - * of implicit vs. explicit fencing. - * - * "OUT_FENCE_PTR”: - * Use this property to pass a file descriptor pointer to DRM. Once the - * Atomic Commit request call returns OUT_FENCE_PTR will be filled with - * the file descriptor number of a Sync File. This Sync File contains the - * CRTC fence that will be signaled when all framebuffers present on the - * Atomic Commit * request for that given CRTC are scanned out on the - * screen. - * - * The Atomic Commit request fails if a invalid pointer is passed. If the - * Atomic Commit request fails for any other reason the out fence fd - * returned will be -1. On a Atomic Commit with the - * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1. - * - * Note that out-fences don't have a special interface to drivers and are - * internally represented by a &struct drm_pending_vblank_event in struct - * &drm_crtc_state, which is also used by the nonblocking atomic commit - * helpers and for the DRM event handling for existing userspace. - */ - -struct drm_out_fence_state { - s32 __user *out_fence_ptr; - struct sync_file *sync_file; - int fd; -}; - -static int setup_out_fence(struct drm_out_fence_state *fence_state, - struct dma_fence *fence) -{ - fence_state->fd = get_unused_fd_flags(O_CLOEXEC); - if (fence_state->fd < 0) - return fence_state->fd; - - if (put_user(fence_state->fd, fence_state->out_fence_ptr)) - return -EFAULT; - - fence_state->sync_file = sync_file_create(fence); - if (!fence_state->sync_file) - return -ENOMEM; - - return 0; -} - -static int prepare_signaling(struct drm_device *dev, - struct drm_atomic_state *state, - struct drm_mode_atomic *arg, - struct drm_file *file_priv, - struct drm_out_fence_state **fence_state, - unsigned int *num_fences) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - struct drm_connector *conn; - struct drm_connector_state *conn_state; - int i, c = 0, ret; - - if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) - return 0; - - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - s32 __user *fence_ptr; - - fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc); - - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { - struct drm_pending_vblank_event *e; - - e = create_vblank_event(crtc, arg->user_data); - if (!e) - return -ENOMEM; - - crtc_state->event = e; - } - - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { - struct drm_pending_vblank_event *e = crtc_state->event; - - if (!file_priv) - continue; - - ret = drm_event_reserve_init(dev, file_priv, &e->base, - &e->event.base); - if (ret) { - kfree(e); - crtc_state->event = NULL; - return ret; - } - } - - if (fence_ptr) { - struct dma_fence *fence; - struct drm_out_fence_state *f; - - f = krealloc(*fence_state, sizeof(**fence_state) * - (*num_fences + 1), GFP_KERNEL); - if (!f) - return -ENOMEM; - - memset(&f[*num_fences], 0, sizeof(*f)); - - f[*num_fences].out_fence_ptr = fence_ptr; - *fence_state = f; - - fence = drm_crtc_create_fence(crtc); - if (!fence) - return -ENOMEM; - - ret = setup_out_fence(&f[(*num_fences)++], fence); - if (ret) { - dma_fence_put(fence); - return ret; - } - - crtc_state->event->base.fence = fence; - } - - c++; - } - - for_each_new_connector_in_state(state, conn, conn_state, i) { - struct drm_writeback_connector *wb_conn; - struct drm_writeback_job *job; - struct drm_out_fence_state *f; - struct dma_fence *fence; - s32 __user *fence_ptr; - - fence_ptr = get_out_fence_for_connector(state, conn); - if (!fence_ptr) - continue; - - job = drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - f = krealloc(*fence_state, sizeof(**fence_state) * - (*num_fences + 1), GFP_KERNEL); - if (!f) - return -ENOMEM; - - memset(&f[*num_fences], 0, sizeof(*f)); - - f[*num_fences].out_fence_ptr = fence_ptr; - *fence_state = f; - - wb_conn = drm_connector_to_writeback(conn); - fence = drm_writeback_get_out_fence(wb_conn); - if (!fence) - return -ENOMEM; - - ret = setup_out_fence(&f[(*num_fences)++], fence); - if (ret) { - dma_fence_put(fence); - return ret; - } - - job->out_fence = fence; - } - - /* - * Having this flag means user mode pends on event which will never - * reach due to lack of at least one CRTC for signaling - */ - if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) - return -EINVAL; - - return 0; -} - -static void complete_signaling(struct drm_device *dev, - struct drm_atomic_state *state, - struct drm_out_fence_state *fence_state, - unsigned int num_fences, - bool install_fds) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - int i; - - if (install_fds) { - for (i = 0; i < num_fences; i++) - fd_install(fence_state[i].fd, - fence_state[i].sync_file->file); - - kfree(fence_state); - return; - } - - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - struct drm_pending_vblank_event *event = crtc_state->event; - /* - * Free the allocated event. drm_atomic_helper_setup_commit - * can allocate an event too, so only free it if it's ours - * to prevent a double free in drm_atomic_state_clear. - */ - if (event && (event->base.fence || event->base.file_priv)) { - drm_event_cancel_free(dev, &event->base); - crtc_state->event = NULL; - } - } - - if (!fence_state) - return; - - for (i = 0; i < num_fences; i++) { - if (fence_state[i].sync_file) - fput(fence_state[i].sync_file->file); - if (fence_state[i].fd >= 0) - put_unused_fd(fence_state[i].fd); - - /* If this fails log error to the user */ - if (fence_state[i].out_fence_ptr && - put_user(-1, fence_state[i].out_fence_ptr)) - DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n"); - } - - kfree(fence_state); -} - -int drm_mode_atomic_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_atomic *arg = data; - uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); - uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); - uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); - uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); - unsigned int copied_objs, copied_props; - struct drm_atomic_state *state; - struct drm_modeset_acquire_ctx ctx; - struct drm_out_fence_state *fence_state; - int ret = 0; - unsigned int i, j, num_fences; - - /* disallow for drivers not supporting atomic: */ - if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) - return -EINVAL; - - /* disallow for userspace that has not enabled atomic cap (even - * though this may be a bit overkill, since legacy userspace - * wouldn't know how to call this ioctl) - */ - if (!file_priv->atomic) - return -EINVAL; - - if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) - return -EINVAL; - - if (arg->reserved) - return -EINVAL; - - if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) && - !dev->mode_config.async_page_flip) - return -EINVAL; - - /* can't test and expect an event at the same time. */ - if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) && - (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) - return -EINVAL; - - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); - - state = drm_atomic_state_alloc(dev); - if (!state) - return -ENOMEM; - - state->acquire_ctx = &ctx; - state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); - -retry: - copied_objs = 0; - copied_props = 0; - fence_state = NULL; - num_fences = 0; - - for (i = 0; i < arg->count_objs; i++) { - uint32_t obj_id, count_props; - struct drm_mode_object *obj; - - if (get_user(obj_id, objs_ptr + copied_objs)) { - ret = -EFAULT; - goto out; - } - - obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY); - if (!obj) { - ret = -ENOENT; - goto out; - } - - if (!obj->properties) { - drm_mode_object_put(obj); - ret = -ENOENT; - goto out; - } - - if (get_user(count_props, count_props_ptr + copied_objs)) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - copied_objs++; - - for (j = 0; j < count_props; j++) { - uint32_t prop_id; - uint64_t prop_value; - struct drm_property *prop; - - if (get_user(prop_id, props_ptr + copied_props)) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - prop = drm_mode_obj_find_prop_id(obj, prop_id); - if (!prop) { - drm_mode_object_put(obj); - ret = -ENOENT; - goto out; - } - - if (copy_from_user(&prop_value, - prop_values_ptr + copied_props, - sizeof(prop_value))) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - ret = drm_atomic_set_property(state, obj, prop, - prop_value); - if (ret) { - drm_mode_object_put(obj); - goto out; - } - - copied_props++; - } - - drm_mode_object_put(obj); - } - - ret = prepare_signaling(dev, state, arg, file_priv, &fence_state, - &num_fences); - if (ret) - goto out; - - if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { - ret = drm_atomic_check_only(state); - } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { - ret = drm_atomic_nonblocking_commit(state); - } else { - if (unlikely(drm_debug & DRM_UT_STATE)) - drm_atomic_print_state(state); - - ret = drm_atomic_commit(state); - } - -out: - complete_signaling(dev, state, fence_state, num_fences, !ret); - - if (ret == -EDEADLK) { - drm_atomic_state_clear(state); - ret = drm_modeset_backoff(&ctx); - if (!ret) - goto retry; - } - - drm_atomic_state_put(state); - - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - - return ret; -} diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2c23a48482da..3cf1aa132778 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c new file mode 100644 index 000000000000..26690a664ec6 --- /dev/null +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -0,0 +1,1393 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "drm_crtc_internal.h" + +/** + * DOC: overview + * + * This file contains the marshalling and demarshalling glue for the atomic UAPI + * in all it's form: The monster ATOMIC IOCTL itself, code for GET_PROPERTY and + * SET_PROPERTY IOCTls. Plus interface functions for compatibility helpers and + * drivers which have special needs to construct their own atomic updates, e.g. + * for load detect or similiar. + */ + +/** + * drm_atomic_set_mode_for_crtc - set mode for CRTC + * @state: the CRTC whose incoming state to update + * @mode: kernel-internal mode to use for the CRTC, or NULL to disable + * + * Set a mode (originating from the kernel) on the desired CRTC state and update + * the enable property. + * + * RETURNS: + * Zero on success, error code on failure. Cannot return -EDEADLK. + */ +int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, + const struct drm_display_mode *mode) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_mode_modeinfo umode; + + /* Early return for no change. */ + if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) + return 0; + + drm_property_blob_put(state->mode_blob); + state->mode_blob = NULL; + + if (mode) { + drm_mode_convert_to_umode(&umode, mode); + state->mode_blob = + drm_property_create_blob(state->crtc->dev, + sizeof(umode), + &umode); + if (IS_ERR(state->mode_blob)) + return PTR_ERR(state->mode_blob); + + drm_mode_copy(&state->mode, mode); + state->enable = true; + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", + mode->name, crtc->base.id, crtc->name, state); + } else { + memset(&state->mode, 0, sizeof(state->mode)); + state->enable = false; + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", + crtc->base.id, crtc->name, state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); + +/** + * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC + * @state: the CRTC whose incoming state to update + * @blob: pointer to blob property to use for mode + * + * Set a mode (originating from a blob property) on the desired CRTC state. + * This function will take a reference on the blob property for the CRTC state, + * and release the reference held on the state's existing mode property, if any + * was set. + * + * RETURNS: + * Zero on success, error code on failure. Cannot return -EDEADLK. + */ +int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, + struct drm_property_blob *blob) +{ + struct drm_crtc *crtc = state->crtc; + + if (blob == state->mode_blob) + return 0; + + drm_property_blob_put(state->mode_blob); + state->mode_blob = NULL; + + memset(&state->mode, 0, sizeof(state->mode)); + + if (blob) { + int ret; + + if (blob->length != sizeof(struct drm_mode_modeinfo)) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] bad mode blob length: %zu\n", + crtc->base.id, crtc->name, + blob->length); + return -EINVAL; + } + + ret = drm_mode_convert_umode(crtc->dev, + &state->mode, blob->data); + if (ret) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] invalid mode (ret=%d, status=%s):\n", + crtc->base.id, crtc->name, + ret, drm_get_mode_status_name(state->mode.status)); + drm_mode_debug_printmodeline(&state->mode); + return -EINVAL; + } + + state->mode_blob = drm_property_blob_get(blob); + state->enable = true; + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", + state->mode.name, crtc->base.id, crtc->name, + state); + } else { + state->enable = false; + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", + crtc->base.id, crtc->name, state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); + +/** + * drm_atomic_set_crtc_for_plane - set crtc for plane + * @plane_state: the plane whose incoming state to update + * @crtc: crtc to use for the plane + * + * Changing the assigned crtc for a plane requires us to grab the lock and state + * for the new crtc, as needed. This function takes care of all these details + * besides updating the pointer in the state object itself. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK + * then the w/w mutex code has detected a deadlock and the entire atomic + * sequence must be restarted. All other errors are fatal. + */ +int +drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, + struct drm_crtc *crtc) +{ + struct drm_plane *plane = plane_state->plane; + struct drm_crtc_state *crtc_state; + /* Nothing to do for same crtc*/ + if (plane_state->crtc == crtc) + return 0; + if (plane_state->crtc) { + crtc_state = drm_atomic_get_crtc_state(plane_state->state, + plane_state->crtc); + if (WARN_ON(IS_ERR(crtc_state))) + return PTR_ERR(crtc_state); + + crtc_state->plane_mask &= ~drm_plane_mask(plane); + } + + plane_state->crtc = crtc; + + if (crtc) { + crtc_state = drm_atomic_get_crtc_state(plane_state->state, + crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + crtc_state->plane_mask |= drm_plane_mask(plane); + } + + if (crtc) + DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [CRTC:%d:%s]\n", + plane->base.id, plane->name, plane_state, + crtc->base.id, crtc->name); + else + DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [NOCRTC]\n", + plane->base.id, plane->name, plane_state); + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane); + +/** + * drm_atomic_set_fb_for_plane - set framebuffer for plane + * @plane_state: atomic state object for the plane + * @fb: fb to use for the plane + * + * Changing the assigned framebuffer for a plane requires us to grab a reference + * to the new fb and drop the reference to the old fb, if there is one. This + * function takes care of all these details besides updating the pointer in the + * state object itself. + */ +void +drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb) +{ + struct drm_plane *plane = plane_state->plane; + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for [PLANE:%d:%s] state %p\n", + fb->base.id, plane->base.id, plane->name, + plane_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for [PLANE:%d:%s] state %p\n", + plane->base.id, plane->name, plane_state); + + drm_framebuffer_assign(&plane_state->fb, fb); +} +EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); + +/** + * drm_atomic_set_fence_for_plane - set fence for plane + * @plane_state: atomic state object for the plane + * @fence: dma_fence to use for the plane + * + * Helper to setup the plane_state fence in case it is not set yet. + * By using this drivers doesn't need to worry if the user choose + * implicit or explicit fencing. + * + * This function will not set the fence to the state if it was set + * via explicit fencing interfaces on the atomic ioctl. In that case it will + * drop the reference to the fence as we are not storing it anywhere. + * Otherwise, if &drm_plane_state.fence is not set this function we just set it + * with the received implicit fence. In both cases this function consumes a + * reference for @fence. + * + * This way explicit fencing can be used to overrule implicit fencing, which is + * important to make explicit fencing use-cases work: One example is using one + * buffer for 2 screens with different refresh rates. Implicit fencing will + * clamp rendering to the refresh rate of the slower screen, whereas explicit + * fence allows 2 independent render and display loops on a single buffer. If a + * driver allows obeys both implicit and explicit fences for plane updates, then + * it will break all the benefits of explicit fencing. + */ +void +drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, + struct dma_fence *fence) +{ + if (plane_state->fence) { + dma_fence_put(fence); + return; + } + + plane_state->fence = fence; +} +EXPORT_SYMBOL(drm_atomic_set_fence_for_plane); + +/** + * drm_atomic_set_crtc_for_connector - set crtc for connector + * @conn_state: atomic state object for the connector + * @crtc: crtc to use for the connector + * + * Changing the assigned crtc for a connector requires us to grab the lock and + * state for the new crtc, as needed. This function takes care of all these + * details besides updating the pointer in the state object itself. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK + * then the w/w mutex code has detected a deadlock and the entire atomic + * sequence must be restarted. All other errors are fatal. + */ +int +drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, + struct drm_crtc *crtc) +{ + struct drm_connector *connector = conn_state->connector; + struct drm_crtc_state *crtc_state; + + if (conn_state->crtc == crtc) + return 0; + + if (conn_state->crtc) { + crtc_state = drm_atomic_get_new_crtc_state(conn_state->state, + conn_state->crtc); + + crtc_state->connector_mask &= + ~drm_connector_mask(conn_state->connector); + + drm_connector_put(conn_state->connector); + conn_state->crtc = NULL; + } + + if (crtc) { + crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + crtc_state->connector_mask |= + drm_connector_mask(conn_state->connector); + + drm_connector_get(conn_state->connector); + conn_state->crtc = crtc; + + DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [CRTC:%d:%s]\n", + connector->base.id, connector->name, + conn_state, crtc->base.id, crtc->name); + } else { + DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [NOCRTC]\n", + connector->base.id, connector->name, + conn_state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); + +static void set_out_fence_for_crtc(struct drm_atomic_state *state, + struct drm_crtc *crtc, s32 __user *fence_ptr) +{ + state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr; +} + +static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state, + struct drm_crtc *crtc) +{ + s32 __user *fence_ptr; + + fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr; + state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL; + + return fence_ptr; +} + +static int set_out_fence_for_connector(struct drm_atomic_state *state, + struct drm_connector *connector, + s32 __user *fence_ptr) +{ + unsigned int index = drm_connector_index(connector); + + if (!fence_ptr) + return 0; + + if (put_user(-1, fence_ptr)) + return -EFAULT; + + state->connectors[index].out_fence_ptr = fence_ptr; + + return 0; +} + +static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state, + struct drm_connector *connector) +{ + unsigned int index = drm_connector_index(connector); + s32 __user *fence_ptr; + + fence_ptr = state->connectors[index].out_fence_ptr; + state->connectors[index].out_fence_ptr = NULL; + + return fence_ptr; +} + +static int +drm_atomic_replace_property_blob_from_id(struct drm_device *dev, + struct drm_property_blob **blob, + uint64_t blob_id, + ssize_t expected_size, + ssize_t expected_elem_size, + bool *replaced) +{ + struct drm_property_blob *new_blob = NULL; + + if (blob_id != 0) { + new_blob = drm_property_lookup_blob(dev, blob_id); + if (new_blob == NULL) + return -EINVAL; + + if (expected_size > 0 && + new_blob->length != expected_size) { + drm_property_blob_put(new_blob); + return -EINVAL; + } + if (expected_elem_size > 0 && + new_blob->length % expected_elem_size != 0) { + drm_property_blob_put(new_blob); + return -EINVAL; + } + } + + *replaced |= drm_property_replace_blob(blob, new_blob); + drm_property_blob_put(new_blob); + + return 0; +} + +static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, + struct drm_crtc_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *config = &dev->mode_config; + bool replaced = false; + int ret; + + if (property == config->prop_active) + state->active = val; + else if (property == config->prop_mode_id) { + struct drm_property_blob *mode = + drm_property_lookup_blob(dev, val); + ret = drm_atomic_set_mode_prop_for_crtc(state, mode); + drm_property_blob_put(mode); + return ret; + } else if (property == config->degamma_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->degamma_lut, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->ctm_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->ctm, + val, + sizeof(struct drm_color_ctm), -1, + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->gamma_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->gamma_lut, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->prop_out_fence_ptr) { + s32 __user *fence_ptr = u64_to_user_ptr(val); + + if (!fence_ptr) + return 0; + + if (put_user(-1, fence_ptr)) + return -EFAULT; + + set_out_fence_for_crtc(state->state, crtc, fence_ptr); + } else if (crtc->funcs->atomic_set_property) { + return crtc->funcs->atomic_set_property(crtc, state, property, val); + } else { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n", + crtc->base.id, crtc->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_crtc_get_property(struct drm_crtc *crtc, + const struct drm_crtc_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_active) + *val = state->active; + else if (property == config->prop_mode_id) + *val = (state->mode_blob) ? state->mode_blob->base.id : 0; + else if (property == config->degamma_lut_property) + *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; + else if (property == config->ctm_property) + *val = (state->ctm) ? state->ctm->base.id : 0; + else if (property == config->gamma_lut_property) + *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + else if (property == config->prop_out_fence_ptr) + *val = 0; + else if (crtc->funcs->atomic_get_property) + return crtc->funcs->atomic_get_property(crtc, state, property, val); + else + return -EINVAL; + + return 0; +} + +static int drm_atomic_plane_set_property(struct drm_plane *plane, + struct drm_plane_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = plane->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_fb_id) { + struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); + drm_atomic_set_fb_for_plane(state, fb); + if (fb) + drm_framebuffer_put(fb); + } else if (property == config->prop_in_fence_fd) { + if (state->fence) + return -EINVAL; + + if (U642I64(val) == -1) + return 0; + + state->fence = sync_file_get_fence(val); + if (!state->fence) + return -EINVAL; + + } else if (property == config->prop_crtc_id) { + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + return drm_atomic_set_crtc_for_plane(state, crtc); + } else if (property == config->prop_crtc_x) { + state->crtc_x = U642I64(val); + } else if (property == config->prop_crtc_y) { + state->crtc_y = U642I64(val); + } else if (property == config->prop_crtc_w) { + state->crtc_w = val; + } else if (property == config->prop_crtc_h) { + state->crtc_h = val; + } else if (property == config->prop_src_x) { + state->src_x = val; + } else if (property == config->prop_src_y) { + state->src_y = val; + } else if (property == config->prop_src_w) { + state->src_w = val; + } else if (property == config->prop_src_h) { + state->src_h = val; + } else if (property == plane->alpha_property) { + state->alpha = val; + } else if (property == plane->blend_mode_property) { + state->pixel_blend_mode = val; + } else if (property == plane->rotation_property) { + if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 0x%llx\n", + plane->base.id, plane->name, val); + return -EINVAL; + } + state->rotation = val; + } else if (property == plane->zpos_property) { + state->zpos = val; + } else if (property == plane->color_encoding_property) { + state->color_encoding = val; + } else if (property == plane->color_range_property) { + state->color_range = val; + } else if (plane->funcs->atomic_set_property) { + return plane->funcs->atomic_set_property(plane, state, + property, val); + } else { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", + plane->base.id, plane->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_plane_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = plane->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_fb_id) { + *val = (state->fb) ? state->fb->base.id : 0; + } else if (property == config->prop_in_fence_fd) { + *val = -1; + } else if (property == config->prop_crtc_id) { + *val = (state->crtc) ? state->crtc->base.id : 0; + } else if (property == config->prop_crtc_x) { + *val = I642U64(state->crtc_x); + } else if (property == config->prop_crtc_y) { + *val = I642U64(state->crtc_y); + } else if (property == config->prop_crtc_w) { + *val = state->crtc_w; + } else if (property == config->prop_crtc_h) { + *val = state->crtc_h; + } else if (property == config->prop_src_x) { + *val = state->src_x; + } else if (property == config->prop_src_y) { + *val = state->src_y; + } else if (property == config->prop_src_w) { + *val = state->src_w; + } else if (property == config->prop_src_h) { + *val = state->src_h; + } else if (property == plane->alpha_property) { + *val = state->alpha; + } else if (property == plane->blend_mode_property) { + *val = state->pixel_blend_mode; + } else if (property == plane->rotation_property) { + *val = state->rotation; + } else if (property == plane->zpos_property) { + *val = state->zpos; + } else if (property == plane->color_encoding_property) { + *val = state->color_encoding; + } else if (property == plane->color_range_property) { + *val = state->color_range; + } else if (plane->funcs->atomic_get_property) { + return plane->funcs->atomic_get_property(plane, state, property, val); + } else { + return -EINVAL; + } + + return 0; +} + +static struct drm_writeback_job * +drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) +{ + WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); + + if (!conn_state->writeback_job) + conn_state->writeback_job = + kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); + + return conn_state->writeback_job; +} + +static int drm_atomic_set_writeback_fb_for_connector( + struct drm_connector_state *conn_state, + struct drm_framebuffer *fb) +{ + struct drm_writeback_job *job = + drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + drm_framebuffer_assign(&job->fb, fb); + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", + fb->base.id, conn_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", + conn_state); + + return 0; +} + +static int drm_atomic_connector_set_property(struct drm_connector *connector, + struct drm_connector_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = connector->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_crtc_id) { + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + return drm_atomic_set_crtc_for_connector(state, crtc); + } else if (property == config->dpms_property) { + /* setting DPMS property requires special handling, which + * is done in legacy setprop path for us. Disallow (for + * now?) atomic writes to DPMS property: + */ + return -EINVAL; + } else if (property == config->tv_select_subconnector_property) { + state->tv.subconnector = val; + } else if (property == config->tv_left_margin_property) { + state->tv.margins.left = val; + } else if (property == config->tv_right_margin_property) { + state->tv.margins.right = val; + } else if (property == config->tv_top_margin_property) { + state->tv.margins.top = val; + } else if (property == config->tv_bottom_margin_property) { + state->tv.margins.bottom = val; + } else if (property == config->tv_mode_property) { + state->tv.mode = val; + } else if (property == config->tv_brightness_property) { + state->tv.brightness = val; + } else if (property == config->tv_contrast_property) { + state->tv.contrast = val; + } else if (property == config->tv_flicker_reduction_property) { + state->tv.flicker_reduction = val; + } else if (property == config->tv_overscan_property) { + state->tv.overscan = val; + } else if (property == config->tv_saturation_property) { + state->tv.saturation = val; + } else if (property == config->tv_hue_property) { + state->tv.hue = val; + } else if (property == config->link_status_property) { + /* Never downgrade from GOOD to BAD on userspace's request here, + * only hw issues can do that. + * + * For an atomic property the userspace doesn't need to be able + * to understand all the properties, but needs to be able to + * restore the state it wants on VT switch. So if the userspace + * tries to change the link_status from GOOD to BAD, driver + * silently rejects it and returns a 0. This prevents userspace + * from accidently breaking the display when it restores the + * state. + */ + if (state->link_status != DRM_LINK_STATUS_GOOD) + state->link_status = val; + } else if (property == config->aspect_ratio_property) { + state->picture_aspect_ratio = val; + } else if (property == config->content_type_property) { + state->content_type = val; + } else if (property == connector->scaling_mode_property) { + state->scaling_mode = val; + } else if (property == connector->content_protection_property) { + if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); + return -EINVAL; + } + state->content_protection = val; + } else if (property == config->writeback_fb_id_property) { + struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); + int ret = drm_atomic_set_writeback_fb_for_connector(state, fb); + if (fb) + drm_framebuffer_put(fb); + return ret; + } else if (property == config->writeback_out_fence_ptr_property) { + s32 __user *fence_ptr = u64_to_user_ptr(val); + + return set_out_fence_for_connector(state->state, connector, + fence_ptr); + } else if (connector->funcs->atomic_set_property) { + return connector->funcs->atomic_set_property(connector, + state, property, val); + } else { + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]]\n", + connector->base.id, connector->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = connector->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_crtc_id) { + *val = (state->crtc) ? state->crtc->base.id : 0; + } else if (property == config->dpms_property) { + *val = connector->dpms; + } else if (property == config->tv_select_subconnector_property) { + *val = state->tv.subconnector; + } else if (property == config->tv_left_margin_property) { + *val = state->tv.margins.left; + } else if (property == config->tv_right_margin_property) { + *val = state->tv.margins.right; + } else if (property == config->tv_top_margin_property) { + *val = state->tv.margins.top; + } else if (property == config->tv_bottom_margin_property) { + *val = state->tv.margins.bottom; + } else if (property == config->tv_mode_property) { + *val = state->tv.mode; + } else if (property == config->tv_brightness_property) { + *val = state->tv.brightness; + } else if (property == config->tv_contrast_property) { + *val = state->tv.contrast; + } else if (property == config->tv_flicker_reduction_property) { + *val = state->tv.flicker_reduction; + } else if (property == config->tv_overscan_property) { + *val = state->tv.overscan; + } else if (property == config->tv_saturation_property) { + *val = state->tv.saturation; + } else if (property == config->tv_hue_property) { + *val = state->tv.hue; + } else if (property == config->link_status_property) { + *val = state->link_status; + } else if (property == config->aspect_ratio_property) { + *val = state->picture_aspect_ratio; + } else if (property == config->content_type_property) { + *val = state->content_type; + } else if (property == connector->scaling_mode_property) { + *val = state->scaling_mode; + } else if (property == connector->content_protection_property) { + *val = state->content_protection; + } else if (property == config->writeback_fb_id_property) { + /* Writeback framebuffer is one-shot, write and forget */ + *val = 0; + } else if (property == config->writeback_out_fence_ptr_property) { + *val = 0; + } else if (connector->funcs->atomic_get_property) { + return connector->funcs->atomic_get_property(connector, + state, property, val); + } else { + return -EINVAL; + } + + return 0; +} + +int drm_atomic_get_property(struct drm_mode_object *obj, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = property->dev; + int ret; + + switch (obj->type) { + case DRM_MODE_OBJECT_CONNECTOR: { + struct drm_connector *connector = obj_to_connector(obj); + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + ret = drm_atomic_connector_get_property(connector, + connector->state, property, val); + break; + } + case DRM_MODE_OBJECT_CRTC: { + struct drm_crtc *crtc = obj_to_crtc(obj); + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + ret = drm_atomic_crtc_get_property(crtc, + crtc->state, property, val); + break; + } + case DRM_MODE_OBJECT_PLANE: { + struct drm_plane *plane = obj_to_plane(obj); + WARN_ON(!drm_modeset_is_locked(&plane->mutex)); + ret = drm_atomic_plane_get_property(plane, + plane->state, property, val); + break; + } + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* + * The big monster ioctl + */ + +static struct drm_pending_vblank_event *create_vblank_event( + struct drm_crtc *crtc, uint64_t user_data) +{ + struct drm_pending_vblank_event *e = NULL; + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (!e) + return NULL; + + e->event.base.type = DRM_EVENT_FLIP_COMPLETE; + e->event.base.length = sizeof(e->event); + e->event.vbl.crtc_id = crtc->base.id; + e->event.vbl.user_data = user_data; + + return e; +} + +int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, + struct drm_connector *connector, + int mode) +{ + struct drm_connector *tmp_connector; + struct drm_connector_state *new_conn_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i, ret, old_mode = connector->dpms; + bool active = false; + + ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, + state->acquire_ctx); + if (ret) + return ret; + + if (mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; + connector->dpms = mode; + + crtc = connector->state->crtc; + if (!crtc) + goto out; + ret = drm_atomic_add_affected_connectors(state, crtc); + if (ret) + goto out; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + goto out; + } + + for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) { + if (new_conn_state->crtc != crtc) + continue; + if (tmp_connector->dpms == DRM_MODE_DPMS_ON) { + active = true; + break; + } + } + + crtc_state->active = active; + ret = drm_atomic_commit(state); +out: + if (ret != 0) + connector->dpms = old_mode; + return ret; +} + +int drm_atomic_set_property(struct drm_atomic_state *state, + struct drm_mode_object *obj, + struct drm_property *prop, + uint64_t prop_value) +{ + struct drm_mode_object *ref; + int ret; + + if (!drm_property_change_valid_get(prop, prop_value, &ref)) + return -EINVAL; + + switch (obj->type) { + case DRM_MODE_OBJECT_CONNECTOR: { + struct drm_connector *connector = obj_to_connector(obj); + struct drm_connector_state *connector_state; + + connector_state = drm_atomic_get_connector_state(state, connector); + if (IS_ERR(connector_state)) { + ret = PTR_ERR(connector_state); + break; + } + + ret = drm_atomic_connector_set_property(connector, + connector_state, prop, prop_value); + break; + } + case DRM_MODE_OBJECT_CRTC: { + struct drm_crtc *crtc = obj_to_crtc(obj); + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + break; + } + + ret = drm_atomic_crtc_set_property(crtc, + crtc_state, prop, prop_value); + break; + } + case DRM_MODE_OBJECT_PLANE: { + struct drm_plane *plane = obj_to_plane(obj); + struct drm_plane_state *plane_state; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); + break; + } + + ret = drm_atomic_plane_set_property(plane, + plane_state, prop, prop_value); + break; + } + default: + ret = -EINVAL; + break; + } + + drm_property_change_valid_put(prop, ref); + return ret; +} + +/** + * DOC: explicit fencing properties + * + * Explicit fencing allows userspace to control the buffer synchronization + * between devices. A Fence or a group of fences are transfered to/from + * userspace using Sync File fds and there are two DRM properties for that. + * IN_FENCE_FD on each DRM Plane to send fences to the kernel and + * OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel. + * + * As a contrast, with implicit fencing the kernel keeps track of any + * ongoing rendering, and automatically ensures that the atomic update waits + * for any pending rendering to complete. For shared buffers represented with + * a &struct dma_buf this is tracked in &struct reservation_object. + * Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), + * whereas explicit fencing is what Android wants. + * + * "IN_FENCE_FD”: + * Use this property to pass a fence that DRM should wait on before + * proceeding with the Atomic Commit request and show the framebuffer for + * the plane on the screen. The fence can be either a normal fence or a + * merged one, the sync_file framework will handle both cases and use a + * fence_array if a merged fence is received. Passing -1 here means no + * fences to wait on. + * + * If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag + * it will only check if the Sync File is a valid one. + * + * On the driver side the fence is stored on the @fence parameter of + * &struct drm_plane_state. Drivers which also support implicit fencing + * should set the implicit fence using drm_atomic_set_fence_for_plane(), + * to make sure there's consistent behaviour between drivers in precedence + * of implicit vs. explicit fencing. + * + * "OUT_FENCE_PTR”: + * Use this property to pass a file descriptor pointer to DRM. Once the + * Atomic Commit request call returns OUT_FENCE_PTR will be filled with + * the file descriptor number of a Sync File. This Sync File contains the + * CRTC fence that will be signaled when all framebuffers present on the + * Atomic Commit * request for that given CRTC are scanned out on the + * screen. + * + * The Atomic Commit request fails if a invalid pointer is passed. If the + * Atomic Commit request fails for any other reason the out fence fd + * returned will be -1. On a Atomic Commit with the + * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1. + * + * Note that out-fences don't have a special interface to drivers and are + * internally represented by a &struct drm_pending_vblank_event in struct + * &drm_crtc_state, which is also used by the nonblocking atomic commit + * helpers and for the DRM event handling for existing userspace. + */ + +struct drm_out_fence_state { + s32 __user *out_fence_ptr; + struct sync_file *sync_file; + int fd; +}; + +static int setup_out_fence(struct drm_out_fence_state *fence_state, + struct dma_fence *fence) +{ + fence_state->fd = get_unused_fd_flags(O_CLOEXEC); + if (fence_state->fd < 0) + return fence_state->fd; + + if (put_user(fence_state->fd, fence_state->out_fence_ptr)) + return -EFAULT; + + fence_state->sync_file = sync_file_create(fence); + if (!fence_state->sync_file) + return -ENOMEM; + + return 0; +} + +static int prepare_signaling(struct drm_device *dev, + struct drm_atomic_state *state, + struct drm_mode_atomic *arg, + struct drm_file *file_priv, + struct drm_out_fence_state **fence_state, + unsigned int *num_fences) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_connector *conn; + struct drm_connector_state *conn_state; + int i, c = 0, ret; + + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) + return 0; + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + s32 __user *fence_ptr; + + fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc); + + if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { + struct drm_pending_vblank_event *e; + + e = create_vblank_event(crtc, arg->user_data); + if (!e) + return -ENOMEM; + + crtc_state->event = e; + } + + if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { + struct drm_pending_vblank_event *e = crtc_state->event; + + if (!file_priv) + continue; + + ret = drm_event_reserve_init(dev, file_priv, &e->base, + &e->event.base); + if (ret) { + kfree(e); + crtc_state->event = NULL; + return ret; + } + } + + if (fence_ptr) { + struct dma_fence *fence; + struct drm_out_fence_state *f; + + f = krealloc(*fence_state, sizeof(**fence_state) * + (*num_fences + 1), GFP_KERNEL); + if (!f) + return -ENOMEM; + + memset(&f[*num_fences], 0, sizeof(*f)); + + f[*num_fences].out_fence_ptr = fence_ptr; + *fence_state = f; + + fence = drm_crtc_create_fence(crtc); + if (!fence) + return -ENOMEM; + + ret = setup_out_fence(&f[(*num_fences)++], fence); + if (ret) { + dma_fence_put(fence); + return ret; + } + + crtc_state->event->base.fence = fence; + } + + c++; + } + + for_each_new_connector_in_state(state, conn, conn_state, i) { + struct drm_writeback_connector *wb_conn; + struct drm_writeback_job *job; + struct drm_out_fence_state *f; + struct dma_fence *fence; + s32 __user *fence_ptr; + + fence_ptr = get_out_fence_for_connector(state, conn); + if (!fence_ptr) + continue; + + job = drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + f = krealloc(*fence_state, sizeof(**fence_state) * + (*num_fences + 1), GFP_KERNEL); + if (!f) + return -ENOMEM; + + memset(&f[*num_fences], 0, sizeof(*f)); + + f[*num_fences].out_fence_ptr = fence_ptr; + *fence_state = f; + + wb_conn = drm_connector_to_writeback(conn); + fence = drm_writeback_get_out_fence(wb_conn); + if (!fence) + return -ENOMEM; + + ret = setup_out_fence(&f[(*num_fences)++], fence); + if (ret) { + dma_fence_put(fence); + return ret; + } + + job->out_fence = fence; + } + + /* + * Having this flag means user mode pends on event which will never + * reach due to lack of at least one CRTC for signaling + */ + if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) + return -EINVAL; + + return 0; +} + +static void complete_signaling(struct drm_device *dev, + struct drm_atomic_state *state, + struct drm_out_fence_state *fence_state, + unsigned int num_fences, + bool install_fds) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i; + + if (install_fds) { + for (i = 0; i < num_fences; i++) + fd_install(fence_state[i].fd, + fence_state[i].sync_file->file); + + kfree(fence_state); + return; + } + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + struct drm_pending_vblank_event *event = crtc_state->event; + /* + * Free the allocated event. drm_atomic_helper_setup_commit + * can allocate an event too, so only free it if it's ours + * to prevent a double free in drm_atomic_state_clear. + */ + if (event && (event->base.fence || event->base.file_priv)) { + drm_event_cancel_free(dev, &event->base); + crtc_state->event = NULL; + } + } + + if (!fence_state) + return; + + for (i = 0; i < num_fences; i++) { + if (fence_state[i].sync_file) + fput(fence_state[i].sync_file->file); + if (fence_state[i].fd >= 0) + put_unused_fd(fence_state[i].fd); + + /* If this fails log error to the user */ + if (fence_state[i].out_fence_ptr && + put_user(-1, fence_state[i].out_fence_ptr)) + DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n"); + } + + kfree(fence_state); +} + +int drm_mode_atomic_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_atomic *arg = data; + uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); + uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); + uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); + uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); + unsigned int copied_objs, copied_props; + struct drm_atomic_state *state; + struct drm_modeset_acquire_ctx ctx; + struct drm_out_fence_state *fence_state; + int ret = 0; + unsigned int i, j, num_fences; + + /* disallow for drivers not supporting atomic: */ + if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) + return -EINVAL; + + /* disallow for userspace that has not enabled atomic cap (even + * though this may be a bit overkill, since legacy userspace + * wouldn't know how to call this ioctl) + */ + if (!file_priv->atomic) + return -EINVAL; + + if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) + return -EINVAL; + + if (arg->reserved) + return -EINVAL; + + if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) && + !dev->mode_config.async_page_flip) + return -EINVAL; + + /* can't test and expect an event at the same time. */ + if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) && + (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) + return -EINVAL; + + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); + + state = drm_atomic_state_alloc(dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx = &ctx; + state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); + +retry: + copied_objs = 0; + copied_props = 0; + fence_state = NULL; + num_fences = 0; + + for (i = 0; i < arg->count_objs; i++) { + uint32_t obj_id, count_props; + struct drm_mode_object *obj; + + if (get_user(obj_id, objs_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY); + if (!obj) { + ret = -ENOENT; + goto out; + } + + if (!obj->properties) { + drm_mode_object_put(obj); + ret = -ENOENT; + goto out; + } + + if (get_user(count_props, count_props_ptr + copied_objs)) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + copied_objs++; + + for (j = 0; j < count_props; j++) { + uint32_t prop_id; + uint64_t prop_value; + struct drm_property *prop; + + if (get_user(prop_id, props_ptr + copied_props)) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + prop = drm_mode_obj_find_prop_id(obj, prop_id); + if (!prop) { + drm_mode_object_put(obj); + ret = -ENOENT; + goto out; + } + + if (copy_from_user(&prop_value, + prop_values_ptr + copied_props, + sizeof(prop_value))) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + ret = drm_atomic_set_property(state, obj, prop, + prop_value); + if (ret) { + drm_mode_object_put(obj); + goto out; + } + + copied_props++; + } + + drm_mode_object_put(obj); + } + + ret = prepare_signaling(dev, state, arg, file_priv, &fence_state, + &num_fences); + if (ret) + goto out; + + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { + ret = drm_atomic_check_only(state); + } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { + ret = drm_atomic_nonblocking_commit(state); + } else { + if (unlikely(drm_debug & DRM_UT_STATE)) + drm_atomic_print_state(state); + + ret = drm_atomic_commit(state); + } + +out: + complete_signaling(dev, state, fence_state, num_fences, !ret); + + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry; + } + + drm_atomic_state_put(state); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + + return ret; +} diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 5a84c3bc915d..ce75e9506e85 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index ff5e0d521c21..ede20b55d50c 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -204,6 +204,9 @@ struct drm_minor; int drm_atomic_debugfs_init(struct drm_minor *minor); #endif +void drm_atomic_print_state(const struct drm_atomic_state *state); + +/* drm_atomic_uapi.c */ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, struct drm_connector *connector, int mode); @@ -213,6 +216,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state, uint64_t prop_value); int drm_atomic_get_property(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val); + +/* IOCTL */ int drm_mode_atomic_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index c8a7829d73d6..227f52e55d05 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "drm_internal.h" diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 2810d4131411..7607f9cd6f77 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 621f17643bb0..a393756b664e 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9382375d33b2..c24bc848ac6c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index b640e39ebaca..015341e2dd4c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -21,6 +21,8 @@ #include #include +#include + #include "msm_drv.h" #include "dpu_kms.h" #include "dpu_formats.h" diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index c1f1779c980f..4bcdeca7479d 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -15,6 +15,8 @@ * this program. If not, see . */ +#include + #include "msm_drv.h" #include "msm_gem.h" #include "msm_kms.h" diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 0e6a121858d1..3ce136ba8791 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index cf78f74bb87f..f39ee212412d 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "uapi/drm/vc4_drm.h" #include "vc4_drv.h" diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 93d29af34024..d6adebcd6ea4 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -584,22 +584,6 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, return plane->state; } -int __must_check -drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, - const struct drm_display_mode *mode); -int __must_check -drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, - struct drm_property_blob *blob); -int __must_check -drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, - struct drm_crtc *crtc); -void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, - struct drm_framebuffer *fb); -void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, - struct dma_fence *fence); -int __must_check -drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, - struct drm_crtc *crtc); int __must_check drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc); diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h new file mode 100644 index 000000000000..8cec52ad1277 --- /dev/null +++ b/include/drm/drm_atomic_uapi.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#ifndef DRM_ATOMIC_UAPI_H_ +#define DRM_ATOMIC_UAPI_H_ + +struct drm_crtc_state; +struct drm_display_mode; +struct drm_property_blob; +struct drm_plane_state; +struct drm_crtc; +struct drm_connector_state; +struct dma_fence; +struct drm_framebuffer; + +int __must_check +drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, + const struct drm_display_mode *mode); +int __must_check +drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, + struct drm_property_blob *blob); +int __must_check +drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, + struct drm_crtc *crtc); +void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb); +void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, + struct dma_fence *fence); +int __must_check +drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, + struct drm_crtc *crtc); + +#endif -- cgit v1.2.3 From fde35c9c7db5732cc1fbd89fa5eba5a9e0b25f6e Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 7 Sep 2018 11:58:49 -0500 Subject: clk: renesas: cpg-mssr: Add R7S9210 support Add support for the R7S9210 (RZ/A2) Clock Pulse Generator and Module Standby. The Module Standby HW in the RZ/A series is very close to R-Car HW, except for how the registers are laid out. The MSTP registers are only 8-bits wide, there are no status registers (MSTPSR), and the register offsets are a little different. Since the RZ/A hardware manuals refer to these registers as the Standby Control Registers, we'll use that name to distinguish the RZ/A type from the R-Car type. Signed-off-by: Chris Brandt Acked-by: Rob Herring # DT bits Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 5 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r7s9210-cpg-mssr.c | 189 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 81 +++++++-- drivers/clk/renesas/renesas-cpg-mssr.h | 13 ++ include/dt-bindings/clock/r7s9210-cpg-mssr.h | 20 +++ 7 files changed, 300 insertions(+), 14 deletions(-) create mode 100644 drivers/clk/renesas/r7s9210-cpg-mssr.c create mode 100644 include/dt-bindings/clock/r7s9210-cpg-mssr.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 42d0f83d812b..5e46e6be789b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -13,6 +13,7 @@ They provide the following functionalities: Required Properties: - compatible: Must be one of: + - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2) - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) @@ -36,8 +37,8 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, - r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + - "extal" (r7s9210, r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, + r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f998a7333acb..2edcb1bdb487 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -3,6 +3,7 @@ config CLK_RENESAS default y if ARCH_RENESAS select CLK_EMEV2 if ARCH_EMEV2 select CLK_RZA1 if ARCH_R7S72100 + select CLK_R7S9210 if ARCH_R7S9210 select CLK_R8A73A4 if ARCH_R8A73A4 select CLK_R8A7740 if ARCH_R8A7740 select CLK_R8A7743 if ARCH_R8A7743 @@ -46,6 +47,10 @@ config CLK_RZA1 bool "RZ/A1H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP +config CLK_R7S9210 + bool "RZ/A2 clock support" if COMPILE_TEST + select CLK_RENESAS_CPG_MSSR + config CLK_R8A73A4 bool "R-Mobile APE6 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 71d4cafe15c0..dbbfd0b0742b 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -2,6 +2,7 @@ # SoC obj-$(CONFIG_CLK_EMEV2) += clk-emev2.o obj-$(CONFIG_CLK_RZA1) += clk-rz.o +obj-$(CONFIG_CLK_R7S9210) += r7s9210-cpg-mssr.o obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c new file mode 100644 index 000000000000..bd1dd4ff2051 --- /dev/null +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R7S9210 Clock Pulse Generator / Module Standby + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2018 Chris Brandt + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#include +#include +#include +#include "renesas-cpg-mssr.h" + +#define CPG_FRQCR 0x00 + +static u8 cpg_mode; + +/* Internal Clock ratio table */ +static const struct { + unsigned int i; + unsigned int g; + unsigned int b; + unsigned int p1; + /* p0 is always 32 */; +} ratio_tab[5] = { /* I, G, B, P1 */ + { 2, 4, 8, 16}, /* FRQCR = 0x012 */ + { 4, 4, 8, 16}, /* FRQCR = 0x112 */ + { 8, 4, 8, 16}, /* FRQCR = 0x212 */ + { 16, 8, 16, 16}, /* FRQCR = 0x322 */ + { 16, 16, 32, 32}, /* FRQCR = 0x333 */ + }; + +enum rz_clk_types { + CLK_TYPE_RZA_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_RZA_PLL, +}; + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R7S9210_CLK_P0, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static struct cpg_core_clk r7s9210_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), + DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + + /* Core Clock Outputs */ + DEF_FIXED("i", R7S9210_CLK_I, CLK_PLL, 2, 1), + DEF_FIXED("g", R7S9210_CLK_G, CLK_PLL, 4, 1), + DEF_FIXED("b", R7S9210_CLK_B, CLK_PLL, 8, 1), + DEF_FIXED("p1", R7S9210_CLK_P1, CLK_PLL, 16, 1), + DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), + DEF_FIXED("p0", R7S9210_CLK_P0, CLK_PLL, 32, 1), +}; + +static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { + DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), + + DEF_MOD_STB("scif4", 43, R7S9210_CLK_P1C), + DEF_MOD_STB("scif3", 44, R7S9210_CLK_P1C), + DEF_MOD_STB("scif2", 45, R7S9210_CLK_P1C), + DEF_MOD_STB("scif1", 46, R7S9210_CLK_P1C), + DEF_MOD_STB("scif0", 47, R7S9210_CLK_P1C), + + DEF_MOD_STB("ether1", 64, R7S9210_CLK_B), + DEF_MOD_STB("ether0", 65, R7S9210_CLK_B), + + DEF_MOD_STB("i2c3", 84, R7S9210_CLK_P1), + DEF_MOD_STB("i2c2", 85, R7S9210_CLK_P1), + DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1), + DEF_MOD_STB("i2c0", 87, R7S9210_CLK_P1), + +}; + +struct clk * __init rza2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base, + struct raw_notifier_head *notifiers) +{ + struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u16 frqcr; + u8 index; + int i; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->id) { + case CLK_MAIN: + break; + + case CLK_PLL: + if (cpg_mode) + mult = 44; /* Divider 1 is 1/2 */ + else + mult = 88; /* Divider 1 is 1 */ + break; + + default: + return ERR_PTR(-EINVAL); + } + + /* Adjust the dividers based on the current FRQCR setting */ + if (core->id == CLK_MAIN) { + + /* If EXTAL is above 12MHz, then we know it is Mode 1 */ + if (clk_get_rate(parent) > 12000000) + cpg_mode = 1; + + frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; + if (frqcr == 0x012) + index = 0; + else if (frqcr == 0x112) + index = 1; + else if (frqcr == 0x212) + index = 2; + else if (frqcr == 0x322) + index = 3; + else if (frqcr == 0x333) + index = 4; + else + BUG_ON(1); /* Illegal FRQCR value */ + + for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { + switch (r7s9210_core_clks[i].id) { + case R7S9210_CLK_I: + r7s9210_core_clks[i].div = ratio_tab[index].i; + break; + case R7S9210_CLK_G: + r7s9210_core_clks[i].div = ratio_tab[index].g; + break; + case R7S9210_CLK_B: + r7s9210_core_clks[i].div = ratio_tab[index].b; + break; + case R7S9210_CLK_P1: + case R7S9210_CLK_P1C: + r7s9210_core_clks[i].div = ratio_tab[index].p1; + break; + case R7S9210_CLK_P0: + r7s9210_core_clks[i].div = 32; + break; + } + } + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r7s9210_core_clks, + .num_core_clks = ARRAY_SIZE(r7s9210_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r7s9210_mod_clks, + .num_mod_clks = ARRAY_SIZE(r7s9210_mod_clks), + .num_hw_mod_clks = 11 * 32, /* includes STBCR0 which doesn't exist */ + + /* Callbacks */ + .cpg_clk_register = rza2_cpg_clk_register, + + /* RZ/A2 has Standby Control Registers */ + .stbyctrl = true, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f90b0d0ba46a..b97e0e3ff0b1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -73,6 +73,17 @@ static const u16 smstpcr[] = { #define SMSTPCR(i) smstpcr[i] +/* + * Standby Control Register offsets (RZ/A) + * Base address is FRQCR register + */ + +static const u16 stbcr[] = { + 0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420, + 0x424, 0x428, 0x42C, +}; + +#define STBCR(i) stbcr[i] /* * Software Reset Register offsets @@ -110,6 +121,7 @@ static const u16 srcr[] = { * @notifiers: Notifier chain to save/restore clock state for system resume * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control * @smstpcr_saved[].val: Saved values of SMSTPCR[] + * @stbyctrl: This device has Standby Control Registers */ struct cpg_mssr_priv { #ifdef CONFIG_RESET_CONTROLLER @@ -123,6 +135,7 @@ struct cpg_mssr_priv { unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; + bool stbyctrl; struct raw_notifier_head notifiers; struct { @@ -162,16 +175,29 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) enable ? "ON" : "OFF"); spin_lock_irqsave(&priv->rmw_lock, flags); - value = readl(priv->base + SMSTPCR(reg)); - if (enable) - value &= ~bitmask; - else - value |= bitmask; - writel(value, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + value = readb(priv->base + STBCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writeb(value, priv->base + STBCR(reg)); + + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + } else { + value = readl(priv->base + SMSTPCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writel(value, priv->base + SMSTPCR(reg)); + } spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (!enable) + if (!enable || priv->stbyctrl) return 0; for (i = 1000; i > 0; --i) { @@ -205,7 +231,10 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) struct cpg_mssr_priv *priv = clock->priv; u32 value; - value = readl(priv->base + MSTPSR(clock->index / 32)); + if (priv->stbyctrl) + value = readb(priv->base + STBCR(clock->index / 32)); + else + value = readl(priv->base + MSTPSR(clock->index / 32)); return !(value & BIT(clock->index % 32)); } @@ -226,6 +255,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, unsigned int idx; const char *type; struct clk *clk; + int range_check; switch (clkspec->args[0]) { case CPG_CORE: @@ -240,8 +270,14 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, case CPG_MOD: type = "module"; - idx = MOD_CLK_PACK(clkidx); - if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { + if (priv->stbyctrl) { + idx = MOD_CLK_PACK_10(clkidx); + range_check = 7 - (clkidx % 10); + } else { + idx = MOD_CLK_PACK(clkidx); + range_check = 31 - (clkidx % 100); + } + if (range_check < 0 || idx >= priv->num_mod_clks) { dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); @@ -646,6 +682,12 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) static const struct of_device_id cpg_mssr_match[] = { +#ifdef CONFIG_CLK_R7S9210 + { + .compatible = "renesas,r7s9210-cpg-mssr", + .data = &r7s9210_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7743 { .compatible = "renesas,r8a7743-cpg-mssr", @@ -791,13 +833,23 @@ static int cpg_mssr_resume_noirq(struct device *dev) if (!mask) continue; - oldval = readl(priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) + oldval = readb(priv->base + STBCR(reg)); + else + oldval = readl(priv->base + SMSTPCR(reg)); newval = oldval & ~mask; newval |= priv->smstpcr_saved[reg].val & mask; if (newval == oldval) continue; - writel(newval, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + writeb(newval, priv->base + STBCR(reg)); + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + continue; + } else + writel(newval, priv->base + SMSTPCR(reg)); /* Wait until enabled clocks are really enabled */ mask &= ~priv->smstpcr_saved[reg].val; @@ -869,6 +921,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); + priv->stbyctrl = info->stbyctrl; for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); @@ -894,6 +947,10 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) if (error) return error; + /* Reset Controller not supported for Standby Control SoCs */ + if (info->stbyctrl) + return 0; + error = cpg_mssr_reset_controller_register(priv); if (error) return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 2e1730bc5ef2..35f60b3d0e09 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -78,6 +78,13 @@ struct mssr_mod_clk { #define DEF_MOD(_name, _mod, _parent...) \ { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } +/* Convert from sparse base-10 to packed index space */ +#define MOD_CLK_PACK_10(x) ((x / 10) * 32 + (x % 10)) + +#define MOD_CLK_ID_10(x) (MOD_CLK_BASE + MOD_CLK_PACK_10(x)) + +#define DEF_MOD_STB(_name, _mod, _parent...) \ + { .name = _name, .id = MOD_CLK_ID_10(_mod), .parent = _parent } struct device_node; @@ -103,6 +110,10 @@ struct device_node; * * @init: Optional callback to perform SoC-specific initialization * @cpg_clk_register: Optional callback to handle special Core Clock types + * + * @stbyctrl: This device has Standby Control Registers which are 8-bits + * wide, no status registers (MSTPSR) and have different address + * offsets. */ struct cpg_mssr_info { @@ -111,6 +122,7 @@ struct cpg_mssr_info { unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; + bool stbyctrl; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; @@ -134,6 +146,7 @@ struct cpg_mssr_info { struct raw_notifier_head *notifiers); }; +extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; diff --git a/include/dt-bindings/clock/r7s9210-cpg-mssr.h b/include/dt-bindings/clock/r7s9210-cpg-mssr.h new file mode 100644 index 000000000000..b6f85ca149aa --- /dev/null +++ b/include/dt-bindings/clock/r7s9210-cpg-mssr.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#ifndef __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ + +#include + +/* R7S9210 CPG Core Clocks */ +#define R7S9210_CLK_I 0 +#define R7S9210_CLK_G 1 +#define R7S9210_CLK_B 2 +#define R7S9210_CLK_P1 3 +#define R7S9210_CLK_P1C 4 +#define R7S9210_CLK_P0 5 + +#endif /* __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ */ -- cgit v1.2.3 From b4ae675d3f4f31b7810b58895e643177be8fc010 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 4 Aug 2018 05:48:36 -0400 Subject: media: mediactl/*.rst: document argp The documentation of the Media Controller API ioctls is missing a description of the argp ioctl argument. Add this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/mediactl/media-ioc-device-info.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-enum-links.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-g-topology.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-setup-link.rst | 1 + 5 files changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst b/Documentation/media/uapi/mediactl/media-ioc-device-info.rst index 649cb3d9e058..c6f224e404b7 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-device-info.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_device_info`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst index fc2e39c070c9..02738640e34e 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_entity_desc`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst index f158c134e9b0..b89aaae373df 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_links_enum`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst index bac128c7eda9..4e1c59238371 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_v2_topology`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst b/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst index ae5194940100..e345e7dc9ad7 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_link_desc`. Description -- cgit v1.2.3 From 96cb579cc47380a22d3f64da7877e13a7566e296 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 14 Aug 2018 03:52:17 -0400 Subject: media: cec-func-poll.rst/func-poll.rst: update EINVAL description nfds depends on RLIMIT_NOFILE, not OPEN_MAX. Update the description for cec and v4l2. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-func-poll.rst | 3 ++- Documentation/media/uapi/v4l/func-poll.rst | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst index d49f1ee0742d..c698c969635c 100644 --- a/Documentation/media/uapi/cec/cec-func-poll.rst +++ b/Documentation/media/uapi/cec/cec-func-poll.rst @@ -74,4 +74,5 @@ is returned, and the ``errno`` variable is set appropriately: The call was interrupted by a signal. ``EINVAL`` - The ``nfds`` argument is greater than ``OPEN_MAX``. + The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use + ``getrlimit()`` to obtain this value. diff --git a/Documentation/media/uapi/v4l/func-poll.rst b/Documentation/media/uapi/v4l/func-poll.rst index 360bc6523ae2..967fe8920729 100644 --- a/Documentation/media/uapi/v4l/func-poll.rst +++ b/Documentation/media/uapi/v4l/func-poll.rst @@ -113,4 +113,5 @@ EINTR The call was interrupted by a signal. EINVAL - The ``nfds`` argument is greater than ``OPEN_MAX``. + The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use + ``getrlimit()`` to obtain this value. -- cgit v1.2.3 From e9355a7a6584882fa25c471898fdb49c22c9912c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Sep 2018 08:53:11 -0400 Subject: media: videodev2.h.rst.exceptions: add V4L2_DV_FL_CAN_DETECT_REDUCED_FPS This fixes a documentation warning: Documentation/output/videodev2.h.rst:6: WARNING: undefined label: v4l2-dv-fl-can-detect-reduced-fps (if the link has no caption the label must precede a section header) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/videodev2.h.rst.exceptions | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index ca9f0edc579e..63fa131729c0 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -278,6 +278,7 @@ replace define V4L2_DV_BT_STD_SDI dv-bt-standards replace define V4L2_DV_FL_REDUCED_BLANKING dv-bt-standards replace define V4L2_DV_FL_CAN_REDUCE_FPS dv-bt-standards +replace define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS dv-bt-standards replace define V4L2_DV_FL_REDUCED_FPS dv-bt-standards replace define V4L2_DV_FL_HALF_LINE dv-bt-standards replace define V4L2_DV_FL_IS_CE_VIDEO dv-bt-standards -- cgit v1.2.3 From 6ea0d588d35b55e6df8e9ac12b95c34a669c39d4 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Aug 2018 07:37:08 -0400 Subject: media: uvcvideo: Add a D4M camera description D4M is a mobile model from the D4XX family of Intel RealSense cameras. This patch adds a descriptor for it, which enables reading per-frame metadata from it. Signed-off-by: Guennadi Liakhovetski [laurent.pinchart@ideasonboard.com Small clarifications to the documentation] Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/meta-formats.rst | 1 + Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst | 210 ++++++++++++++++++++++ drivers/media/usb/uvc/uvc_driver.c | 11 ++ include/uapi/linux/videodev2.h | 1 + 4 files changed, 223 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst index 0c4e1ecf5879..cf971d5ad9ea 100644 --- a/Documentation/media/uapi/v4l/meta-formats.rst +++ b/Documentation/media/uapi/v4l/meta-formats.rst @@ -12,6 +12,7 @@ These formats are used for the :ref:`metadata` interface only. .. toctree:: :maxdepth: 1 + pixfmt-meta-d4xx pixfmt-meta-uvc pixfmt-meta-vsp1-hgo pixfmt-meta-vsp1-hgt diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst new file mode 100644 index 000000000000..63bf1a2c9116 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst @@ -0,0 +1,210 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _v4l2-meta-fmt-d4xx: + +******************************* +V4L2_META_FMT_D4XX ('D4XX') +******************************* + +Intel D4xx UVC Cameras Metadata + + +Description +=========== + +Intel D4xx (D435 and other) cameras include per-frame metadata in their UVC +payload headers, following the Microsoft(R) UVC extension proposal [1_]. That +means, that the private D4XX metadata, following the standard UVC header, is +organised in blocks. D4XX cameras implement several standard block types, +proposed by Microsoft, and several proprietary ones. Supported standard metadata +types are MetadataId_CaptureStats (ID 3), MetadataId_CameraExtrinsics (ID 4), +and MetadataId_CameraIntrinsics (ID 5). For their description see [1_]. This +document describes proprietary metadata types, used by D4xx cameras. + +V4L2_META_FMT_D4XX buffers follow the metadata buffer layout of +V4L2_META_FMT_UVC with the only difference, that it also includes proprietary +payload header data. D4xx cameras use bulk transfers and only send one payload +per frame, therefore their headers cannot be larger than 255 bytes. + +Below are proprietary Microsoft style metadata types, used by D4xx cameras, +where all fields are in little endian order: + +.. flat-table:: D4xx metadata + :widths: 1 4 + :header-rows: 1 + :stub-columns: 0 + + * - Field + - Description + * - :cspan:`1` *Depth Control* + * - __u32 ID + - 0x80000000 + * - __u32 Size + - Size in bytes (currently 56) + * - __u32 Version + - Version of this structure. The documentation herein corresponds to + version xxx. The version number will be incremented when new fields are + added. + * - __u32 Flags + - A bitmask of flags: see [2_] below + * - __u32 Gain + - Gain value in internal units, same as the V4L2_CID_GAIN control, used to + capture the frame + * - __u32 Exposure + - Exposure time (in microseconds) used to capture the frame + * - __u32 Laser power + - Power of the laser LED 0-360, used for depth measurement + * - __u32 AE mode + - 0: manual; 1: automatic exposure + * - __u32 Exposure priority + - Exposure priority value: 0 - constant frame rate + * - __u32 AE ROI left + - Left border of the AE Region of Interest (all ROI values are in pixels + and lie between 0 and maximum width or height respectively) + * - __u32 AE ROI right + - Right border of the AE Region of Interest + * - __u32 AE ROI top + - Top border of the AE Region of Interest + * - __u32 AE ROI bottom + - Bottom border of the AE Region of Interest + * - __u32 Preset + - Preset selector value, default: 0, unless changed by the user + * - __u32 Laser mode + - 0: off, 1: on + * - :cspan:`1` *Capture Timing* + * - __u32 ID + - 0x80000001 + * - __u32 Size + - Size in bytes (currently 40) + * - __u32 Version + - Version of this structure. The documentation herein corresponds to + version xxx. The version number will be incremented when new fields are + added. + * - __u32 Flags + - A bitmask of flags: see [3_] below + * - __u32 Frame counter + - Monotonically increasing counter + * - __u32 Optical time + - Time in microseconds from the beginning of a frame till its middle + * - __u32 Readout time + - Time, used to read out a frame in microseconds + * - __u32 Exposure time + - Frame exposure time in microseconds + * - __u32 Frame interval + - In microseconds = 1000000 / framerate + * - __u32 Pipe latency + - Time in microseconds from start of frame to data in USB buffer + * - :cspan:`1` *Configuration* + * - __u32 ID + - 0x80000002 + * - __u32 Size + - Size in bytes (currently 40) + * - __u32 Version + - Version of this structure. The documentation herein corresponds to + version xxx. The version number will be incremented when new fields are + added. + * - __u32 Flags + - A bitmask of flags: see [4_] below + * - __u8 Hardware type + - Camera hardware version [5_] + * - __u8 SKU ID + - Camera hardware configuration [6_] + * - __u32 Cookie + - Internal synchronisation + * - __u16 Format + - Image format code [7_] + * - __u16 Width + - Width in pixels + * - __u16 Height + - Height in pixels + * - __u16 Framerate + - Requested frame rate per second + * - __u16 Trigger + - Byte 0: bit 0: depth and RGB are synchronised, bit 1: external trigger + +.. _1: + +[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5 + +.. _2: + +[2] Depth Control flags specify which fields are valid: :: + + 0x00000001 Gain + 0x00000002 Exposure + 0x00000004 Laser power + 0x00000008 AE mode + 0x00000010 Exposure priority + 0x00000020 AE ROI + 0x00000040 Preset + +.. _3: + +[3] Capture Timing flags specify which fields are valid: :: + + 0x00000001 Frame counter + 0x00000002 Optical time + 0x00000004 Readout time + 0x00000008 Exposure time + 0x00000010 Frame interval + 0x00000020 Pipe latency + +.. _4: + +[4] Configuration flags specify which fields are valid: :: + + 0x00000001 Hardware type + 0x00000002 SKU ID + 0x00000004 Cookie + 0x00000008 Format + 0x00000010 Width + 0x00000020 Height + 0x00000040 Framerate + 0x00000080 Trigger + 0x00000100 Cal count + +.. _5: + +[5] Camera model: :: + + 0 DS5 + 1 IVCAM2 + +.. _6: + +[6] 8-bit camera hardware configuration bitfield: :: + + [1:0] depthCamera + 00: no depth + 01: standard depth + 10: wide depth + 11: reserved + [2] depthIsActive - has a laser projector + [3] RGB presence + [4] Inertial Measurement Unit (IMU) presence + [5] projectorType + 0: HPTG + 1: Princeton + [6] 0: a projector, 1: an LED + [7] reserved + +.. _7: + +[7] Image format codes per video streaming interface: + +Depth: :: + + 1 Z16 + 2 Z + +Left sensor: :: + + 1 Y8 + 2 UYVY + 3 R8L8 + 4 Calibration + 5 W10 + +Fish Eye sensor: :: + + 1 RAW8 diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 9bc6027d04d0..b1114ec37a55 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2339,6 +2339,8 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { }; #define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q} +#define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \ + {.meta_format = m} /* * The Logitech cameras listed below have their interface class set to @@ -2812,6 +2814,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 }, + /* Intel RealSense D4M */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0b03, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 622f0479d668..184e4dbe8f9c 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -703,6 +703,7 @@ struct v4l2_pix_format { #define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */ #define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */ #define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */ +#define V4L2_META_FMT_D4XX v4l2_fourcc('D', '4', 'X', 'X') /* D4XX Payload Header metadata */ /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe -- cgit v1.2.3 From 34b41472465b1b5a2c6c63255431fb2c1a450af1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 23 Aug 2018 06:14:12 -0400 Subject: media: media-request: return -EINVAL for invalid request_fds Instead of returning -ENOENT when a request_fd was not found (VIDIOC_QBUF and VIDIOC_G/S/TRY_EXT_CTRLS), we now return -EINVAL. This is in line with what we do when invalid dmabuf fds are passed to e.g. VIDIOC_QBUF. Also document that EINVAL is returned for invalid m.fd values, we never documented that. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/buffer.rst | 4 ++-- Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst | 18 ++++++++---------- Documentation/media/uapi/v4l/vidioc-qbuf.rst | 12 +++++------- drivers/media/media-request.c | 6 ++++-- include/media/media-request.h | 2 +- 5 files changed, 20 insertions(+), 22 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index dd0065a95ea0..35c2fadd10de 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst @@ -313,8 +313,8 @@ struct v4l2_buffer queued to that request. This is set by the user when calling :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls. If the device does not support requests, then ``EPERM`` will be returned. - If requests are supported but an invalid request FD is given, then - ``ENOENT`` will be returned. + If requests are supported but an invalid request file descriptor is + given, then ``EINVAL`` will be returned. diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 771fd1161277..9c56a9b6e98a 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -101,8 +101,8 @@ then the controls are not applied immediately when calling :ref:`VIDIOC_S_EXT_CTRLS `, but instead are applied by the driver for the buffer associated with the same request. If the device does not support requests, then ``EPERM`` will be returned. -If requests are supported but an invalid request FD is given, then -``ENOENT`` will be returned. +If requests are supported but an invalid request file descriptor is given, +then ``EINVAL`` will be returned. An attempt to call :ref:`VIDIOC_S_EXT_CTRLS ` for a request that has already been queued will result in an ``EBUSY`` error. @@ -301,8 +301,8 @@ still cause this situation. - File descriptor of the request to be used by this operation. Only valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``. If the device does not support requests, then ``EPERM`` will be returned. - If requests are supported but an invalid request FD is given, then - ``ENOENT`` will be returned. + If requests are supported but an invalid request file descriptor is + given, then ``EINVAL`` will be returned. * - __u32 - ``reserved``\ [1] - Reserved for future extensions. @@ -378,11 +378,13 @@ appropriately. The generic error codes are described at the EINVAL The struct :c:type:`v4l2_ext_control` ``id`` is - invalid, the struct :c:type:`v4l2_ext_controls` + invalid, or the struct :c:type:`v4l2_ext_controls` ``which`` is invalid, or the struct :c:type:`v4l2_ext_control` ``value`` was inappropriate (e.g. the given menu index is not supported by the - driver). This error code is also returned by the + driver), or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` + but the given ``request_fd`` was invalid. + This error code is also returned by the :ref:`VIDIOC_S_EXT_CTRLS ` and :ref:`VIDIOC_TRY_EXT_CTRLS ` ioctls if two or more control values are in conflict. @@ -409,7 +411,3 @@ EACCES EPERM The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the device does not support requests. - -ENOENT - The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the - the given ``request_fd`` was invalid. diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index 0e415f2551b2..7bff69c15452 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -105,8 +105,8 @@ until the request itself is queued. Also, the driver will apply any settings associated with the request for this buffer. This field will be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set. If the device does not support requests, then ``EPERM`` will be returned. -If requests are supported but an invalid request FD is given, then -``ENOENT`` will be returned. +If requests are supported but an invalid request file descriptor is given, +then ``EINVAL`` will be returned. .. caution:: It is not allowed to mix queuing requests with queuing buffers directly. @@ -152,7 +152,9 @@ EAGAIN EINVAL The buffer ``type`` is not supported, or the ``index`` is out of bounds, or no buffers have been allocated yet, or the ``userptr`` or - ``length`` are invalid. + ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was + set but the the given ``request_fd`` was invalid, or ``m.fd`` was + an invalid DMABUF file descriptor. EIO ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate @@ -179,7 +181,3 @@ EPERM the application now tries to queue it directly, or vice versa (it is not permitted to mix the two APIs). Or an attempt is made to queue a CAPTURE buffer to a request for a :ref:`memory-to-memory device `. - -ENOENT - The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the the given - ``request_fd`` was invalid. diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c index 4b0ce8fde7c9..4cee67e6657e 100644 --- a/drivers/media/media-request.c +++ b/drivers/media/media-request.c @@ -244,7 +244,7 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd) filp = fget(request_fd); if (!filp) - return ERR_PTR(-ENOENT); + goto err_no_req_fd; if (filp->f_op != &request_fops) goto err_fput; @@ -268,7 +268,9 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd) err_fput: fput(filp); - return ERR_PTR(-ENOENT); +err_no_req_fd: + dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd); + return ERR_PTR(-EINVAL); } EXPORT_SYMBOL_GPL(media_request_get_by_fd); diff --git a/include/media/media-request.h b/include/media/media-request.h index ac02019c1d77..453a6b95c61a 100644 --- a/include/media/media-request.h +++ b/include/media/media-request.h @@ -153,7 +153,7 @@ void media_request_put(struct media_request *req); * by the media device. * * Return a -EPERM error pointer if requests are not supported - * by this driver. Return -ENOENT if the request was not found. + * by this driver. Return -EINVAL if the request was not found. * Return the pointer to the request if found: the caller will * have to call @media_request_put when it finished using the * request. -- cgit v1.2.3 From b6b84557eca71ae0631be1567fec85870a2c1b93 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 23 Aug 2018 06:33:49 -0400 Subject: media: v4l2-ctrls: return -EACCES if request wasn't completed For now (this might be relaxed in the future) we do not allow getting controls from a request that isn't completed. In that case we return -EACCES. Update the documentation accordingly. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst | 18 +++++++++--------- drivers/media/v4l2-core/v4l2-ctrls.c | 5 ++--- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 9c56a9b6e98a..ad8908ce3095 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -107,13 +107,12 @@ then ``EINVAL`` will be returned. An attempt to call :ref:`VIDIOC_S_EXT_CTRLS ` for a request that has already been queued will result in an ``EBUSY`` error. -If ``request_fd`` is specified and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` -during a call to :ref:`VIDIOC_G_EXT_CTRLS `, then the -returned values will be the values currently set for the request (or the -hardware value if none is set) if the request has not yet been queued, or the -values of the controls at the time of request completion if it has already -completed. Attempting to get controls while the request has been queued but -not yet completed will result in an ``EBUSY`` error. +If ``request_fd`` is specified and ``which`` is set to +``V4L2_CTRL_WHICH_REQUEST_VAL`` during a call to +:ref:`VIDIOC_G_EXT_CTRLS `, then it will return the +values of the controls at the time of request completion. +If the request is not yet completed, then this will result in an +``EACCES`` error. The driver will only set/get these controls if all control values are correct. This prevents the situation where only some of the controls @@ -405,8 +404,9 @@ ENOSPC and this error code is returned. EACCES - Attempt to try or set a read-only control or to get a write-only - control. + Attempt to try or set a read-only control, or to get a write-only + control, or to get a control from a request that has not yet been + completed. EPERM The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index a197b60183f5..ccaf3068de6d 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -3301,10 +3301,9 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev, if (IS_ERR(req)) return PTR_ERR(req); - if (req->state != MEDIA_REQUEST_STATE_IDLE && - req->state != MEDIA_REQUEST_STATE_COMPLETE) { + if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { media_request_put(req); - return -EBUSY; + return -EACCES; } obj = v4l2_ctrls_find_req_obj(hdl, req, false); -- cgit v1.2.3 From dc58a553ba8c4edd26c4f585bbbc16ab2f0ec35f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 23 Aug 2018 06:45:09 -0400 Subject: media: buffer.rst: only set V4L2_BUF_FLAG_REQUEST_FD for QBUF Document that V4L2_BUF_FLAG_REQUEST_FD should only be used with VIDIOC_QBUF and cleared otherwise. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/buffer.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index 35c2fadd10de..1865cd5b9d3c 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst @@ -312,6 +312,8 @@ struct v4l2_buffer and flag ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be queued to that request. This is set by the user when calling :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls. + Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls + other than :ref:`VIDIOC_QBUF `. If the device does not support requests, then ``EPERM`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. -- cgit v1.2.3 From f35f5d72e70e6b91389eb98fcabf43b79f40587f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 23 Aug 2018 09:56:22 -0400 Subject: media: videodev2.h: add new capabilities for buffer types VIDIOC_REQBUFS and VIDIOC_CREATE_BUFFERS will return capabilities telling userspace what the given buffer type is capable of. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/v4l/vidioc-create-bufs.rst | 14 +++++++- Documentation/media/uapi/v4l/vidioc-reqbufs.rst | 42 +++++++++++++++++++++- include/uapi/linux/videodev2.h | 13 +++++-- 3 files changed, 65 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst index a39e18d69511..eadf6f757fbf 100644 --- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst @@ -102,7 +102,19 @@ than the number requested. - ``format`` - Filled in by the application, preserved by the driver. * - __u32 - - ``reserved``\ [8] + - ``capabilities`` + - Set by the driver. If 0, then the driver doesn't support + capabilities. In that case all you know is that the driver is + guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support + other :c:type:`v4l2_memory` types. It will not support any others + capabilities. See :ref:`here ` for a list of the + capabilities. + + If you want to just query the capabilities without making any + other changes, then set ``count`` to 0, ``memory`` to + ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type. + * - __u32 + - ``reserved``\ [7] - A place holder for future extensions. Drivers and applications must set the array to zero. diff --git a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst index 316f52c8a310..d4bbbb0c60e8 100644 --- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst @@ -88,10 +88,50 @@ any DMA in progress, an implicit ``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See :c:type:`v4l2_memory`. * - __u32 - - ``reserved``\ [2] + - ``capabilities`` + - Set by the driver. If 0, then the driver doesn't support + capabilities. In that case all you know is that the driver is + guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support + other :c:type:`v4l2_memory` types. It will not support any others + capabilities. + + If you want to query the capabilities with a minimum of side-effects, + then this can be called with ``count`` set to 0, ``memory`` set to + ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will + free any previously allocated buffers, so this is typically something + that will be done at the start of the application. + * - __u32 + - ``reserved``\ [1] - A place holder for future extensions. Drivers and applications must set the array to zero. +.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}| + +.. _v4l2-buf-capabilities: +.. _V4L2-BUF-CAP-SUPPORTS-MMAP: +.. _V4L2-BUF-CAP-SUPPORTS-USERPTR: +.. _V4L2-BUF-CAP-SUPPORTS-DMABUF: +.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: + +.. cssclass:: longtable + +.. flat-table:: V4L2 Buffer Capabilities Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * - ``V4L2_BUF_CAP_SUPPORTS_MMAP`` + - 0x00000001 + - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode. + * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR`` + - 0x00000002 + - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode. + * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF`` + - 0x00000004 + - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode. + * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` + - 0x00000008 + - This buffer type supports :ref:`requests `. Return Value ============ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 2350151ce4ea..55d45a387dd2 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -856,9 +856,16 @@ struct v4l2_requestbuffers { __u32 count; __u32 type; /* enum v4l2_buf_type */ __u32 memory; /* enum v4l2_memory */ - __u32 reserved[2]; + __u32 capabilities; + __u32 reserved[1]; }; +/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */ +#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0) +#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) +#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) +#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) + /** * struct v4l2_plane - plane info for multi-planar buffers * @bytesused: number of bytes occupied by data in the plane (payload) @@ -2319,6 +2326,7 @@ struct v4l2_dbg_chip_info { * return: number of created buffers * @memory: enum v4l2_memory; buffer memory type * @format: frame format, for which buffers are requested + * @capabilities: capabilities of this buffer type. * @reserved: future extensions */ struct v4l2_create_buffers { @@ -2326,7 +2334,8 @@ struct v4l2_create_buffers { __u32 count; __u32 memory; struct v4l2_format format; - __u32 reserved[8]; + __u32 capabilities; + __u32 reserved[7]; }; /* -- cgit v1.2.3 From 15cd442e79e2a60a725ee5501e4ffb537698c802 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Sep 2018 07:29:14 -0400 Subject: media: media-request: EPERM -> EACCES/EBUSY If requests are not supported by the driver, then return EACCES, not EPERM. If you attempt to mix queueing buffers directly and using requests, then EBUSY is returned instead of EPERM: once a specific queueing mode has been chosen the queue is 'busy' if you attempt the other mode (i.e. direct queueing vs via a request). Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/mediactl/media-request-ioc-queue.rst | 9 ++++----- Documentation/media/uapi/mediactl/request-api.rst | 4 ++-- Documentation/media/uapi/v4l/buffer.rst | 2 +- Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst | 9 ++++----- Documentation/media/uapi/v4l/vidioc-qbuf.rst | 18 ++++++++++-------- drivers/media/common/videobuf2/videobuf2-core.c | 2 +- drivers/media/common/videobuf2/videobuf2-v4l2.c | 9 ++++++--- drivers/media/media-request.c | 4 ++-- include/media/media-request.h | 4 ++-- 9 files changed, 32 insertions(+), 29 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst index d4f8119e0643..dbf635ae9b2b 100644 --- a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst @@ -49,7 +49,7 @@ exception is the ``EIO`` error which signals a fatal error that requires the application to stop streaming to reset the hardware state. It is not allowed to mix queuing requests with queuing buffers directly -(without a request). ``EPERM`` will be returned if the first buffer was +(without a request). ``EBUSY`` will be returned if the first buffer was queued directly and you next try to queue a request, or vice versa. A request must contain at least one buffer, otherwise this ioctl will @@ -63,10 +63,9 @@ appropriately. The generic error codes are described at the :ref:`Generic Error Codes ` chapter. EBUSY - The request was already queued. -EPERM - The application queued the first buffer directly, but later attempted - to use a request. It is not permitted to mix the two APIs. + The request was already queued or the application queued the first + buffer directly, but later attempted to use a request. It is not permitted + to mix the two APIs. ENOENT The request did not contain any buffers. All requests are required to have at least one buffer. This can also be returned if required diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst index 0b9da58b01e3..aeb8d00934a4 100644 --- a/Documentation/media/uapi/mediactl/request-api.rst +++ b/Documentation/media/uapi/mediactl/request-api.rst @@ -64,7 +64,7 @@ request cannot be modified anymore. .. caution:: For :ref:`memory-to-memory devices ` you can use requests only for output buffers, not for capture buffers. Attempting to add a capture buffer - to a request will result in an ``EPERM`` error. + to a request will result in an ``EACCES`` error. If the request contains parameters for multiple entities, individual drivers may synchronize so the requested pipeline's topology is applied before the buffers @@ -77,7 +77,7 @@ perfect atomicity may not be possible due to hardware limitations. whichever method is used first locks this in place until :ref:`VIDIOC_STREAMOFF ` is called or the device is :ref:`closed `. Attempts to directly queue a buffer when earlier - a buffer was queued via a request or vice versa will result in an ``EPERM`` + a buffer was queued via a request or vice versa will result in an ``EBUSY`` error. Controls can still be set without a request and are applied immediately, diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index 1865cd5b9d3c..58a6d7d336e6 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst @@ -314,7 +314,7 @@ struct v4l2_buffer :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls. Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls other than :ref:`VIDIOC_QBUF `. - If the device does not support requests, then ``EPERM`` will be returned. + If the device does not support requests, then ``EACCES`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index ad8908ce3095..54a999df5aec 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -100,7 +100,7 @@ file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``, then the controls are not applied immediately when calling :ref:`VIDIOC_S_EXT_CTRLS `, but instead are applied by the driver for the buffer associated with the same request. -If the device does not support requests, then ``EPERM`` will be returned. +If the device does not support requests, then ``EACCES`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. @@ -233,7 +233,7 @@ still cause this situation. these controls have to be retrieved from a request or tried/set for a request. In the latter case the ``request_fd`` field contains the file descriptor of the request that should be used. If the device - does not support requests, then ``EPERM`` will be returned. + does not support requests, then ``EACCES`` will be returned. .. note:: @@ -299,7 +299,7 @@ still cause this situation. - ``request_fd`` - File descriptor of the request to be used by this operation. Only valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``. - If the device does not support requests, then ``EPERM`` will be returned. + If the device does not support requests, then ``EACCES`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. * - __u32 @@ -408,6 +408,5 @@ EACCES control, or to get a control from a request that has not yet been completed. -EPERM - The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the + Or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the device does not support requests. diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index 7bff69c15452..e619fc80a323 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -104,18 +104,18 @@ in use. Setting it means that the buffer will not be passed to the driver until the request itself is queued. Also, the driver will apply any settings associated with the request for this buffer. This field will be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set. -If the device does not support requests, then ``EPERM`` will be returned. +If the device does not support requests, then ``EACCES`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. .. caution:: It is not allowed to mix queuing requests with queuing buffers directly. - ``EPERM`` will be returned if the first buffer was queued directly and + ``EBUSY`` will be returned if the first buffer was queued directly and then the application tries to queue a request, or vice versa. For :ref:`memory-to-memory devices ` you can specify the ``request_fd`` only for output buffers, not for capture buffers. Attempting - to specify this for a capture buffer will result in an ``EPERM`` error. + to specify this for a capture buffer will result in an ``EACCES`` error. Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled (capturing) or displayed (output) buffer from the driver's outgoing @@ -175,9 +175,11 @@ EPIPE codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already dequeued and no new buffers are expected to become available. -EPERM +EACCES The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not - support requests. Or the first buffer was queued via a request, but - the application now tries to queue it directly, or vice versa (it is - not permitted to mix the two APIs). Or an attempt is made to queue a - CAPTURE buffer to a request for a :ref:`memory-to-memory device `. + support requests for the given buffer type. + +EBUSY + The first buffer was queued via a request, but the application now tries + to queue it directly, or vice versa (it is not permitted to mix the two + APIs). diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 2dc3fc935f87..cb86b02afd4a 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -1495,7 +1495,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, (!req && vb->state != VB2_BUF_STATE_IN_REQUEST && q->uses_requests)) { dprintk(1, "queue in wrong mode (qbuf vs requests)\n"); - return -EPERM; + return -EBUSY; } if (req) { diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 2caaabd50532..6831a2eb1859 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -381,12 +381,15 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) { if (q->uses_requests) { dprintk(1, "%s: queue uses requests\n", opname); - return -EPERM; + return -EBUSY; } return 0; - } else if (q->uses_qbuf || !q->supports_requests) { + } else if (!q->supports_requests) { + dprintk(1, "%s: queue does not support requests\n", opname); + return -EACCES; + } else if (q->uses_qbuf) { dprintk(1, "%s: queue does not use requests\n", opname); - return -EPERM; + return -EBUSY; } /* diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c index 414197645e09..4e9db1fed697 100644 --- a/drivers/media/media-request.c +++ b/drivers/media/media-request.c @@ -249,7 +249,7 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd) if (!mdev || !mdev->ops || !mdev->ops->req_validate || !mdev->ops->req_queue) - return ERR_PTR(-EPERM); + return ERR_PTR(-EACCES); filp = fget(request_fd); if (!filp) @@ -405,7 +405,7 @@ int media_request_object_bind(struct media_request *req, int ret = -EBUSY; if (WARN_ON(!ops->release)) - return -EPERM; + return -EACCES; spin_lock_irqsave(&req->lock, flags); diff --git a/include/media/media-request.h b/include/media/media-request.h index f0920aa84509..0ce75c35131f 100644 --- a/include/media/media-request.h +++ b/include/media/media-request.h @@ -198,7 +198,7 @@ void media_request_put(struct media_request *req); * Get the request represented by @request_fd that is owned * by the media device. * - * Return a -EPERM error pointer if requests are not supported + * Return a -EACCES error pointer if requests are not supported * by this driver. Return -EINVAL if the request was not found. * Return the pointer to the request if found: the caller will * have to call @media_request_put when it finished using the @@ -231,7 +231,7 @@ static inline void media_request_put(struct media_request *req) static inline struct media_request * media_request_get_by_fd(struct media_device *mdev, int request_fd) { - return ERR_PTR(-EPERM); + return ERR_PTR(-EACCES); } #endif -- cgit v1.2.3 From d4215edbd4b170b207b0e5a1d8ae42fb49f5c470 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Aug 2018 05:11:04 -0400 Subject: media: media-request: update documentation Various clarifications and readability improvements based on Laurent Pinchart's review of the documentation. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../uapi/mediactl/media-ioc-request-alloc.rst | 3 +- .../uapi/mediactl/media-request-ioc-queue.rst | 7 +-- Documentation/media/uapi/mediactl/request-api.rst | 51 ++++++++++++---------- .../media/uapi/mediactl/request-func-close.rst | 1 + .../media/uapi/mediactl/request-func-poll.rst | 2 +- Documentation/media/uapi/v4l/buffer.rst | 14 ++++-- .../media/uapi/v4l/vidioc-g-ext-ctrls.rst | 5 ++- Documentation/media/uapi/v4l/vidioc-qbuf.rst | 5 ++- 8 files changed, 52 insertions(+), 36 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst index 34434e2b3918..0f8b31874002 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst @@ -52,7 +52,8 @@ for the request to complete. The request will remain allocated until all the file descriptors associated with it are closed by :ref:`close() ` and the driver no -longer uses the request internally. +longer uses the request internally. See also +:ref:`here ` for more information. Return Value ============ diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst index dbf635ae9b2b..6dd2d7fea714 100644 --- a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst @@ -40,9 +40,6 @@ Other errors can be returned if the contents of the request contained invalid or inconsistent data, see the next section for a list of common error codes. On error both the request and driver state are unchanged. -Typically if you get an error here, then that means that the application -did something wrong and you have to fix the application. - Once a request is queued, then the driver is required to gracefully handle errors that occur when the request is applied to the hardware. The exception is the ``EIO`` error which signals a fatal error that requires @@ -68,8 +65,8 @@ EBUSY to mix the two APIs. ENOENT The request did not contain any buffers. All requests are required - to have at least one buffer. This can also be returned if required - controls are missing. + to have at least one buffer. This can also be returned if some required + configuration is missing in the request. ENOMEM Out of memory when allocating internal data structures for this request. diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst index aeb8d00934a4..5f4a23029c48 100644 --- a/Documentation/media/uapi/mediactl/request-api.rst +++ b/Documentation/media/uapi/mediactl/request-api.rst @@ -12,6 +12,9 @@ the same pipeline to reconfigure and collaborate closely on a per-frame basis. Another is support of stateless codecs, which require controls to be applied to specific frames (aka 'per-frame controls') in order to be used efficiently. +While the initial use-case was V4L2, it can be extended to other subsystems +as well, as long as they use the media controller. + Supporting these features without the Request API is not always possible and if it is, it is terribly inefficient: user-space would have to flush all activity on the media pipeline, reconfigure it for the next frame, queue the buffers to @@ -20,19 +23,23 @@ dequeuing before considering the next frame. This defeats the purpose of having buffer queues since in practice only one buffer would be queued at a time. The Request API allows a specific configuration of the pipeline (media -controller topology + controls for each media entity) to be associated with -specific buffers. The parameters are applied by each participating device as -buffers associated to a request flow in. This allows user-space to schedule -several tasks ("requests") with different parameters in advance, knowing that -the parameters will be applied when needed to get the expected result. Control -values at the time of request completion are also available for reading. +controller topology + configuration for each media entity) to be associated with +specific buffers. This allows user-space to schedule several tasks ("requests") +with different configurations in advance, knowing that the configuration will be +applied when needed to get the expected result. Configuration values at the time +of request completion are also available for reading. Usage ===== -The Request API is used on top of standard media controller and V4L2 calls, -which are augmented with an extra ``request_fd`` parameter. Requests themselves -are allocated from the supporting media controller node. +The Request API extends the Media Controller API and cooperates with +subsystem-specific APIs to support request usage. At the Media Controller +level, requests are allocated from the supporting Media Controller device +node. Their life cycle is then managed through the request file descriptors in +an opaque way. Configuration data, buffer handles and processing results +stored in requests are accessed through subsystem-specific APIs extended for +request support, such as V4L2 APIs that take an explicit ``request_fd`` +parameter. Request Allocation ------------------ @@ -47,29 +54,27 @@ Request Preparation Standard V4L2 ioctls can then receive a request file descriptor to express the fact that the ioctl is part of said request, and is not to be applied immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that -support this. Controls set with a ``request_fd`` parameter are stored instead -of being immediately applied, and buffers queued to a request do not enter the -regular buffer queue until the request itself is queued. +support this. Configurations set with a ``request_fd`` parameter are stored +instead of being immediately applied, and buffers queued to a request do not +enter the regular buffer queue until the request itself is queued. Request Submission ------------------ -Once the parameters and buffers of the request are specified, it can be +Once the configuration and buffers of the request are specified, it can be queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor. A request must contain at least one buffer, otherwise ``ENOENT`` is returned. -This will make the buffers associated to the request available to their driver, -which can then apply the associated controls as buffers are processed. A queued -request cannot be modified anymore. +A queued request cannot be modified anymore. .. caution:: For :ref:`memory-to-memory devices ` you can use requests only for output buffers, not for capture buffers. Attempting to add a capture buffer to a request will result in an ``EACCES`` error. -If the request contains parameters for multiple entities, individual drivers may -synchronize so the requested pipeline's topology is applied before the buffers -are processed. Media controller drivers do a best effort implementation since -perfect atomicity may not be possible due to hardware limitations. +If the request contains configurations for multiple entities, individual drivers +may synchronize so the requested pipeline's topology is applied before the +buffers are processed. Media controller drivers do a best effort implementation +since perfect atomicity may not be possible due to hardware limitations. .. caution:: @@ -96,14 +101,16 @@ Note that user-space does not need to wait for the request to complete to dequeue its buffers: buffers that are available halfway through a request can be dequeued independently of the request's state. -A completed request contains the state of the request at the time of the -request completion. User-space can query that state by calling +A completed request contains the state of the device after the request was +executed. User-space can query that state by calling :ref:`ioctl VIDIOC_G_EXT_CTRLS ` with the request file descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS ` for a request that has been queued but not yet completed will return ``EBUSY`` since the control values might be changed at any time by the driver while the request is in flight. +.. _media-request-life-time: + Recycling and Destruction ------------------------- diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst index b5c78683840b..098d7f2b9548 100644 --- a/Documentation/media/uapi/mediactl/request-func-close.rst +++ b/Documentation/media/uapi/mediactl/request-func-close.rst @@ -36,6 +36,7 @@ Description Closes the request file descriptor. Resources associated with the request are freed once all file descriptors associated with the request are closed and the driver has completed the request. +See :ref:`here ` for more information. Return Value diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst index 70cc9d406a9f..85191254f381 100644 --- a/Documentation/media/uapi/mediactl/request-func-poll.rst +++ b/Documentation/media/uapi/mediactl/request-func-poll.rst @@ -50,7 +50,7 @@ when the request was completed. When the function times out it returns a value of zero, on failure it returns -1 and the ``errno`` variable is set appropriately. -Attempting to poll for a request that is completed or not yet queued will +Attempting to poll for a request that is not yet queued will set the ``POLLERR`` flag in ``revents``. diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index 58a6d7d336e6..2e266d32470a 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst @@ -308,12 +308,18 @@ struct v4l2_buffer * - __u32 - ``request_fd`` - - - The file descriptor of the request to queue the buffer to. If specified - and flag ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be - queued to that request. This is set by the user when calling - :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls. + - The file descriptor of the request to queue the buffer to. If the flag + ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be + queued to this request. If the flag is not set, then this field will + be ignored. + + The ``V4L2_BUF_FLAG_REQUEST_FD`` flag and this field are only used by + :ref:`ioctl VIDIOC_QBUF ` and ignored by other ioctls that + take a :c:type:`v4l2_buffer` as argument. + Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls other than :ref:`VIDIOC_QBUF `. + If the device does not support requests, then ``EACCES`` will be returned. If requests are supported but an invalid request file descriptor is given, then ``EINVAL`` will be returned. diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 54a999df5aec..d9930fe776cf 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -237,7 +237,7 @@ still cause this situation. .. note:: - When using ``V4L2_CTRL_WHICH_DEF_VAL`` note that You can only + When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only get the default value of the control, you cannot set or try it. For backwards compatibility you can also use a control class here @@ -382,7 +382,8 @@ EINVAL :c:type:`v4l2_ext_control` ``value`` was inappropriate (e.g. the given menu index is not supported by the driver), or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` - but the given ``request_fd`` was invalid. + but the given ``request_fd`` was invalid or ``V4L2_CTRL_WHICH_REQUEST_VAL`` + is not supported by the kernel. This error code is also returned by the :ref:`VIDIOC_S_EXT_CTRLS ` and :ref:`VIDIOC_TRY_EXT_CTRLS ` ioctls if two or more control values are in conflict. diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index e619fc80a323..753b3b5946b1 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -111,7 +111,10 @@ then ``EINVAL`` will be returned. .. caution:: It is not allowed to mix queuing requests with queuing buffers directly. ``EBUSY`` will be returned if the first buffer was queued directly and - then the application tries to queue a request, or vice versa. + then the application tries to queue a request, or vice versa. After + closing the file descriptor, calling + :ref:`VIDIOC_STREAMOFF ` or calling :ref:`VIDIOC_REQBUFS` + the check for this will be reset. For :ref:`memory-to-memory devices ` you can specify the ``request_fd`` only for output buffers, not for capture buffers. Attempting -- cgit v1.2.3 From 20b00bbe70bd6aa48bd654fe2d1e742b9c060eb0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Sep 2018 11:04:00 -0400 Subject: media: vidioc-cropcap/g-crop.rst: fix confusing sentence The note that the text refers to is actually *below* the type description, not above. Fix this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/vidioc-cropcap.rst | 2 +- Documentation/media/uapi/v4l/vidioc-g-crop.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/vidioc-cropcap.rst b/Documentation/media/uapi/v4l/vidioc-cropcap.rst index a65dbec6b20b..0a7b8287fd38 100644 --- a/Documentation/media/uapi/v4l/vidioc-cropcap.rst +++ b/Documentation/media/uapi/v4l/vidioc-cropcap.rst @@ -58,7 +58,7 @@ overlay devices. - Type of the data stream, set by the application. Only these types are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above. + ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below. * - struct :ref:`v4l2_rect ` - ``bounds`` - Defines the window within capturing or output is possible, this diff --git a/Documentation/media/uapi/v4l/vidioc-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-g-crop.rst index a6ed43ba9ca3..b95ba6743cbd 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-crop.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-crop.rst @@ -84,7 +84,7 @@ When cropping is not supported then no parameters are changed and - Type of the data stream, set by the application. Only these types are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above. + ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below. * - struct :c:type:`v4l2_rect` - ``c`` - Cropping rectangle. The same co-ordinate system as for struct -- cgit v1.2.3 From b0c351b55bfbc99a83f33536ae66c3f6104362cd Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 6 Sep 2018 05:02:12 -0400 Subject: media: dt-bindings: media: Add i.MX Pixel Pipeline binding Add DT binding documentation for the Pixel Pipeline (PXP) found on various NXP i.MX SoCs. Signed-off-by: Philipp Zabel Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/fsl-pxp.txt | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/fsl-pxp.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/fsl-pxp.txt b/Documentation/devicetree/bindings/media/fsl-pxp.txt new file mode 100644 index 000000000000..2477e7f87381 --- /dev/null +++ b/Documentation/devicetree/bindings/media/fsl-pxp.txt @@ -0,0 +1,26 @@ +Freescale Pixel Pipeline +======================== + +The Pixel Pipeline (PXP) is a memory-to-memory graphics processing engine +that supports scaling, colorspace conversion, alpha blending, rotation, and +pixel conversion via lookup table. Different versions are present on various +i.MX SoCs from i.MX23 to i.MX7. + +Required properties: +- compatible: should be "fsl,-pxp", where SoC can be one of imx23, imx28, + imx6dl, imx6sl, imx6ul, imx6sx, imx6ull, or imx7d. +- reg: the register base and size for the device registers +- interrupts: the PXP interrupt, two interrupts for imx6ull and imx7d. +- clock-names: should be "axi" +- clocks: the PXP AXI clock + +Example: + +pxp@21cc000 { + compatible = "fsl,imx6ull-pxp"; + reg = <0x021cc000 0x4000>; + interrupts = , + ; + clock-names = "axi"; + clocks = <&clks IMX6UL_CLK_PXP>; +}; -- cgit v1.2.3 From ad9ff96f65383f8296082158f7e44e466caaf71d Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 7 Sep 2018 20:41:36 +0300 Subject: drm/vkms: Add kerneldoc entry Add an initial kerneldoc entry for vkms with a todo list. Signed-off-by: Haneen Mohammed [danvet: Keep the todo.rst entry to point at the vkms docs instead.] Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180907174136.GA2648@haneenDRM --- Documentation/gpu/drivers.rst | 1 + Documentation/gpu/todo.rst | 7 +++++++ Documentation/gpu/vkms.rst | 24 ++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.c | 9 +++++++++ 4 files changed, 41 insertions(+) create mode 100644 Documentation/gpu/vkms.rst (limited to 'Documentation') diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index 65be325bf282..7d2d3875ff1a 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -13,6 +13,7 @@ GPU Driver Documentation tve200 v3d vc4 + vkms bridge/dw-hdmi xen-front diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 4c7c3ab60089..77c2b3c25565 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -360,6 +360,13 @@ converting things over. For modeset tests we also first need a bit of infrastructure to use dumb buffers for untiled buffers, to be able to run all the non-i915 specific modeset tests. +Extend virtual test driver (VKMS) +--------------------------------- + +See the documentation of :ref:`VKMS ` for more details. This is an ideal +internship task, since it only requires a virtual machine and can be sized to +fit the available time. + Contact: Daniel Vetter Driver Specific diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst new file mode 100644 index 000000000000..0a6ea6216e41 --- /dev/null +++ b/Documentation/gpu/vkms.rst @@ -0,0 +1,24 @@ +.. _vkms: + +========================================== + drm/vkms Virtual Kernel Modesetting +========================================== + +.. kernel-doc:: drivers/gpu/drm/vkms/vkms_drv.c + :doc: vkms (Virtual Kernel Modesetting) + +TODO +==== + +CRC API +------- + +- Optimize CRC computation ``compute_crc()`` and plane blending ``blend()`` + +- Use the alpha value to blend vaddr_src with vaddr_dst instead of + overwriting it in ``blend()``. + +- Add igt test to check cleared alpha value for XRGB plane format. + +- Add igt test to check extreme alpha values i.e. fully opaque and fully + transparent (intermediate values are affected by hw-specific rounding modes). diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 2d49ad31ad0b..07cfde1b4132 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -5,6 +5,15 @@ * (at your option) any later version. */ +/** + * DOC: vkms (Virtual Kernel Modesetting) + * + * vkms is a software-only model of a kms driver that is useful for testing, + * or for running X (or similar) on headless machines and be able to still + * use the GPU. vkms aims to enable a virtual display without the need for + * a hardware display capability. + */ + #include #include #include -- cgit v1.2.3 From af04a9cd9adb894da5dd41329f50b63f162fa083 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 2 Aug 2018 12:34:20 +0200 Subject: dt-bindings: imx6q-clock: add new fsl,pmic-stby-poweroff property Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/clock/imx6q-clock.txt | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index a45ca67a9d5f..e1308346e00d 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -6,6 +6,14 @@ Required properties: - interrupts: Should contain CCM interrupt - #clock-cells: Should be <1> +Optional properties: +- fsl,pmic-stby-poweroff: Configure CCM to assert PMIC_STBY_REQ signal + on power off. + Use this property if the SoC should be powered off by external power + management IC (PMIC) triggered via PMIC_STBY_REQ signal. + Boards that are designed to initiate poweroff on PMIC_ON_REQ signal should + be using "syscon-poweroff" driver instead. + The clock consumer should specify the desired clock by having the clock ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6qdl-clock.h for the full list of i.MX6 Quad and DualLite clock IDs. -- cgit v1.2.3 From 7f0e99cc916933ecd7fd407e2eb42448198e0404 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:53:19 +0100 Subject: soc: renesas: rcar-sysc: Add r8a774a1 support Add support for RZ/G2M (R8A774A1) SoC power areas to the R-Car SYSC driver. Signed-off-by: Biju Das Reviewed-by: Chris Paterson Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- .../bindings/power/renesas,rcar-sysc.txt | 1 + drivers/soc/renesas/Kconfig | 5 +++ drivers/soc/renesas/Makefile | 1 + drivers/soc/renesas/r8a774a1-sysc.c | 45 ++++++++++++++++++++++ drivers/soc/renesas/rcar-sysc.c | 3 ++ drivers/soc/renesas/rcar-sysc.h | 1 + 6 files changed, 56 insertions(+) create mode 100644 drivers/soc/renesas/r8a774a1-sysc.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index 180ae65be753..4e3ec6ac6345 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -10,6 +10,7 @@ Required properties: - "renesas,r8a7743-sysc" (RZ/G1M) - "renesas,r8a7745-sysc" (RZ/G1E) - "renesas,r8a77470-sysc" (RZ/G1C) + - "renesas,r8a774a1-sysc" (RZ/G2M) - "renesas,r8a7779-sysc" (R-Car H1) - "renesas,r8a7790-sysc" (R-Car H2) - "renesas,r8a7791-sysc" (R-Car M2-W) diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 1d824cbd462d..d769330b640e 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -9,6 +9,7 @@ config SOC_RENESAS select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7745 if ARCH_R8A7745 select SYSC_R8A77470 if ARCH_R8A77470 + select SYSC_R8A774A1 if ARCH_R8A774A1 select SYSC_R8A7779 if ARCH_R8A7779 select SYSC_R8A7790 if ARCH_R8A7790 select SYSC_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793 @@ -37,6 +38,10 @@ config SYSC_R8A77470 bool "RZ/G1C System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A774A1 + bool "RZ/G2M System Controller support" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A7779 bool "R-Car H1 System Controller support" if COMPILE_TEST select SYSC_RCAR diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index c37b0803c1b6..6adb9d6964a0 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_SOC_RENESAS) += renesas-soc.o obj-$(CONFIG_SYSC_R8A7743) += r8a7743-sysc.o obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o obj-$(CONFIG_SYSC_R8A77470) += r8a77470-sysc.o +obj-$(CONFIG_SYSC_R8A774A1) += r8a774a1-sysc.o obj-$(CONFIG_SYSC_R8A7779) += r8a7779-sysc.o obj-$(CONFIG_SYSC_R8A7790) += r8a7790-sysc.o obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o diff --git a/drivers/soc/renesas/r8a774a1-sysc.c b/drivers/soc/renesas/r8a774a1-sysc.c new file mode 100644 index 000000000000..9db51ff6f5ed --- /dev/null +++ b/drivers/soc/renesas/r8a774a1-sysc.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/G2M System Controller + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on Renesas R-Car M3-W System Controller + * Copyright (C) 2016 Glider bvba + */ + +#include +#include + +#include + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a774a1_areas[] __initconst = { + { "always-on", 0, 0, R8A774A1_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca57-scu", 0x1c0, 0, R8A774A1_PD_CA57_SCU, R8A774A1_PD_ALWAYS_ON, + PD_SCU }, + { "ca57-cpu0", 0x80, 0, R8A774A1_PD_CA57_CPU0, R8A774A1_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca57-cpu1", 0x80, 1, R8A774A1_PD_CA57_CPU1, R8A774A1_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca53-scu", 0x140, 0, R8A774A1_PD_CA53_SCU, R8A774A1_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A774A1_PD_CA53_CPU0, R8A774A1_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A774A1_PD_CA53_CPU1, R8A774A1_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu2", 0x200, 2, R8A774A1_PD_CA53_CPU2, R8A774A1_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu3", 0x200, 3, R8A774A1_PD_CA53_CPU3, R8A774A1_PD_CA53_SCU, + PD_CPU_NOCR }, + { "a3vc", 0x380, 0, R8A774A1_PD_A3VC, R8A774A1_PD_ALWAYS_ON }, + { "a2vc0", 0x3c0, 0, R8A774A1_PD_A2VC0, R8A774A1_PD_A3VC }, + { "a2vc1", 0x3c0, 1, R8A774A1_PD_A2VC1, R8A774A1_PD_A3VC }, + { "3dg-a", 0x100, 0, R8A774A1_PD_3DG_A, R8A774A1_PD_ALWAYS_ON }, + { "3dg-b", 0x100, 1, R8A774A1_PD_3DG_B, R8A774A1_PD_3DG_A }, +}; + +const struct rcar_sysc_info r8a774a1_sysc_info __initconst = { + .areas = r8a774a1_areas, + .num_areas = ARRAY_SIZE(r8a774a1_areas), +}; diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 029188e8be6e..fe32f7a3b215 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -275,6 +275,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A77470 { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A774A1 + { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A7779 { .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info }, #endif diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index a22e7cf25e30..33defe624a8c 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -52,6 +52,7 @@ struct rcar_sysc_info { extern const struct rcar_sysc_info r8a7743_sysc_info; extern const struct rcar_sysc_info r8a7745_sysc_info; extern const struct rcar_sysc_info r8a77470_sysc_info; +extern const struct rcar_sysc_info r8a774a1_sysc_info; extern const struct rcar_sysc_info r8a7779_sysc_info; extern const struct rcar_sysc_info r8a7790_sysc_info; extern const struct rcar_sysc_info r8a7791_sysc_info; -- cgit v1.2.3 From 3116d859e7b15d3740afd44c975cdb34a4c1246e Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:55:04 +0100 Subject: soc: renesas: rcar-rst: Add support for RZ/G2M Signed-off-by: Biju Das Reviewed-by: Chris Paterson Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/reset/renesas,rst.txt | 1 + drivers/soc/renesas/Kconfig | 6 +++--- drivers/soc/renesas/rcar-rst.c | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index 67e83b02e10b..e4fe0ab294bf 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -18,6 +18,7 @@ Required properties: - "renesas,r8a7743-rst" (RZ/G1M) - "renesas,r8a7745-rst" (RZ/G1E) - "renesas,r8a77470-rst" (RZ/G1C) + - "renesas,r8a774a1-rst" (RZ/G2M) - "renesas,r8a7778-reset-wdt" (R-Car M1A) - "renesas,r8a7779-reset-wdt" (R-Car H1) - "renesas,r8a7790-rst" (R-Car H2) diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index d769330b640e..00d4c9db1981 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -3,9 +3,9 @@ config SOC_RENESAS default y if ARCH_RENESAS select SOC_BUS select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \ - ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \ - ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77990 || \ - ARCH_R8A77995 + ARCH_R8A774A1 || ARCH_R8A7795 || ARCH_R8A7796 || \ + ARCH_R8A77965 || ARCH_R8A77970 || ARCH_R8A77980 || \ + ARCH_R8A77990 || ARCH_R8A77995 select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7745 if ARCH_R8A7745 select SYSC_R8A77470 if ARCH_R8A77470 diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index d9c1034e70e9..a447873ce182 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -41,10 +41,12 @@ static const struct rst_config rcar_rst_gen3 __initconst = { }; static const struct of_device_id rcar_rst_matches[] __initconst = { - /* RZ/G is handled like R-Car Gen2 */ + /* RZ/G1 is handled like R-Car Gen2 */ { .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 }, + /* RZ/G2 is handled like R-Car Gen3 */ + { .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 }, /* R-Car Gen1 */ { .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 }, { .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 }, -- cgit v1.2.3 From 39c0e5a8746cfbfb87e86761337c807e7faea134 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 10 Sep 2018 12:53:48 +0100 Subject: dt-bindings: arm: Document RZ/G2E SoC DT bindings Add device tree bindings documentation for Renesas RZ/G2E (r8a774c0) SoC. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 4a03a6b3397e..f5e0f82fd503 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -27,6 +27,8 @@ SoCs: compatible = "renesas,r8a77470" - RZ/G2M (R8A774A1) compatible = "renesas,r8a774a1" + - RZ/G2E (RA8774C0) + compatible = "renesas,r8a774c0" - R-Car M1A (R8A77781) compatible = "renesas,r8a7778" - R-Car H1 (R8A77790) -- cgit v1.2.3 From 27582f0ea97fe3e4a38beb98ab36cce4b6f029d5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Jun 2018 09:48:07 -0400 Subject: media: dt-bindings: adv748x: Fix decimal unit addresses With recent dtc and W=1: Warning (graph_port): video-receiver@70/port@10: graph node unit address error, expected "a" Warning (graph_port): video-receiver@70/port@11: graph node unit address error, expected "b" Unit addresses are always hexadecimal (without prefix), while the bases of reg property values depend on their prefixes. Fixes: e69595170b1cad85 ("media: adv748x: Add adv7481, adv7482 bindings") Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Reviewed-by: Kieran Bingham Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/i2c/adv748x.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.txt b/Documentation/devicetree/bindings/media/i2c/adv748x.txt index 21ffb5ed8183..54d1d3bc1869 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv748x.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv748x.txt @@ -73,7 +73,7 @@ Example: }; }; - port@10 { + port@a { reg = <10>; adv7482_txa: endpoint { @@ -83,7 +83,7 @@ Example: }; }; - port@11 { + port@b { reg = <11>; adv7482_txb: endpoint { -- cgit v1.2.3 From e2050f7c6f22d8dd3d81e84c5d39f11b5e68283d Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 8 Aug 2018 12:33:51 -0400 Subject: media: dt-bindings: media: adv7604: Fix slave map documentation The reg-names property in the documentation is missing an '='. Add it. Fixes: 9feb786876c7 ("media: dt-bindings: media: adv7604: Extend bindings to allow specifying slave map addresses") Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/i2c/adv7604.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index dcf57e7c60eb..b3e688b77a38 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt @@ -66,7 +66,7 @@ Example: * other maps will retain their default addresses. */ reg = <0x4c>, <0x66>; - reg-names "main", "edid"; + reg-names = "main", "edid"; reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; -- cgit v1.2.3 From 69a8c2452caae22008ee170d3ef66e97e9df391e Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 2 Sep 2018 09:26:17 +0200 Subject: dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C The Allwinner H6 SoC's DE3 needs the SRAM C section being claimed in the system controller to work, like A64 DE2. As H6 and A64 system controller are quite similar, code is reused now, and the A64 fallback compatible string is added after the H6 compatible string. Signed-off-by: Icenowy Zheng [fixed typo in compatible string] Signed-off-by: Jernej Skrabec Reviewed-by: Chen-Yu Tsai Signed-off-by: Chen-Yu Tsai --- Documentation/devicetree/bindings/sram/sunxi-sram.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt index c51ade86578c..62dd0748f0ef 100644 --- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt +++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt @@ -18,6 +18,7 @@ Required properties: - "allwinner,sun8i-h3-system-control" - "allwinner,sun50i-a64-sram-controller" (deprecated) - "allwinner,sun50i-a64-system-control" + - "allwinner,sun50i-h6-system-control", "allwinner,sun50i-a64-system-control" - reg : sram controller register offset + length SRAM nodes @@ -54,6 +55,9 @@ The valid sections compatible for H3 are: The valid sections compatible for A64 are: - allwinner,sun50i-a64-sram-c +The valid sections compatible for H6 are: + - allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c + Devices using SRAM sections --------------------------- -- cgit v1.2.3 From 0af04934be0046ec056074edfb176f42a21da6f0 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Thu, 9 Aug 2018 15:29:44 -0400 Subject: media: dt-bindings: media: adv748x: Document re-mappable addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ADV748x supports configurable slave addresses for its I2C pages. Document the page names, and provide an example for setting each of the pages explicitly. Signed-off-by: Kieran Bingham Reviewed-by: Rob Herring Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/i2c/adv748x.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.txt b/Documentation/devicetree/bindings/media/i2c/adv748x.txt index 54d1d3bc1869..5dddc95f9cc4 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv748x.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv748x.txt @@ -10,7 +10,11 @@ Required Properties: - "adi,adv7481" for the ADV7481 - "adi,adv7482" for the ADV7482 - - reg: I2C slave address + - reg: I2C slave addresses + The ADV748x has up to twelve 256-byte maps that can be accessed via the + main I2C ports. Each map has it own I2C address and acts as a standard + slave device on the I2C bus. The main address is mandatory, others are + optional and remain at default values if not specified. Optional Properties: @@ -18,6 +22,11 @@ Optional Properties: "intrq3". All interrupts are optional. The "intrq3" interrupt is only available on the adv7481 - interrupts: Specify the interrupt lines for the ADV748x + - reg-names : Names of maps with programmable addresses. + It shall contain all maps needing a non-default address. + Possible map names are: + "main", "dpll", "cp", "hdmi", "edid", "repeater", + "infoframe", "cbus", "cec", "sdp", "txa", "txb" The device node must contain one 'port' child node per device input and output port, in accordance with the video interface bindings defined in @@ -47,7 +56,10 @@ Example: video-receiver@70 { compatible = "adi,adv7482"; - reg = <0x70>; + reg = <0x70 0x71 0x72 0x73 0x74 0x75 + 0x60 0x61 0x62 0x63 0x64 0x65>; + reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater", + "infoframe", "cbus", "cec", "sdp", "txa", "txb"; #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3 From 5516803d48ed946320aba48fdf45bad383252891 Mon Sep 17 00:00:00 2001 From: Maxime Jourdan Date: Thu, 23 Aug 2018 13:49:52 +0200 Subject: dt-bindings: soc: amlogic: add meson-canvas documentation DT bindings doc for amlogic,meson-canvas Reviewed-by: Jerome Brunet Signed-off-by: Maxime Jourdan Reviewed-by: Rob Herring Signed-off-by: Kevin Hilman --- .../bindings/soc/amlogic/amlogic,canvas.txt | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt new file mode 100644 index 000000000000..436d2106e80d --- /dev/null +++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt @@ -0,0 +1,29 @@ +Amlogic Canvas +================================ + +A canvas is a collection of metadata that describes a pixel buffer. +Those metadata include: width, height, phyaddr, wrapping, block mode +and endianness. + +Many IPs within Amlogic SoCs rely on canvas indexes to read/write pixel data +rather than use the phy addresses directly. For instance, this is the case for +the video decoders and the display. + +Amlogic SoCs have 256 canvas. + +Device Tree Bindings: +--------------------- + +Video Lookup Table +-------------------------- + +Required properties: +- compatible: "amlogic,canvas" +- reg: Base physical address and size of the canvas registers. + +Example: + +canvas: video-lut@48 { + compatible = "amlogic,canvas"; + reg = <0x0 0x48 0x0 0x14>; +}; -- cgit v1.2.3 From 56512ffd2923fbe9665e84026074da96273dcb61 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 31 Aug 2018 12:20:38 -0700 Subject: dt-bindings: net: dsa: Document B53 SRAB interrupts and registers Document the Broadcom roboswitch Switch Register Access Block interrupt lines and additional register base addresses for port mux configuration and SGMII status/configuration registers. Signed-off-by: Florian Fainelli Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/net/dsa/b53.txt | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt index 1811e1972a7a..5201bc15fdd6 100644 --- a/Documentation/devicetree/bindings/net/dsa/b53.txt +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt @@ -46,6 +46,42 @@ Required properties: "brcm,bcm6328-switch" "brcm,bcm6368-switch" and the mandatory "brcm,bcm63xx-switch" +Required properties for BCM585xx/586xx/88312 SoCs: + + - reg: a total of 3 register base addresses, the first one must be the + Switch Register Access block base, the second is the port 5/4 mux + configuration register and the third one is the SGMII configuration + and status register base address. + + - interrupts: a total of 13 interrupts must be specified, in the following + order: port 0-5, 7-8 link status change, then the integrated PHY interrupt, + then the timestamping interrupt and the sleep timer interrupts for ports + 5,7,8. + +Optional properties for BCM585xx/586xx/88312 SoCs: + + - reg-names: a total of 3 names matching the 3 base register address, must + be in the following order: + "srab" + "mux_config" + "sgmii_config" + + - interrupt-names: a total of 13 names matching the 13 interrupts specified + must be in the following order: + "link_state_p0" + "link_state_p1" + "link_state_p2" + "link_state_p3" + "link_state_p4" + "link_state_p5" + "link_state_p7" + "link_state_p8" + "phy" + "ts" + "imp_sleep_timer_p5" + "imp_sleep_timer_p7" + "imp_sleep_timer_p8" + See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional required and optional properties. -- cgit v1.2.3 From b54ef3814f4a30c4c023ea099c8e4c962cfe3614 Mon Sep 17 00:00:00 2001 From: Venkata Narendra Kumar Gutta Date: Wed, 12 Sep 2018 11:06:35 -0700 Subject: dt-bindings: msm: Update documentation of qcom,llcc Add reg-names and interrupts for LLCC documentation and the usage examples. llcc broadcast base is added in addition to llcc base, which is used for llcc broadcast writes. Signed-off-by: Venkata Narendra Kumar Gutta Reviewed-by: Rob Herring Signed-off-by: Andy Gross --- .../devicetree/bindings/arm/msm/qcom,llcc.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt index 5e85749262ae..eaee06b2d8f2 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt @@ -16,11 +16,26 @@ Properties: - reg: Usage: required Value Type: - Definition: Start address and the the size of the register region. + Definition: The first element specifies the llcc base start address and + the size of the register region. The second element specifies + the llcc broadcast base address and size of the register region. + +- reg-names: + Usage: required + Value Type: + Definition: Register region names. Must be "llcc_base", "llcc_broadcast_base". + +- interrupts: + Usage: required + Definition: The interrupt is associated with the llcc edac device. + It's used for llcc cache single and double bit error detection + and reporting. Example: cache-controller@1100000 { compatible = "qcom,sdm845-llcc"; - reg = <0x1100000 0x250000>; + reg = <0x1100000 0x200000>, <0x1300000 0x50000> ; + reg-names = "llcc_base", "llcc_broadcast_base"; + interrupts = ; }; -- cgit v1.2.3 From 8a07855e66e6b8ddf452d81c6aac0b1ff3665e86 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 29 Aug 2018 16:15:03 -0700 Subject: dt-bindings: firmware: scm: Refactor compatibles and clocks When the binding was written all "future" platforms required three clocks, so the default compatible (qcom,scm) was defined to require this. But as history shows all "future" platforms actually lack required clocks. Given how the binding is written these compatibles have to be added as an exception to the default. Refactor the description of compatible to define that a platform compatible should be given, followed by the fallback of qcom,scm. Also refactor the description of the clocks in a way that this does not need to be updated as new platform specific compatibles are added. Signed-off-by: Bjorn Andersson Reviewed-by: Stephen Boyd Signed-off-by: Andy Gross --- .../devicetree/bindings/firmware/qcom,scm.txt | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt index fcf6979c0b6d..1c8e24530f7c 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt @@ -7,16 +7,21 @@ assorted actions. Required properties: - compatible: must contain one of the following: - * "qcom,scm-apq8064" for APQ8064 platforms - * "qcom,scm-msm8660" for MSM8660 platforms - * "qcom,scm-msm8690" for MSM8690 platforms - * "qcom,scm-msm8996" for MSM8996 platforms - * "qcom,scm-ipq4019" for IPQ4019 platforms - * "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc) -- clocks: One to three clocks may be required based on compatible. - * No clock required for "qcom,scm-msm8996", "qcom,scm-ipq4019" - * Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960" - * Core, iface, and bus clocks required for "qcom,scm" + * "qcom,scm-apq8064" + * "qcom,scm-apq8084" + * "qcom,scm-msm8660" + * "qcom,scm-msm8916" + * "qcom,scm-msm8960" + * "qcom,scm-msm8974" + * "qcom,scm-msm8996" + * "qcom,scm-ipq4019" + and: + * "qcom,scm" +- clocks: Specifies clocks needed by the SCM interface, if any: + * core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660" and + "qcom,scm-msm8960" + * core, iface and bus clocks required for "qcom,scm-apq8084", + "qcom,scm-msm8916" and "qcom,scm-msm8974" - clock-names: Must contain "core" for the core clock, "iface" for the interface clock and "bus" for the bus clock per the requirements of the compatible. - qcom,dload-mode: phandle to the TCSR hardware block and offset of the @@ -26,8 +31,10 @@ Example for MSM8916: firmware { scm { - compatible = "qcom,scm"; - clocks = <&gcc GCC_CRYPTO_CLK> , <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>; + compatible = "qcom,msm8916", "qcom,scm"; + clocks = <&gcc GCC_CRYPTO_CLK> , + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc GCC_CRYPTO_AHB_CLK>; clock-names = "core", "bus", "iface"; }; }; -- cgit v1.2.3 From bb85ce5122487b2b1de1b48b557c5fdf9828dc6e Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 29 Aug 2018 16:15:05 -0700 Subject: dt-bindings: firmware: scm: Add MSM8998 and SDM845 Now that the compatible/clock handling is reworked add compatibles for MSM8998 and SDM845 to the SCM binding. Signed-off-by: Bjorn Andersson Reviewed-by: Stephen Boyd Signed-off-by: Andy Gross --- Documentation/devicetree/bindings/firmware/qcom,scm.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt index 1c8e24530f7c..41f133a4e2fa 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt @@ -14,7 +14,9 @@ Required properties: * "qcom,scm-msm8960" * "qcom,scm-msm8974" * "qcom,scm-msm8996" + * "qcom,scm-msm8998" * "qcom,scm-ipq4019" + * "qcom,scm-sdm845" and: * "qcom,scm" - clocks: Specifies clocks needed by the SCM interface, if any: -- cgit v1.2.3 From 4ffe5aa53791ac5ab2c29e99f23c07cb85922dd5 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 4 Jun 2018 22:04:59 +0300 Subject: dt-bindings: display: renesas: du: document R8A77980 bindings Document the R-Car V3H (R8A77980) SoC in the R-Car DU bindings; the DU hardware has the same topology as in the R-Car V3M (R8A77970). Signed-off-by: Sergei Shtylyov Reviewed-by: Simon Horman Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index ec9d34be2ff7..caae2348a292 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -15,6 +15,7 @@ Required Properties: - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU + - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU - reg: the memory-mapped I/O registers base address and length @@ -61,6 +62,7 @@ corresponding to each DU output. R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 - R8A77965 (R-Car M3-N) DPAD 0 HDMI 0 LVDS 0 - R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - - + R8A77980 (R-Car V3H) DPAD 0 LVDS 0 - - R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 - -- cgit v1.2.3 From ab77eb4c4de77a3095abbc213b8f191c58ebdca1 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 5 Jun 2018 23:28:58 +0300 Subject: dt-bindings: display: renesas: lvds: document R8A77980 bindings Document the R-Car V3H (R8A77980) SoC in the R-Car LVDS bindings. Signed-off-by: Sergei Shtylyov Acked-by: Rob Herring Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt index 4f0ab3ed3b6f..5a4e379bb414 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt @@ -14,6 +14,7 @@ Required properties: - "renesas,r8a7795-lvds" for R8A7795 (R-Car H3) compatible LVDS encoders - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders + - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders - reg: Base address and length for the memory-mapped registers -- cgit v1.2.3 From 39dc9a103bc587d32a0416c5a47483a6e9ef88e2 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 10 Sep 2018 15:41:28 +0100 Subject: dt-bindings: power: rcar-sysc: Document r8a774c0 sysc Document bindings for the RZ/G2E (a.k.a. R8A774C0) system controller. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index 4e3ec6ac6345..4cb97d48bf66 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -11,6 +11,7 @@ Required properties: - "renesas,r8a7745-sysc" (RZ/G1E) - "renesas,r8a77470-sysc" (RZ/G1C) - "renesas,r8a774a1-sysc" (RZ/G2M) + - "renesas,r8a774c0-sysc" (RZ/G2E) - "renesas,r8a7779-sysc" (R-Car H1) - "renesas,r8a7790-sysc" (R-Car H2) - "renesas,r8a7791-sysc" (R-Car M2-W) -- cgit v1.2.3 From fe46b8229f287e912b8c8d28bf8dde4cd704c17e Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 10 Sep 2018 16:09:40 +0100 Subject: dt-bindings: reset: rcar-rst: Document r8a774c0 rst Document bindings for the RZ/G2E (a.k.a. R8A774C0) reset module. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Acked-by: Philipp Zabel Reviewed-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/reset/renesas,rst.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index e4fe0ab294bf..25e6db546215 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -19,6 +19,7 @@ Required properties: - "renesas,r8a7745-rst" (RZ/G1E) - "renesas,r8a77470-rst" (RZ/G1C) - "renesas,r8a774a1-rst" (RZ/G2M) + - "renesas,r8a774c0-rst" (RZ/G2E) - "renesas,r8a7778-reset-wdt" (R-Car M1A) - "renesas,r8a7779-reset-wdt" (R-Car H1) - "renesas,r8a7790-rst" (R-Car H2) -- cgit v1.2.3 From 08ea4a3004da9dfbf361f6791934af58a35ec350 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:42 +0100 Subject: dt-bindings: power: rcar-sysc: Document r8a7744 SYSC binding Add binding documentation for the RZ/G1N (R8A7744) SYSC block. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index 4cb97d48bf66..eae2a880155a 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -8,6 +8,7 @@ and various coprocessors. Required properties: - compatible: Must contain exactly one of the following: - "renesas,r8a7743-sysc" (RZ/G1M) + - "renesas,r8a7744-sysc" (RZ/G1N) - "renesas,r8a7745-sysc" (RZ/G1E) - "renesas,r8a77470-sysc" (RZ/G1C) - "renesas,r8a774a1-sysc" (RZ/G2M) -- cgit v1.2.3 From f1ae799039bfd3fcc046041714eb0ac227505d0f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:45 +0100 Subject: dt-bindings: reset: rcar-rst: Document r8a7744 reset module Document bindings for the RZ/G1N (R8A7744) reset module. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/reset/renesas,rst.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index 25e6db546215..b03c48a1150e 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -16,6 +16,7 @@ Required properties: - "renesas,-rst" for R-Car Gen2 and Gen3, and RZ/G Examples with soctypes are: - "renesas,r8a7743-rst" (RZ/G1M) + - "renesas,r8a7744-rst" (RZ/G1N) - "renesas,r8a7745-rst" (RZ/G1E) - "renesas,r8a77470-rst" (RZ/G1C) - "renesas,r8a774a1-rst" (RZ/G2M) -- cgit v1.2.3 From 1a07dd8a6b8510dd8ffd43cceff51c7d4cba0693 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 19 Jul 2018 07:54:28 -0400 Subject: media: dt-bindings: dw9714, dw9807-vcm: Add files to MAINTAINERS, rename files Add the DT binding documentation for dw9714 and dw9807-vcm to the MAINTAINERS file. The dw9807-vcm binding documentation file is renamed to match the dw9807's VCM bit's compatible string. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt | 9 +++++++++ Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt | 9 --------- MAINTAINERS | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt delete mode 100644 Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt new file mode 100644 index 000000000000..c4701f1eaaf6 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt @@ -0,0 +1,9 @@ +Dongwoon Anatech DW9807 voice coil lens driver + +DW9807 is a 10-bit DAC with current sink capability. It is intended for +controlling voice coil lenses. + +Mandatory properties: + +- compatible: "dongwoon,dw9807-vcm" +- reg: I2C slave address diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt deleted file mode 100644 index c4701f1eaaf6..000000000000 --- a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt +++ /dev/null @@ -1,9 +0,0 @@ -Dongwoon Anatech DW9807 voice coil lens driver - -DW9807 is a 10-bit DAC with current sink capability. It is intended for -controlling voice coil lenses. - -Mandatory properties: - -- compatible: "dongwoon,dw9807-vcm" -- reg: I2C slave address diff --git a/MAINTAINERS b/MAINTAINERS index 0650a8dadae0..9989925f658d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4504,6 +4504,7 @@ L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/i2c/dw9714.c +F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt DONGWOON DW9807 LENS VOICE COIL DRIVER M: Sakari Ailus @@ -4511,6 +4512,7 @@ L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/i2c/dw9807.c +F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt DOUBLETALK DRIVER M: "James R. Van Zandt" -- cgit v1.2.3 From 4619ef4747c23818063c4e8480d63966a40297c6 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 17 Sep 2018 09:44:09 +0100 Subject: dt-bindings: apmu: Document r8a77470 support Document APMU and SMP enable method for RZ/G1C (also known as r8a77470) SoC. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/power/renesas,apmu.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt index f747f95eee58..e6f47c9b3d0e 100644 --- a/Documentation/devicetree/bindings/power/renesas,apmu.txt +++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt @@ -9,6 +9,7 @@ Required properties: Examples with soctypes are: - "renesas,r8a7743-apmu" (RZ/G1M) - "renesas,r8a7745-apmu" (RZ/G1E) + - "renesas,r8a77470-apmu" (RZ/G1C) - "renesas,r8a7790-apmu" (R-Car H2) - "renesas,r8a7791-apmu" (R-Car M2-W) - "renesas,r8a7792-apmu" (R-Car V2H) -- cgit v1.2.3 From 5c5b3b0ebe6d78cad645cc010d7e8fb81ccd099b Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 16 Sep 2018 12:34:07 +0800 Subject: dt-bindings: sun4i-drm: add compatible for R40 HDMI PHY The Allwinner R40 HDMI PHY is currently the only one that seems to be able to select between two PLL inputs. Add a compatible string for it, and the pll-1 clock input definition. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180916043409.62374-3-icenowy@aosc.io --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index 0bbb5d47f228..22d6dda587c5 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -107,6 +107,7 @@ Required properties: - compatible: value must be one of: * allwinner,sun8i-a83t-hdmi-phy * allwinner,sun8i-h3-hdmi-phy + * allwinner,sun8i-r40-hdmi-phy * allwinner,sun50i-a64-hdmi-phy - reg: base address and size of memory-mapped region - clocks: phandles to the clocks feeding the HDMI PHY @@ -116,9 +117,9 @@ Required properties: - resets: phandle to the reset controller driving the PHY - reset-names: must be "phy" -H3 and A64 HDMI PHY require additional clocks: +H3, A64 and R40 HDMI PHY require additional clocks: - pll-0: parent of phy clock - - pll-1: second possible phy clock parent (A64 only) + - pll-1: second possible phy clock parent (A64/R40 only) TV Encoder ---------- -- cgit v1.2.3 From 5851fa4d088747af4a141110541594a2a4479b12 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 7 Sep 2018 23:02:53 +0300 Subject: dt-bindings: timer: renesas: tmu: document R8A779{7|8}0 bindings Document the R-Car V3{M|H} (R8A779{7|8}0) SoC in the Renesas TMU bindings; the TMU hardware in those is the Renesas standard 3-channel timer unit. Signed-off-by: Sergei Shtylyov Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/timer/renesas,tmu.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.txt b/Documentation/devicetree/bindings/timer/renesas,tmu.txt index cd5f20bf2582..4ddff85837da 100644 --- a/Documentation/devicetree/bindings/timer/renesas,tmu.txt +++ b/Documentation/devicetree/bindings/timer/renesas,tmu.txt @@ -12,6 +12,8 @@ Required Properties: - "renesas,tmu-r8a7740" for the r8a7740 TMU - "renesas,tmu-r8a7778" for the r8a7778 TMU - "renesas,tmu-r8a7779" for the r8a7779 TMU + - "renesas,tmu-r8a77970" for the r8a77970 TMU + - "renesas,tmu-r8a77980" for the r8a77980 TMU - "renesas,tmu" for any TMU. This is a fallback for the above renesas,tmu-* entries -- cgit v1.2.3 From bbd71915ee9c56cc585c76b4b3aee791152ffbff Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:47 +0100 Subject: dt-bindings: clock: renesas: cpg-mssr: Document r8a7744 binding Add binding documentation for the RZ/G1N (R8A7744) Clock Pulse Generator driver. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 5e46e6be789b..629dd4f8ddac 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -15,6 +15,7 @@ Required Properties: - compatible: Must be one of: - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2) - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) + - "renesas,r8a7744-cpg-mssr" for the r8a7744 SoC (RZ/G1N) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) @@ -37,12 +38,12 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r7s9210, r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, - r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, - r8a77970, r8a77980, r8a77990, r8a77995) + - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, + r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, + r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, - r8a7794) + - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, + r8a7793, r8a7794) - #clock-cells: Must be 2 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" -- cgit v1.2.3 From 7c0043c0a48c18fccd43e5cd9f45751316564647 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Wed, 12 Sep 2018 11:41:54 +0100 Subject: dt-bindings: clock: renesas: cpg-mssr: Document r8a774c0 This patch documents RZ/G2E (a.k.a. R8A774C0) bindings for the Clock Pulse Generator driver. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 629dd4f8ddac..916a601b76a7 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -19,6 +19,7 @@ Required Properties: - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) + - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) @@ -39,8 +40,9 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, - r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, - r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) + r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, + r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, + r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) -- cgit v1.2.3 From d84207999d216f743c7c011874e0a99282c64d11 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 10 Aug 2018 23:23:36 +0530 Subject: dt-bindings: arm: hisilicon: Add binding for Hi3670 SoC Add devicetree binding for Hi3670 SoC. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Wei Xu --- Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 199cd36fe1ba..14f54f569c63 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -8,6 +8,10 @@ HiKey960 Board Required root node properties: - compatible = "hisilicon,hi3660-hikey960", "hisilicon,hi3660"; +Hi3670 SoC +Required root node properties: + - compatible = "hisilicon,hi3670"; + Hi3798cv200 SoC Required root node properties: - compatible = "hisilicon,hi3798cv200"; -- cgit v1.2.3 From a446451d04b7e5ef0d9b328bdd52ffb784439871 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 10 Aug 2018 23:23:38 +0530 Subject: dt-bindings: arm: hisilicon: Add binding for HiKey970 board Add devicetree binding for HiKey970 board. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Wei Xu --- Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 14f54f569c63..a97f643e7d1c 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -12,6 +12,10 @@ Hi3670 SoC Required root node properties: - compatible = "hisilicon,hi3670"; +HiKey970 Board +Required root node properties: + - compatible = "hisilicon,hi3670-hikey970", "hisilicon,hi3670"; + Hi3798cv200 SoC Required root node properties: - compatible = "hisilicon,hi3798cv200"; -- cgit v1.2.3 From 91e28030fd5deb56b5f14b870bc2e2c856435cca Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Wed, 25 Jul 2018 17:46:44 +0200 Subject: dt-bindings: exynos_dsim: update of graph bindings Of-graph bindings should describe ports present in the device, not the devices it can be connected to. The patch replaces verbose description with shorter but more precise one. While at it clock related properties are moved to the main node as it is their actual location. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- .../bindings/display/exynos/exynos_dsim.txt | 25 ++++++---------------- 1 file changed, 6 insertions(+), 19 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt index 2fff8b406f4c..be377786e8cd 100644 --- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt +++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt @@ -21,6 +21,9 @@ Required properties: - samsung,pll-clock-frequency: specifies frequency of the oscillator clock - #address-cells, #size-cells: should be set respectively to <1> and <0> according to DSI host bindings (see MIPI DSI bindings [1]) + - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst + mode + - samsung,esc-clock-frequency: specifies DSI frequency in escape mode Optional properties: - power-domains: a phandle to DSIM power domain node @@ -29,25 +32,9 @@ Child nodes: Should contain DSI peripheral nodes (see MIPI DSI bindings [1]). Video interfaces: - Device node can contain video interface port nodes according to [2]. - The following are properties specific to those nodes: - - port node inbound: - - reg: (required) must be 0. - port node outbound: - - reg: (required) must be 1. - - endpoint node connected from mic node (reg = 0): - - remote-endpoint: specifies the endpoint in mic node. This node is required - for Exynos5433 mipi dsi. So mic can access to panel node - throughout this dsi node. - endpoint node connected to panel node (reg = 1): - - remote-endpoint: specifies the endpoint in panel node. This node is - required in all kinds of exynos mipi dsi to represent - the connection between mipi dsi and panel. - - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst - mode - - samsung,esc-clock-frequency: specifies DSI frequency in escape mode + Device node can contain following video interface port nodes according to [2]: + 0: RGB input, + 1: DSI output [1]: Documentation/devicetree/bindings/display/mipi-dsi-bus.txt [2]: Documentation/devicetree/bindings/media/video-interfaces.txt -- cgit v1.2.3 From a779df303b0513f6ca6ae6ff06b0b93508193a5c Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 12 Sep 2018 15:44:19 +0300 Subject: Documentation: filesystems: remove reminiscences of POHMELFS The POHMELFS filesystem was removed in 2012 by commit 67435319866f8 ("staging: pohmelfs: remove drivers/staging/pohmelfs") promising that a newer version will be included to the kernel, but unfortunately it didn't happen. Since likely any delopment of the filesystem is halted, the change removes the abandoned POHMELFS documentation from the kernel tree. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/00-INDEX | 2 - .../filesystems/pohmelfs/design_notes.txt | 72 ------- Documentation/filesystems/pohmelfs/info.txt | 99 --------- .../filesystems/pohmelfs/network_protocol.txt | 227 --------------------- 4 files changed, 400 deletions(-) delete mode 100644 Documentation/filesystems/pohmelfs/design_notes.txt delete mode 100644 Documentation/filesystems/pohmelfs/info.txt delete mode 100644 Documentation/filesystems/pohmelfs/network_protocol.txt (limited to 'Documentation') diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 0937bade1099..a53f20114353 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -101,8 +101,6 @@ omfs.txt - info on the Optimized MPEG FileSystem. path-lookup.txt - info on path walking and name lookup locking. -pohmelfs/ - - directory containing pohmelfs filesystem documentation. porting - various information on filesystem porting. proc.txt diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt deleted file mode 100644 index 106d17fbb05f..000000000000 --- a/Documentation/filesystems/pohmelfs/design_notes.txt +++ /dev/null @@ -1,72 +0,0 @@ -POHMELFS: Parallel Optimized Host Message Exchange Layered File System. - - Evgeniy Polyakov - -Homepage: http://www.ioremap.net/projects/pohmelfs - -POHMELFS first began as a network filesystem with coherent local data and -metadata caches but is now evolving into a parallel distributed filesystem. - -Main features of this FS include: - * Locally coherent cache for data and metadata with (potentially) byte-range locks. - Since all Linux filesystems lock the whole inode during writing, algorithm - is very simple and does not use byte-ranges, although they are sent in - locking messages. - * Completely async processing of all events except creation of hard and symbolic - links, and rename events. - Object creation and data reading and writing are processed asynchronously. - * Flexible object architecture optimized for network processing. - Ability to create long paths to objects and remove arbitrarily huge - directories with a single network command. - (like removing the whole kernel tree via a single network command). - * Very high performance. - * Fast and scalable multithreaded userspace server. Being in userspace it works - with any underlying filesystem and still is much faster than async in-kernel NFS one. - * Client is able to switch between different servers (if one goes down, client - automatically reconnects to second and so on). - * Transactions support. Full failover for all operations. - Resending transactions to different servers on timeout or error. - * Read request (data read, directory listing, lookup requests) balancing between multiple servers. - * Write requests are replicated to multiple servers and completed only when all of them are acked. - * Ability to add and/or remove servers from the working set at run-time. - * Strong authentication and possible data encryption in network channel. - * Extended attributes support. - -POHMELFS is based on transactions, which are potentially long-standing objects that live -in the client's memory. Each transaction contains all the information needed to process a given -command (or set of commands, which is frequently used during data writing: single transactions -can contain creation and data writing commands). Transactions are committed by all the servers -to which they are sent and, in case of failures, are eventually resent or dropped with an error. -For example, reading will return an error if no servers are available. - -POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is -possible to detach replies from requests and, if the command requires data to be received, the -caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different -servers and async threads will pick up replies in parallel, find appropriate transactions in the -system and put the data where it belongs (like the page or inode cache). - -The main feature of POHMELFS is writeback data and the metadata cache. -Only a few non-performance critical operations use the write-through cache and -are synchronous: hard and symbolic link creation, and object rename. Creation, -removal of objects and data writing are asynchronous and are sent to -the server during system writeback. Only one writer at a time is allowed for any -given inode, which is guarded by an appropriate locking protocol. -Because of this feature, POHMELFS is extremely fast at metadata intensive -workloads and can fully utilize the bandwidth to the servers when doing bulk -data transfers. - -POHMELFS clients operate with a working set of servers and are capable of balancing read-only -operations (like lookups or directory listings) between them according to IO priorities. -Administrators can add or remove servers from the set at run-time via special commands (described -in Documentation/filesystems/pohmelfs/info.txt file). Writes are replicated to all servers, which -are connected with write permission turned on. IO priority and permissions can be changed in -run-time. - -POHMELFS is capable of full data channel encryption and/or strong crypto hashing. -One can select any kernel supported cipher, encryption mode, hash type and operation mode -(hmac or digest). It is also possible to use both or neither (default). Crypto configuration -is checked during mount time and, if the server does not support it, appropriate capabilities -will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified). -Crypto performance heavily depends on the number of crypto threads, which asynchronously perform -crypto operations and send the resulting data to server or submit it up the stack. This number -can be controlled via a mount option. diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt deleted file mode 100644 index db2e41393626..000000000000 --- a/Documentation/filesystems/pohmelfs/info.txt +++ /dev/null @@ -1,99 +0,0 @@ -POHMELFS usage information. - -Mount options. -All but index, number of crypto threads and maximum IO size can changed via remount. - -idx=%u - Each mountpoint is associated with a special index via this option. - Administrator can add or remove servers from the given index, so all mounts, - which were attached to it, are updated. - Default it is 0. - -trans_scan_timeout=%u - This timeout, expressed in milliseconds, specifies time to scan transaction - trees looking for stale requests, which have to be resent, or if number of - retries exceed specified limit, dropped with error. - Default is 5 seconds. - -drop_scan_timeout=%u - Internal timeout, expressed in milliseconds, which specifies how frequently - inodes marked to be dropped are freed. It also specifies how frequently - the system checks that servers have to be added or removed from current working set. - Default is 1 second. - -wait_on_page_timeout=%u - Number of milliseconds to wait for reply from remote server for data reading command. - If this timeout is exceeded, reading returns an error. - Default is 5 seconds. - -trans_retries=%u - This is the number of times that a transaction will be resent to a server that did - not answer for the last @trans_scan_timeout milliseconds. - When the number of resends exceeds this limit, the transaction is completed with error. - Default is 5 resends. - -crypto_thread_num=%u - Number of crypto processing threads. Threads are used both for RX and TX traffic. - Default is 2, or no threads if crypto operations are not supported. - -trans_max_pages=%u - Maximum number of pages in a single transaction. This parameter also controls - the number of pages, allocated for crypto processing (each crypto thread has - pool of pages, the number of which is equal to 'trans_max_pages'. - Default is 100 pages. - -crypto_fail_unsupported - If specified, mount will fail if the server does not support requested crypto operations. - By default mount will disable non-matching crypto operations. - -mcache_timeout=%u - Maximum number of milliseconds to wait for the mcache objects to be processed. - Mcache includes locks (given lock should be granted by server), attributes (they should be - fully received in the given timeframe). - Default is 5 seconds. - -Usage examples. - -Add server server1.net:1025 into the working set with index $idx -with appropriate hash algorithm and key file and cipher algorithm, mode and key file: -$cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key - -Mount filesystem with given index $idx to /mnt mountpoint. -Client will connect to all servers specified in the working set via previous command: -mount -t pohmel -o idx=$idx q /mnt - -Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw): -$cfg A modify -a server1.net -p 1025 -i $idx -I 1 - -Change IO priority to 123 (node with the highest priority gets read requests). -$cfg A modify -a server1.net -p 1025 -i $idx -P 123 - -One can check currect status of all connections in the mountstats file: -# cat /proc/$PID/mountstats -... -device none mounted on /mnt with fstype pohmel -idx addr(:port) socket_type protocol active priority permissions -0 server1.net:1026 1 6 1 250 1 -0 server2.net:1025 1 6 1 123 3 - -Server installation. - -Creating a server, which listens at port 1025 and 0.0.0.0 address. -Working root directory (note, that server chroots there, so you have to have appropriate permissions) -is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there -are appropriate key files. -Number of working threads is set to 10. - -# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key - - -A 6 - listen on ipv6 address. Default: Disabled. - -r root - path to root directory. Default: /tmp. - -a addr - listen address. Default: 0.0.0.0. - -p port - listen port. Default: 1025. - -w workers - number of workers per connected client. Default: 1. - -K file - hash key size. Default: none. - -k file - cipher key size. Default: none. - -h - this help. - -Number of worker threads specifies how many workers will be created for each client. -Bulk single-client transafers usually are better handled with smaller number (like 1-3). diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt deleted file mode 100644 index c680b4b5353d..000000000000 --- a/Documentation/filesystems/pohmelfs/network_protocol.txt +++ /dev/null @@ -1,227 +0,0 @@ -POHMELFS network protocol. - -Basic structure used in network communication is following command: - -struct netfs_cmd -{ - __u16 cmd; /* Command number */ - __u16 csize; /* Attached crypto information size */ - __u16 cpad; /* Attached padding size */ - __u16 ext; /* External flags */ - __u32 size; /* Size of the attached data */ - __u32 trans; /* Transaction id */ - __u64 id; /* Object ID to operate on. Used for feedback.*/ - __u64 start; /* Start of the object. */ - __u64 iv; /* IV sequence */ - __u8 data[0]; -}; - -Commands can be embedded into transaction command (which in turn has own command), -so one can extend protocol as needed without breaking backward compatibility as long -as old commands are supported. All string lengths include tail 0 byte. - -All commands are transferred over the network in big-endian. CPU endianness is used at the end peers. - -@cmd - command number, which specifies command to be processed. Following - commands are used currently: - - NETFS_READDIR = 1, /* Read directory for given inode number */ - NETFS_READ_PAGE, /* Read data page from the server */ - NETFS_WRITE_PAGE, /* Write data page to the server */ - NETFS_CREATE, /* Create directory entry */ - NETFS_REMOVE, /* Remove directory entry */ - NETFS_LOOKUP, /* Lookup single object */ - NETFS_LINK, /* Create a link */ - NETFS_TRANS, /* Transaction */ - NETFS_OPEN, /* Open intent */ - NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */ - NETFS_PAGE_CACHE, /* Page cache invalidation message */ - NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */ - NETFS_RENAME, /* Rename object */ - NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */ - NETFS_LOCK, /* Distributed lock message */ - NETFS_XATTR_SET, /* Set extended attribute */ - NETFS_XATTR_GET, /* Get extended attribute */ - -@ext - external flags. Used by different commands to specify some extra arguments - like partial size of the embedded objects or creation flags. - -@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached, - but size of the requested data is incorporated here. It does not include size of the command - header (struct netfs_cmd) itself. - -@id - id of the object this command operates on. Each command can use it for own purpose. - -@start - start of the object this command operates on. Each command can use it for own purpose. - -@csize, @cpad - size and padding size of the (attached if needed) crypto information. - -Command specifications. - -@NETFS_READDIR -This command is used to sync content of the remote dir to the client. - -@ext - length of the path to object. -@size - the same. -@id - local inode number of the directory to read. -@start - zero. - - -@NETFS_READ_PAGE -This command is used to read data from remote server. -Data size does not exceed local page cache size. - -@id - inode number. -@start - first byte offset. -@size - number of bytes to read plus length of the path to object. -@ext - object path length. - - -@NETFS_CREATE -Used to create object. -It does not require that all directories on top of the object were -already created, it will create them automatically. Each object has -associated @netfs_path_entry data structure, which contains creation -mode (permissions and type) and length of the name as long as name itself. - -@start - 0 -@size - size of the all data structures needed to create a path -@id - local inode number -@ext - 0 - - -@NETFS_REMOVE -Used to remove object. - -@ext - length of the path to object. -@size - the same. -@id - local inode number. -@start - zero. - - -@NETFS_LOOKUP -Lookup information about object on server. - -@ext - length of the path to object. -@size - the same. -@id - local inode number of the directory to look object in. -@start - local inode number of the object to look at. - - -@NETFS_LINK -Create hard of symlink. -Command is sent as "object_path|target_path". - -@size - size of the above string. -@id - parent local inode number. -@start - 1 for symlink, 0 for hardlink. -@ext - size of the "object_path" above. - - -@NETFS_TRANS -Transaction header. - -@size - incorporates all embedded command sizes including theirs header sizes. -@start - transaction generation number - unique id used to find transaction. -@ext - transaction flags. Unused at the moment. -@id - 0. - - -@NETFS_OPEN -Open intent for given transaction. - -@id - local inode number. -@start - 0. -@size - path length to the object. -@ext - open flags (O_RDWR and so on). - - -@NETFS_INODE_INFO -Metadata update command. -It is sent to servers when attributes of the object are changed and received -when data or metadata were updated. It operates with the following structure: - -struct netfs_inode_info -{ - unsigned int mode; - unsigned int nlink; - unsigned int uid; - unsigned int gid; - unsigned int blocksize; - unsigned int padding; - __u64 ino; - __u64 blocks; - __u64 rdev; - __u64 size; - __u64 version; -}; - -It effectively mirrors stat(2) returned data. - - -@ext - path length to the object. -@size - the same plus size of the netfs_inode_info structure. -@id - local inode number. -@start - 0. - - -@NETFS_PAGE_CACHE -Command is only received by clients. It contains information about -page to be marked as not up-to-date. - -@id - client's inode number. -@start - last byte of the page to be invalidated. If it is not equal to - current inode size, it will be vmtruncated(). -@size - 0 -@ext - 0 - - -@NETFS_READ_PAGES -Used to read multiple contiguous pages in one go. - -@start - first byte of the contiguous region to read. -@size - contains of two fields: lower 8 bits are used to represent page cache shift - used by client, another 3 bytes are used to get number of pages. -@id - local inode number. -@ext - path length to the object. - - -@NETFS_RENAME -Used to rename object. -Attached data is formed into following string: "old_path|new_path". - -@id - local inode number. -@start - parent inode number. -@size - length of the above string. -@ext - length of the old path part. - - -@NETFS_CAPABILITIES -Used to exchange crypto capabilities with server. -If crypto capabilities are not supported by server, then client will disable it -or fail (if 'crypto_fail_unsupported' mount options was specified). - -@id - superblock index. Used to specify crypto information for group of servers. -@size - size of the attached capabilities structure. -@start - 0. -@size - 0. -@scsize - 0. - -@NETFS_LOCK -Used to send lock request/release messages. Although it sends byte range request -and is capable of flushing pages based on that, it is not used, since all Linux -filesystems lock the whole inode. - -@id - lock generation number. -@start - start of the locked range. -@size - size of the locked range. -@ext - lock type: read/write. Not used actually. 15'th bit is used to determine, - if it is lock request (1) or release (0). - -@NETFS_XATTR_SET -@NETFS_XATTR_GET -Used to set/get extended attributes for given inode. -@id - attribute generation number or xattr setting type -@start - size of the attribute (request or attached) -@size - name length, path len and data size for given attribute -@ext - path length for given object -- cgit v1.2.3 From c1a02c216044784f9871a5066fd22de7d0414d0d Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 13 Sep 2018 16:23:38 +1000 Subject: serial: docs: Fix filename for serial reference implementation Currently documentation mentions a file but the filename has a typo in it, underscore instead of hyphen. This makes grep'ing for the file hard. Use correct filename for file amba-pl011.c Signed-off-by: Tobin C. Harding Signed-off-by: Greg Kroah-Hartman --- Documentation/serial/driver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/serial/driver b/Documentation/serial/driver index da193e092fc3..86e47c19a924 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver @@ -7,7 +7,7 @@ This document is meant as a brief overview of some aspects of the new serial driver. It is not complete, any questions you have should be directed to -The reference implementation is contained within amba_pl011.c. +The reference implementation is contained within amba-pl011.c. -- cgit v1.2.3 From 66d77325609a0ae5b0b2acbda362f7191efd2064 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 26 Jun 2018 09:50:10 +0200 Subject: dt-bindings: arm: scu: Correct example SCU unit addresses The unit addresses of the Cortex-A9 SCU device nodes contain too many zeroes. Remove them. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/arm/scu.txt | 2 +- Documentation/devicetree/bindings/arm/ux500/boards.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/scu.txt b/Documentation/devicetree/bindings/arm/scu.txt index 08a587875996..74d0a780ce51 100644 --- a/Documentation/devicetree/bindings/arm/scu.txt +++ b/Documentation/devicetree/bindings/arm/scu.txt @@ -22,7 +22,7 @@ References: Example: -scu@a04100000 { +scu@a0410000 { compatible = "arm,cortex-a9-scu"; reg = <0xa0410000 0x100>; }; diff --git a/Documentation/devicetree/bindings/arm/ux500/boards.txt b/Documentation/devicetree/bindings/arm/ux500/boards.txt index 0fa429534f49..89408de55bfd 100644 --- a/Documentation/devicetree/bindings/arm/ux500/boards.txt +++ b/Documentation/devicetree/bindings/arm/ux500/boards.txt @@ -60,7 +60,7 @@ Example: <0xa0410100 0x100>; }; - scu@a04100000 { + scu@a0410000 { compatible = "arm,cortex-a9-scu"; reg = <0xa0410000 0x100>; }; -- cgit v1.2.3 From 6eb17c6c8aee233e27339bcefe4bf9bef6d94c6c Mon Sep 17 00:00:00 2001 From: Song Qiang Date: Tue, 18 Sep 2018 16:24:21 +0800 Subject: iio: proximity: Add driver support for ST's VL53L0X ToF ranging sensor. This driver was originally written by ST in 2016 as a misc input device driver, and hasn't been maintained for a long time. I grabbed some code from it's API and reformed it into an iio proximity device driver. This version of driver uses i2c bus to talk to the sensor and polling for measuring completes, so no irq line is needed. It can be tested with reading from /sys/bus/iio/devices/iio:deviceX/in_distance_input Signed-off-by: Song Qiang Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/proximity/vl53l0x.txt | 12 ++ MAINTAINERS | 7 + drivers/iio/proximity/Kconfig | 11 ++ drivers/iio/proximity/Makefile | 2 + drivers/iio/proximity/vl53l0x-i2c.c | 164 +++++++++++++++++++++ 5 files changed, 196 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt create mode 100644 drivers/iio/proximity/vl53l0x-i2c.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt new file mode 100644 index 000000000000..aac5f621f8dc --- /dev/null +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt @@ -0,0 +1,12 @@ +ST VL53L0X ToF ranging sensor + +Required properties: + - compatible: must be "st,vl53l0x" + - reg: i2c address where to find the device + +Example: + +vl53l0x@29 { + compatible = "st,vl53l0x"; + reg = <0x29>; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 1e3e0dfe448a..5570477fb22b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13755,6 +13755,13 @@ L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-stm32* +ST VL53L0X ToF RANGER(I2C) IIO DRIVER +M: Song Qiang +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/proximity/vl53l0x-i2c.c +F: Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt + STABLE BRANCH M: Greg Kroah-Hartman L: stable@vger.kernel.org diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index 388ef70c11d2..b99367a89f81 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -92,4 +92,15 @@ config SRF08 To compile this driver as a module, choose M here: the module will be called srf08. +config VL53L0X_I2C + tristate "STMicroelectronics VL53L0X ToF ranger sensor (I2C)" + depends on I2C + help + Say Y here to build a driver for STMicroelectronics VL53L0X + ToF ranger sensors with i2c interface. + This driver can be used to measure the distance of objects. + + To compile this driver as a module, choose M here: the + module will be called vl53l0x-i2c. + endmenu diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index cac3d7d3325e..6d031f903c4c 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_RFD77402) += rfd77402.o obj-$(CONFIG_SRF04) += srf04.o obj-$(CONFIG_SRF08) += srf08.o obj-$(CONFIG_SX9500) += sx9500.o +obj-$(CONFIG_VL53L0X_I2C) += vl53l0x-i2c.o + diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c new file mode 100644 index 000000000000..b48216cc1858 --- /dev/null +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for ST VL53L0X FlightSense ToF Ranging Sensor on a i2c bus. + * + * Copyright (C) 2016 STMicroelectronics Imaging Division. + * Copyright (C) 2018 Song Qiang + * + * Datasheet available at + * + * + * Default 7-bit i2c slave address 0x29. + * + * TODO: FIFO buffer, continuous mode, interrupts, range selection, + * sensor ID check. + */ + +#include +#include +#include + +#include + +#define VL_REG_SYSRANGE_START 0x00 + +#define VL_REG_SYSRANGE_MODE_MASK GENMASK(3, 0) +#define VL_REG_SYSRANGE_MODE_SINGLESHOT 0x00 +#define VL_REG_SYSRANGE_MODE_START_STOP BIT(0) +#define VL_REG_SYSRANGE_MODE_BACKTOBACK BIT(1) +#define VL_REG_SYSRANGE_MODE_TIMED BIT(2) +#define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) + +#define VL_REG_RESULT_INT_STATUS 0x13 +#define VL_REG_RESULT_RANGE_STATUS 0x14 +#define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) + +struct vl53l0x_data { + struct i2c_client *client; +}; + +static int vl53l0x_read_proximity(struct vl53l0x_data *data, + const struct iio_chan_spec *chan, + int *val) +{ + struct i2c_client *client = data->client; + u16 tries = 20; + u8 buffer[12]; + int ret; + + ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1); + if (ret < 0) + return ret; + + do { + ret = i2c_smbus_read_byte_data(client, + VL_REG_RESULT_RANGE_STATUS); + if (ret < 0) + return ret; + + if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) + break; + + usleep_range(1000, 5000); + } while (--tries); + if (!tries) + return -ETIMEDOUT; + + ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS, + 12, buffer); + if (ret < 0) + return ret; + else if (ret != 12) + return -EREMOTEIO; + + /* Values should be between 30~1200 in millimeters. */ + *val = (buffer[10] << 8) + buffer[11]; + + return 0; +} + +static const struct iio_chan_spec vl53l0x_channels[] = { + { + .type = IIO_DISTANCE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static int vl53l0x_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + int ret; + + if (chan->type != IIO_DISTANCE) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = vl53l0x_read_proximity(data, chan, val); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = 1000; + + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static const struct iio_info vl53l0x_info = { + .read_raw = vl53l0x_read_raw, +}; + +static int vl53l0x_probe(struct i2c_client *client) +{ + struct vl53l0x_data *data; + struct iio_dev *indio_dev; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = client; + i2c_set_clientdata(client, indio_dev); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK | + I2C_FUNC_SMBUS_BYTE_DATA)) + return -EOPNOTSUPP; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = "vl53l0x"; + indio_dev->info = &vl53l0x_info; + indio_dev->channels = vl53l0x_channels; + indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct of_device_id st_vl53l0x_dt_match[] = { + { .compatible = "st,vl53l0x", }, + { } +}; +MODULE_DEVICE_TABLE(of, st_vl53l0x_dt_match); + +static struct i2c_driver vl53l0x_driver = { + .driver = { + .name = "vl53l0x-i2c", + .of_match_table = st_vl53l0x_dt_match, + }, + .probe_new = vl53l0x_probe, +}; +module_i2c_driver(vl53l0x_driver); + +MODULE_AUTHOR("Song Qiang "); +MODULE_DESCRIPTION("ST vl53l0x ToF ranging sensor driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From cdb04e08ab7312442784aecbcff7207b7eee1c0b Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 13 Sep 2018 23:35:43 +0530 Subject: dt-bindings: arm: rockchip: Add binding for Rock960 board Add devicetree binding for Rock960 board from Vamrs Limited. Signed-off-by: Manivannan Sadhasivam Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 5fc9c236ca87..6bb80f2b7c5d 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -5,6 +5,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "vamrs,ficus", "rockchip,rk3399"; +- 96boards RK3399 Rock960 (ROCK960 Consumer Edition) + Required root node properties: + - compatible = "vamrs,rock960", "rockchip,rk3399"; + - Amarula Vyasa RK3288 board Required root node properties: - compatible = "amarula,vyasa-rk3288", "rockchip,rk3288"; -- cgit v1.2.3 From db0340182444612bcadb98bdec22f651aa42266c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 14 Sep 2018 04:58:03 -0400 Subject: media: replace ADOBERGB by OPRGB The CTA-861 standards have been updated to refer to opRGB instead of AdobeRGB. The official standard is in fact named opRGB, so switch to that. The two old defines referring to ADOBERGB in the public API are put under #ifndef __KERNEL__ and a comment mentions that they are deprecated. Signed-off-by: Hans Verkuil Cc: stable@vger.kernel.org Acked-by: Daniel Vetter Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/videodev2.h.rst.exceptions | 6 +- drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c | 262 ++++++++++++------------ drivers/media/i2c/adv7511.c | 2 +- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/tc358743.c | 4 +- drivers/media/platform/vivid/vivid-core.h | 2 +- drivers/media/platform/vivid/vivid-ctrls.c | 6 +- drivers/media/platform/vivid/vivid-vid-out.c | 2 +- drivers/media/v4l2-core/v4l2-dv-timings.c | 8 +- include/uapi/linux/videodev2.h | 23 ++- 10 files changed, 165 insertions(+), 152 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index 63fa131729c0..1f4340dd9a37 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -56,7 +56,8 @@ replace symbol V4L2_MEMORY_USERPTR :c:type:`v4l2_memory` # Documented enum v4l2_colorspace replace symbol V4L2_COLORSPACE_470_SYSTEM_BG :c:type:`v4l2_colorspace` replace symbol V4L2_COLORSPACE_470_SYSTEM_M :c:type:`v4l2_colorspace` -replace symbol V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace` +replace symbol V4L2_COLORSPACE_OPRGB :c:type:`v4l2_colorspace` +replace define V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace` replace symbol V4L2_COLORSPACE_BT2020 :c:type:`v4l2_colorspace` replace symbol V4L2_COLORSPACE_DCI_P3 :c:type:`v4l2_colorspace` replace symbol V4L2_COLORSPACE_DEFAULT :c:type:`v4l2_colorspace` @@ -69,7 +70,8 @@ replace symbol V4L2_COLORSPACE_SRGB :c:type:`v4l2_colorspace` # Documented enum v4l2_xfer_func replace symbol V4L2_XFER_FUNC_709 :c:type:`v4l2_xfer_func` -replace symbol V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func` +replace symbol V4L2_XFER_FUNC_OPRGB :c:type:`v4l2_xfer_func` +replace define V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_DCI_P3 :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_DEFAULT :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_NONE :c:type:`v4l2_xfer_func` diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c index 3a3dc23c560c..a4341205c197 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c @@ -602,14 +602,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 }, @@ -658,14 +658,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 }, @@ -714,14 +714,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 }, @@ -770,14 +770,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2599, 901, 909 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 991, 0, 2966 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2989, 3120, 1180 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1913, 3011, 3009 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1836, 3099, 1105 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2627, 413, 2966 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2576, 943, 951 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1026, 0, 2942 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][1] = { 2989, 3120, 1180 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][2] = { 1913, 3011, 3009 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][3] = { 1836, 3099, 1105 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][4] = { 2627, 413, 2966 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][5] = { 2576, 943, 951 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][6] = { 1026, 0, 2942 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2879, 3022, 874 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1688, 2903, 2901 }, @@ -826,14 +826,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][5] = { 3001, 800, 799 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3071 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 776 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][2] = { 1068, 3033, 3033 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][3] = { 1068, 3033, 776 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][4] = { 2977, 851, 3048 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][5] = { 2977, 851, 851 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3048 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 776 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][2] = { 1068, 3033, 3033 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][3] = { 1068, 3033, 776 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][4] = { 2977, 851, 3048 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][5] = { 2977, 851, 851 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3048 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 423 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][2] = { 749, 2926, 2926 }, @@ -882,14 +882,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 }, @@ -922,62 +922,62 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 1063 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 1828, 3033, 3033 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 1828, 3033, 1063 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 2633, 851, 2979 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 2633, 851, 851 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 2979 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 1063 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][2] = { 1828, 3033, 3033 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][3] = { 1828, 3033, 1063 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][4] = { 2633, 851, 2979 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][5] = { 2633, 851, 851 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 2979 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 }, + [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 }, @@ -994,14 +994,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][5] = { 2517, 1159, 900 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][6] = { 1042, 870, 2917 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][1] = { 2976, 3018, 1315 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][2] = { 2024, 2942, 3011 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][3] = { 1930, 2926, 1256 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][4] = { 2563, 1227, 2916 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][5] = { 2494, 1183, 943 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][6] = { 1073, 916, 2894 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][1] = { 2976, 3018, 1315 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][2] = { 2024, 2942, 3011 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][3] = { 1930, 2926, 1256 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][4] = { 2563, 1227, 2916 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][5] = { 2494, 1183, 943 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][6] = { 1073, 916, 2894 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][1] = { 2864, 2910, 1024 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][2] = { 1811, 2826, 2903 }, @@ -1050,14 +1050,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][5] = { 2880, 998, 902 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][6] = { 816, 823, 2940 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][1] = { 3029, 3028, 1255 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][2] = { 1406, 2988, 3011 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][3] = { 1398, 2983, 1190 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][4] = { 2860, 1050, 2939 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][5] = { 2857, 1033, 945 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][6] = { 866, 873, 2916 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][1] = { 3029, 3028, 1255 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][2] = { 1406, 2988, 3011 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][3] = { 1398, 2983, 1190 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][4] = { 2860, 1050, 2939 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][5] = { 2857, 1033, 945 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][6] = { 866, 873, 2916 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][1] = { 2923, 2921, 957 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][2] = { 1125, 2877, 2902 }, @@ -1128,7 +1128,7 @@ static const double rec709_to_240m[3][3] = { { 0.0016327, 0.0044133, 0.9939540 }, }; -static const double rec709_to_adobergb[3][3] = { +static const double rec709_to_oprgb[3][3] = { { 0.7151627, 0.2848373, -0.0000000 }, { 0.0000000, 1.0000000, 0.0000000 }, { -0.0000000, 0.0411705, 0.9588295 }, @@ -1195,7 +1195,7 @@ static double transfer_rec709_to_rgb(double v) return (v < 0.081) ? v / 4.5 : pow((v + 0.099) / 1.099, 1.0 / 0.45); } -static double transfer_rgb_to_adobergb(double v) +static double transfer_rgb_to_oprgb(double v) { return pow(v, 1.0 / 2.19921875); } @@ -1251,8 +1251,8 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func, case V4L2_COLORSPACE_470_SYSTEM_M: mult_matrix(r, g, b, rec709_to_ntsc1953); break; - case V4L2_COLORSPACE_ADOBERGB: - mult_matrix(r, g, b, rec709_to_adobergb); + case V4L2_COLORSPACE_OPRGB: + mult_matrix(r, g, b, rec709_to_oprgb); break; case V4L2_COLORSPACE_BT2020: mult_matrix(r, g, b, rec709_to_bt2020); @@ -1284,10 +1284,10 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func, *g = transfer_rgb_to_srgb(*g); *b = transfer_rgb_to_srgb(*b); break; - case V4L2_XFER_FUNC_ADOBERGB: - *r = transfer_rgb_to_adobergb(*r); - *g = transfer_rgb_to_adobergb(*g); - *b = transfer_rgb_to_adobergb(*b); + case V4L2_XFER_FUNC_OPRGB: + *r = transfer_rgb_to_oprgb(*r); + *g = transfer_rgb_to_oprgb(*g); + *b = transfer_rgb_to_oprgb(*b); break; case V4L2_XFER_FUNC_DCI_P3: *r = transfer_rgb_to_dcip3(*r); @@ -1321,7 +1321,7 @@ int main(int argc, char **argv) V4L2_COLORSPACE_470_SYSTEM_BG, 0, V4L2_COLORSPACE_SRGB, - V4L2_COLORSPACE_ADOBERGB, + V4L2_COLORSPACE_OPRGB, V4L2_COLORSPACE_BT2020, 0, V4L2_COLORSPACE_DCI_P3, @@ -1336,7 +1336,7 @@ int main(int argc, char **argv) "V4L2_COLORSPACE_470_SYSTEM_BG", "", "V4L2_COLORSPACE_SRGB", - "V4L2_COLORSPACE_ADOBERGB", + "V4L2_COLORSPACE_OPRGB", "V4L2_COLORSPACE_BT2020", "", "V4L2_COLORSPACE_DCI_P3", @@ -1345,7 +1345,7 @@ int main(int argc, char **argv) "", "V4L2_XFER_FUNC_709", "V4L2_XFER_FUNC_SRGB", - "V4L2_XFER_FUNC_ADOBERGB", + "V4L2_XFER_FUNC_OPRGB", "V4L2_XFER_FUNC_SMPTE240M", "V4L2_XFER_FUNC_NONE", "V4L2_XFER_FUNC_DCI_P3", diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 55c2ea0720d9..a1f73d998495 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1355,7 +1355,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd, state->xfer_func = format->format.xfer_func; switch (format->format.colorspace) { - case V4L2_COLORSPACE_ADOBERGB: + case V4L2_COLORSPACE_OPRGB: c = HDMI_COLORIMETRY_EXTENDED; ec = y ? HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 : HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index c31673fcd5c1..070fdf65b714 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2474,7 +2474,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", "xvYCC Bt.601", "xvYCC Bt.709", "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)", - "sYCC", "Adobe YCC 601", "AdobeRGB", "invalid", "invalid", + "sYCC", "opYCC 601", "opRGB", "invalid", "invalid", "invalid", "invalid", "invalid" }; static const char * const rgb_quantization_range_txt[] = { diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index ef4dbac6bb58..74159153dfad 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1243,9 +1243,9 @@ static int tc358743_log_status(struct v4l2_subdev *sd) u8 vi_status3 = i2c_rd8(sd, VI_STATUS3); const int deep_color_mode[4] = { 8, 10, 12, 16 }; static const char * const input_color_space[] = { - "RGB", "YCbCr 601", "Adobe RGB", "YCbCr 709", "NA (4)", + "RGB", "YCbCr 601", "opRGB", "YCbCr 709", "NA (4)", "xvYCC 601", "NA(6)", "xvYCC 709", "NA(8)", "sYCC601", - "NA(10)", "NA(11)", "NA(12)", "Adobe YCC 601"}; + "NA(10)", "NA(11)", "NA(12)", "opYCC 601"}; v4l2_info(sd, "-----Chip status-----\n"); v4l2_info(sd, "Chip ID: 0x%02x\n", diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 477c80a4d44c..cd4c8230563c 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -111,7 +111,7 @@ enum vivid_colorspace { VIVID_CS_170M, VIVID_CS_709, VIVID_CS_SRGB, - VIVID_CS_ADOBERGB, + VIVID_CS_OPRGB, VIVID_CS_2020, VIVID_CS_DCI_P3, VIVID_CS_240M, diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 5429193fbb91..999aa101b150 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -348,7 +348,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_REC709, V4L2_COLORSPACE_SRGB, - V4L2_COLORSPACE_ADOBERGB, + V4L2_COLORSPACE_OPRGB, V4L2_COLORSPACE_BT2020, V4L2_COLORSPACE_DCI_P3, V4L2_COLORSPACE_SMPTE240M, @@ -729,7 +729,7 @@ static const char * const vivid_ctrl_colorspace_strings[] = { "SMPTE 170M", "Rec. 709", "sRGB", - "AdobeRGB", + "opRGB", "BT.2020", "DCI-P3", "SMPTE 240M", @@ -752,7 +752,7 @@ static const char * const vivid_ctrl_xfer_func_strings[] = { "Default", "Rec. 709", "sRGB", - "AdobeRGB", + "opRGB", "SMPTE 240M", "None", "DCI-P3", diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 51fec66d8d45..50248e2176a0 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -413,7 +413,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, mp->colorspace = V4L2_COLORSPACE_SMPTE170M; } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M && mp->colorspace != V4L2_COLORSPACE_REC709 && - mp->colorspace != V4L2_COLORSPACE_ADOBERGB && + mp->colorspace != V4L2_COLORSPACE_OPRGB && mp->colorspace != V4L2_COLORSPACE_BT2020 && mp->colorspace != V4L2_COLORSPACE_SRGB) { mp->colorspace = V4L2_COLORSPACE_REC709; diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index b4e50c5509b7..19aabd1fcd2b 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -878,8 +878,8 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, case HDMI_COLORIMETRY_EXTENDED: switch (avi->extended_colorimetry) { case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB: - c.colorspace = V4L2_COLORSPACE_ADOBERGB; - c.xfer_func = V4L2_XFER_FUNC_ADOBERGB; + c.colorspace = V4L2_COLORSPACE_OPRGB; + c.xfer_func = V4L2_XFER_FUNC_OPRGB; break; case HDMI_EXTENDED_COLORIMETRY_BT2020: c.colorspace = V4L2_COLORSPACE_BT2020; @@ -949,9 +949,9 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, c.xfer_func = V4L2_XFER_FUNC_SRGB; break; case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601: - c.colorspace = V4L2_COLORSPACE_ADOBERGB; + c.colorspace = V4L2_COLORSPACE_OPRGB; c.ycbcr_enc = V4L2_YCBCR_ENC_601; - c.xfer_func = V4L2_XFER_FUNC_ADOBERGB; + c.xfer_func = V4L2_XFER_FUNC_OPRGB; break; case HDMI_EXTENDED_COLORIMETRY_BT2020: c.colorspace = V4L2_COLORSPACE_BT2020; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 184e4dbe8f9c..29729d580452 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -225,8 +225,8 @@ enum v4l2_colorspace { /* For RGB colorspaces such as produces by most webcams. */ V4L2_COLORSPACE_SRGB = 8, - /* AdobeRGB colorspace */ - V4L2_COLORSPACE_ADOBERGB = 9, + /* opRGB colorspace */ + V4L2_COLORSPACE_OPRGB = 9, /* BT.2020 colorspace, used for UHDTV. */ V4L2_COLORSPACE_BT2020 = 10, @@ -258,7 +258,7 @@ enum v4l2_xfer_func { * * V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_JPEG: V4L2_XFER_FUNC_SRGB * - * V4L2_COLORSPACE_ADOBERGB: V4L2_XFER_FUNC_ADOBERGB + * V4L2_COLORSPACE_OPRGB: V4L2_XFER_FUNC_OPRGB * * V4L2_COLORSPACE_SMPTE240M: V4L2_XFER_FUNC_SMPTE240M * @@ -269,7 +269,7 @@ enum v4l2_xfer_func { V4L2_XFER_FUNC_DEFAULT = 0, V4L2_XFER_FUNC_709 = 1, V4L2_XFER_FUNC_SRGB = 2, - V4L2_XFER_FUNC_ADOBERGB = 3, + V4L2_XFER_FUNC_OPRGB = 3, V4L2_XFER_FUNC_SMPTE240M = 4, V4L2_XFER_FUNC_NONE = 5, V4L2_XFER_FUNC_DCI_P3 = 6, @@ -281,7 +281,7 @@ enum v4l2_xfer_func { * This depends on the colorspace. */ #define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) \ - ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : \ + ((colsp) == V4L2_COLORSPACE_OPRGB ? V4L2_XFER_FUNC_OPRGB : \ ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : \ ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : \ ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : \ @@ -295,7 +295,7 @@ enum v4l2_ycbcr_encoding { * * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB, - * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 + * V4L2_COLORSPACE_OPRGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 * * V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709 * @@ -382,6 +382,17 @@ enum v4l2_quantization { (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) +/* + * Deprecated names for opRGB colorspace (IEC 61966-2-5) + * + * WARNING: Please don't use these deprecated defines in your code, as + * there is a chance we have to remove them in the future. + */ +#ifndef __KERNEL__ +#define V4L2_COLORSPACE_ADOBERGB V4L2_COLORSPACE_OPRGB +#define V4L2_XFER_FUNC_ADOBERGB V4L2_XFER_FUNC_OPRGB +#endif + enum v4l2_priority { V4L2_PRIORITY_UNSET = 0, /* not initialized */ V4L2_PRIORITY_BACKGROUND = 1, -- cgit v1.2.3 From a58c37978cf02f6d35d05ee4e9288cb8455f1401 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2018 07:47:28 -0400 Subject: media: media colorspaces*.rst: rename AdobeRGB to opRGB Drop all Adobe references and use the official opRGB standard instead. Signed-off-by: Hans Verkuil Cc: stable@vger.kernel.org Acked-by: Daniel Vetter Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/biblio.rst | 10 ---------- Documentation/media/uapi/v4l/colorspaces-defs.rst | 8 ++++---- Documentation/media/uapi/v4l/colorspaces-details.rst | 13 ++++++------- 3 files changed, 10 insertions(+), 21 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst index 1cedcfc04327..386d6cf83e9c 100644 --- a/Documentation/media/uapi/v4l/biblio.rst +++ b/Documentation/media/uapi/v4l/biblio.rst @@ -226,16 +226,6 @@ xvYCC :author: International Electrotechnical Commission (http://www.iec.ch) -.. _adobergb: - -AdobeRGB -======== - - -:title: Adobe© RGB (1998) Color Image Encoding Version 2005-05 - -:author: Adobe Systems Incorporated (http://www.adobe.com) - .. _oprgb: opRGB diff --git a/Documentation/media/uapi/v4l/colorspaces-defs.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst index 410907fe9415..f24615544792 100644 --- a/Documentation/media/uapi/v4l/colorspaces-defs.rst +++ b/Documentation/media/uapi/v4l/colorspaces-defs.rst @@ -51,8 +51,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum - See :ref:`col-rec709`. * - ``V4L2_COLORSPACE_SRGB`` - See :ref:`col-srgb`. - * - ``V4L2_COLORSPACE_ADOBERGB`` - - See :ref:`col-adobergb`. + * - ``V4L2_COLORSPACE_OPRGB`` + - See :ref:`col-oprgb`. * - ``V4L2_COLORSPACE_BT2020`` - See :ref:`col-bt2020`. * - ``V4L2_COLORSPACE_DCI_P3`` @@ -90,8 +90,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum - Use the Rec. 709 transfer function. * - ``V4L2_XFER_FUNC_SRGB`` - Use the sRGB transfer function. - * - ``V4L2_XFER_FUNC_ADOBERGB`` - - Use the AdobeRGB transfer function. + * - ``V4L2_XFER_FUNC_OPRGB`` + - Use the opRGB transfer function. * - ``V4L2_XFER_FUNC_SMPTE240M`` - Use the SMPTE 240M transfer function. * - ``V4L2_XFER_FUNC_NONE`` diff --git a/Documentation/media/uapi/v4l/colorspaces-details.rst b/Documentation/media/uapi/v4l/colorspaces-details.rst index b5d551b9cc8f..09fabf4cd412 100644 --- a/Documentation/media/uapi/v4l/colorspaces-details.rst +++ b/Documentation/media/uapi/v4l/colorspaces-details.rst @@ -290,15 +290,14 @@ Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range 170M/BT.601. The Y'CbCr quantization is limited range. -.. _col-adobergb: +.. _col-oprgb: -Colorspace Adobe RGB (V4L2_COLORSPACE_ADOBERGB) +Colorspace opRGB (V4L2_COLORSPACE_OPRGB) =============================================== -The :ref:`adobergb` standard defines the colorspace used by computer -graphics that use the AdobeRGB colorspace. This is also known as the -:ref:`oprgb` standard. The default transfer function is -``V4L2_XFER_FUNC_ADOBERGB``. The default Y'CbCr encoding is +The :ref:`oprgb` standard defines the colorspace used by computer +graphics that use the opRGB colorspace. The default transfer function is +``V4L2_XFER_FUNC_OPRGB``. The default Y'CbCr encoding is ``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited range. @@ -312,7 +311,7 @@ The chromaticities of the primary colors and the white reference are: .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| -.. flat-table:: Adobe RGB Chromaticities +.. flat-table:: opRGB Chromaticities :header-rows: 1 :stub-columns: 0 :widths: 1 1 2 -- cgit v1.2.3 From 6c78ca379c2edfe71c97c1abbb2716298263b9c7 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 1 Aug 2018 16:45:13 +0800 Subject: dt-bindings: usb: dwc2: add description for px30 This patch adds the compatible of dwc2 for PX30 SoCs. Signed-off-by: Liang Chen Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/usb/dwc2.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 46da5f184460..6dc3c4a34483 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -6,6 +6,7 @@ Required properties: - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC. - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc; + - "rockchip,px30-usb", "rockchip,rk3066-usb", "snps,dwc2": for px30 Soc; - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc; - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; -- cgit v1.2.3 From c27bb30e7b6d385c5bff26406089377d678f1a1d Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 13 Sep 2018 10:51:52 -0400 Subject: media: v4l: Add definitions for MPEG-2 slice format and metadata Stateless video decoding engines require both the MPEG-2 slices and associated metadata from the video stream in order to decode frames. This introduces definitions for a new pixel format, describing buffers with MPEG-2 slice data, as well as control structure sfor passing the frame metadata to drivers. This is based on work from both Florent Revest and Hugues Fruchet. Signed-off-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/extended-controls.rst | 176 +++++++++++++++++++++ Documentation/media/uapi/v4l/pixfmt-compressed.rst | 16 ++ Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 14 +- Documentation/media/videodev2.h.rst.exceptions | 2 + drivers/media/v4l2-core/v4l2-ctrls.c | 63 ++++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/media/v4l2-ctrls.h | 18 ++- include/uapi/linux/v4l2-controls.h | 65 ++++++++ include/uapi/linux/videodev2.h | 5 + 9 files changed, 351 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 9f7312bf3365..65a1d873196b 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -1497,6 +1497,182 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - +.. _v4l2-mpeg-mpeg2: + +``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)`` + Specifies the slice parameters (as extracted from the bitstream) for the + associated MPEG-2 slice data. This includes the necessary parameters for + configuring a stateless hardware decoding pipeline for MPEG-2. + The bitstream parameters are defined according to :ref:`mpeg2part2`. + +.. c:type:: v4l2_ctrl_mpeg2_slice_params + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u32 + - ``bit_size`` + - Size (in bits) of the current slice data. + * - __u32 + - ``data_bit_offset`` + - Offset (in bits) to the video data in the current slice data. + * - struct :c:type:`v4l2_mpeg2_sequence` + - ``sequence`` + - Structure with MPEG-2 sequence metadata, merging relevant fields from + the sequence header and sequence extension parts of the bitstream. + * - struct :c:type:`v4l2_mpeg2_picture` + - ``picture`` + - Structure with MPEG-2 picture metadata, merging relevant fields from + the picture header and picture coding extension parts of the bitstream. + * - __u8 + - ``quantiser_scale_code`` + - Code used to determine the quantization scale to use for the IDCT. + * - __u8 + - ``backward_ref_index`` + - Index for the V4L2 buffer to use as backward reference, used with + B-coded and P-coded frames. + * - __u8 + - ``forward_ref_index`` + - Index for the V4L2 buffer to use as forward reference, used with + B-coded frames. + +.. c:type:: v4l2_mpeg2_sequence + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_mpeg2_sequence + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u16 + - ``horizontal_size`` + - The width of the displayable part of the frame's luminance component. + * - __u16 + - ``vertical_size`` + - The height of the displayable part of the frame's luminance component. + * - __u32 + - ``vbv_buffer_size`` + - Used to calculate the required size of the video buffering verifier, + defined (in bits) as: 16 * 1024 * vbv_buffer_size. + * - __u8 + - ``profile_and_level_indication`` + - The current profile and level indication as extracted from the + bitstream. + * - __u8 + - ``progressive_sequence`` + - Indication that all the frames for the sequence are progressive instead + of interlaced. + * - __u8 + - ``chroma_format`` + - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4). + +.. c:type:: v4l2_mpeg2_picture + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_mpeg2_picture + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u8 + - ``picture_coding_type`` + - Picture coding type for the frame covered by the current slice + (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or + V4L2_MPEG2_PICTURE_CODING_TYPE_B). + * - __u8 + - ``f_code[2][2]`` + - Motion vector codes. + * - __u8 + - ``intra_dc_precision`` + - Precision of Discrete Cosine transform (0: 8 bits precision, + 1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision). + * - __u8 + - ``picture_structure`` + - Picture structure (1: interlaced top field, 2: interlaced bottom field, + 3: progressive frame). + * - __u8 + - ``top_field_first`` + - If set to 1 and interlaced stream, top field is output first. + * - __u8 + - ``frame_pred_frame_dct`` + - If set to 1, only frame-DCT and frame prediction are used. + * - __u8 + - ``concealment_motion_vectors`` + - If set to 1, motion vectors are coded for intra macroblocks. + * - __u8 + - ``q_scale_type`` + - This flag affects the inverse quantization process. + * - __u8 + - ``intra_vlc_format`` + - This flag affects the decoding of transform coefficient data. + * - __u8 + - ``alternate_scan`` + - This flag affects the decoding of transform coefficient data. + * - __u8 + - ``repeat_first_field`` + - This flag affects the decoding process of progressive frames. + * - __u8 + - ``progressive_frame`` + - Indicates whether the current frame is progressive. + +``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)`` + Specifies quantization matrices (as extracted from the bitstream) for the + associated MPEG-2 slice data. + +.. c:type:: v4l2_ctrl_mpeg2_quantization + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_ctrl_mpeg2_quantization + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u8 + - ``load_intra_quantiser_matrix`` + - One bit to indicate whether to load the ``intra_quantiser_matrix`` data. + * - __u8 + - ``load_non_intra_quantiser_matrix`` + - One bit to indicate whether to load the ``non_intra_quantiser_matrix`` + data. + * - __u8 + - ``load_chroma_intra_quantiser_matrix`` + - One bit to indicate whether to load the + ``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV + formats. + * - __u8 + - ``load_chroma_non_intra_quantiser_matrix`` + - One bit to indicate whether to load the + ``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0 + YUV formats. + * - __u8 + - ``intra_quantiser_matrix[64]`` + - The quantization matrix coefficients for intra-coded frames, in zigzag + scanning order. It is relevant for both luma and chroma components, + although it can be superseded by the chroma-specific matrix for + non-4:2:0 YUV formats. + * - __u8 + - ``non_intra_quantiser_matrix[64]`` + - The quantization matrix coefficients for non-intra-coded frames, in + zigzag scanning order. It is relevant for both luma and chroma + components, although it can be superseded by the chroma-specific matrix + for non-4:2:0 YUV formats. + * - __u8 + - ``chroma_intra_quantiser_matrix[64]`` + - The quantization matrix coefficients for the chominance component of + intra-coded frames, in zigzag scanning order. Only relevant for + non-4:2:0 YUV formats. + * - __u8 + - ``chroma_non_intra_quantiser_matrix[64]`` + - The quantization matrix coefficients for the chrominance component of + non-intra-coded frames, in zigzag scanning order. Only relevant for + non-4:2:0 YUV formats. MFC 5.1 MPEG Controls --------------------- diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst index d04b18adac33..ba0f6c49d9bf 100644 --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst @@ -60,6 +60,22 @@ Compressed Formats - ``V4L2_PIX_FMT_MPEG2`` - 'MPG2' - MPEG2 video elementary stream. + * .. _V4L2-PIX-FMT-MPEG2-SLICE: + + - ``V4L2_PIX_FMT_MPEG2_SLICE`` + - 'MG2S' + - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream. + This format is adapted for stateless video decoders that implement a + MPEG-2 pipeline (using the :ref:`codec` and :ref:`media-request-api`). + Metadata associated with the frame to decode is required to be passed + through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and + quantization matrices can optionally be specified through the + ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control. + See the :ref:`associated Codec Control IDs `. + Exactly one output and one capture buffer must be provided for use with + this pixel format. The output buffer must contain the appropriate number + of macroblocks to decode a full corresponding frame to the matching + capture buffer. * .. _V4L2-PIX-FMT-MPEG4: - ``V4L2_PIX_FMT_MPEG4`` diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst index 5bd26e8c9a1a..258f5813f281 100644 --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst @@ -424,8 +424,18 @@ See also the examples in :ref:`control`. - any - An unsigned 32-bit valued control ranging from minimum to maximum inclusive. The step value indicates the increment between values. - - + * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2 + slice parameters for stateless video decoders. + * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2 + quantization matrices for stateless video decoders. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index 99256a2c003e..30ba0d6f546f 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -129,6 +129,8 @@ replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type` # V4L2 capability defines replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 5310ac857e83..65e3cf838ac7 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -844,6 +844,8 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; + case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; + case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; /* VPX controls */ case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; @@ -1292,6 +1294,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_RDS_TX_ALT_FREQS: *type = V4L2_CTRL_TYPE_U32; break; + case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: + *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; + break; + case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: + *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; + break; default: *type = V4L2_CTRL_TYPE_INTEGER; break; @@ -1550,6 +1558,7 @@ static void std_log(const struct v4l2_ctrl *ctrl) static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) { + struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; size_t len; u64 offset; s64 val; @@ -1612,6 +1621,54 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, return -ERANGE; return 0; + case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: + p_mpeg2_slice_params = ptr.p; + + switch (p_mpeg2_slice_params->sequence.chroma_format) { + case 1: /* 4:2:0 */ + case 2: /* 4:2:2 */ + case 3: /* 4:4:4 */ + break; + default: + return -EINVAL; + } + + switch (p_mpeg2_slice_params->picture.intra_dc_precision) { + case 0: /* 8 bits */ + case 1: /* 9 bits */ + case 11: /* 11 bits */ + break; + default: + return -EINVAL; + } + + switch (p_mpeg2_slice_params->picture.picture_structure) { + case 1: /* interlaced top field */ + case 2: /* interlaced bottom field */ + case 3: /* progressive */ + break; + default: + return -EINVAL; + } + + switch (p_mpeg2_slice_params->picture.picture_coding_type) { + case V4L2_MPEG2_PICTURE_CODING_TYPE_I: + case V4L2_MPEG2_PICTURE_CODING_TYPE_P: + case V4L2_MPEG2_PICTURE_CODING_TYPE_B: + break; + default: + return -EINVAL; + } + + if (p_mpeg2_slice_params->backward_ref_index >= VIDEO_MAX_FRAME || + p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME) + return -EINVAL; + + return 0; + + case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: + return 0; + default: return -EINVAL; } @@ -2186,6 +2243,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_U32: elem_size = sizeof(u32); break; + case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); + break; + case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); + break; default: if (type < V4L2_CTRL_COMPOUND_TYPES) elem_size = sizeof(s32); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 87dba0b9c0a7..1a8feaf6c3f7 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1309,6 +1309,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_H263: descr = "H.263"; break; case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; + case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 part 2 ES"; break; case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 53ca4df0c353..0dae03dd5b06 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -35,13 +35,15 @@ struct poll_table_struct; /** * union v4l2_ctrl_ptr - A pointer to a control value. - * @p_s32: Pointer to a 32-bit signed value. - * @p_s64: Pointer to a 64-bit signed value. - * @p_u8: Pointer to a 8-bit unsigned value. - * @p_u16: Pointer to a 16-bit unsigned value. - * @p_u32: Pointer to a 32-bit unsigned value. - * @p_char: Pointer to a string. - * @p: Pointer to a compound value. + * @p_s32: Pointer to a 32-bit signed value. + * @p_s64: Pointer to a 64-bit signed value. + * @p_u8: Pointer to a 8-bit unsigned value. + * @p_u16: Pointer to a 16-bit unsigned value. + * @p_u32: Pointer to a 32-bit unsigned value. + * @p_char: Pointer to a string. + * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. + * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure. + * @p: Pointer to a compound value. */ union v4l2_ctrl_ptr { s32 *p_s32; @@ -50,6 +52,8 @@ union v4l2_ctrl_ptr { u16 *p_u16; u32 *p_u32; char *p_char; + struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; + struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization; void *p; }; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index e4ee10ee917d..51b095898f4b 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -402,6 +402,9 @@ enum v4l2_mpeg_video_multi_slice_mode { #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228) #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229) +#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_MPEG_BASE+250) +#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (V4L2_CID_MPEG_BASE+251) + #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) @@ -1092,4 +1095,66 @@ enum v4l2_detect_md_mode { #define V4L2_CID_DETECT_MD_THRESHOLD_GRID (V4L2_CID_DETECT_CLASS_BASE + 3) #define V4L2_CID_DETECT_MD_REGION_GRID (V4L2_CID_DETECT_CLASS_BASE + 4) +#define V4L2_MPEG2_PICTURE_CODING_TYPE_I 1 +#define V4L2_MPEG2_PICTURE_CODING_TYPE_P 2 +#define V4L2_MPEG2_PICTURE_CODING_TYPE_B 3 +#define V4L2_MPEG2_PICTURE_CODING_TYPE_D 4 + +struct v4l2_mpeg2_sequence { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */ + __u16 horizontal_size; + __u16 vertical_size; + __u32 vbv_buffer_size; + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */ + __u8 profile_and_level_indication; + __u8 progressive_sequence; + __u8 chroma_format; +}; + +struct v4l2_mpeg2_picture { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */ + __u8 picture_coding_type; + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */ + __u8 f_code[2][2]; + __u8 intra_dc_precision; + __u8 picture_structure; + __u8 top_field_first; + __u8 frame_pred_frame_dct; + __u8 concealment_motion_vectors; + __u8 q_scale_type; + __u8 intra_vlc_format; + __u8 alternate_scan; + __u8 repeat_first_field; + __u8 progressive_frame; +}; + +struct v4l2_ctrl_mpeg2_slice_params { + __u32 bit_size; + __u32 data_bit_offset; + + struct v4l2_mpeg2_sequence sequence; + struct v4l2_mpeg2_picture picture; + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */ + __u8 quantiser_scale_code; + + __u8 backward_ref_index; + __u8 forward_ref_index; +}; + +struct v4l2_ctrl_mpeg2_quantization { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */ + __u8 load_intra_quantiser_matrix; + __u8 load_non_intra_quantiser_matrix; + __u8 load_chroma_intra_quantiser_matrix; + __u8 load_chroma_non_intra_quantiser_matrix; + + __u8 intra_quantiser_matrix[64]; + __u8 non_intra_quantiser_matrix[64]; + __u8 chroma_intra_quantiser_matrix[64]; + __u8 chroma_non_intra_quantiser_matrix[64]; +}; + #endif diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 55d45a387dd2..314ec7a5f046 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -635,6 +635,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ +#define V4L2_PIX_FMT_MPEG2_SLICE v4l2_fourcc('M', 'G', '2', 'S') /* MPEG-2 parsed slice data */ #define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */ #define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ @@ -1608,6 +1609,8 @@ struct v4l2_ext_control { __u8 __user *p_u8; __u16 __user *p_u16; __u32 __user *p_u32; + struct v4l2_ctrl_mpeg2_slice_params __user *p_mpeg2_slice_params; + struct v4l2_ctrl_mpeg2_quantization __user *p_mpeg2_quantization; void __user *ptr; }; } __attribute__ ((packed)); @@ -1653,6 +1656,8 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_U8 = 0x0100, V4L2_CTRL_TYPE_U16 = 0x0101, V4L2_CTRL_TYPE_U32 = 0x0102, + V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS = 0x0103, + V4L2_CTRL_TYPE_MPEG2_QUANTIZATION = 0x0104, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ -- cgit v1.2.3 From 36cf35b7864002c2601e4bda4d78d5622ad92544 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 13 Sep 2018 10:51:53 -0400 Subject: media: v4l: Add definition for the Sunxi tiled NV12 format This introduces support for the Sunxi tiled NV12 format, where each component of the YUV frame is divided into macroblocks. Hence, the size of each plane requires specific alignment. The pixels inside each macroblock are coded in linear order (line after line from top to bottom). This tiled NV12 format is used by the video engine on Allwinner platforms: it is the default format for decoded frames (and the only one available in the oldest supported platforms). Signed-off-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-reserved.rst | 15 ++++++++++++++- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst index 38af1472a4b4..0c399858bda2 100644 --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst @@ -243,7 +243,20 @@ please make a proposal on the linux-media mailing list. It is an opaque intermediate format and the MDP hardware must be used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``, ``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``. - + * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12: + + - ``V4L2_PIX_FMT_SUNXI_TILED_NV12`` + - 'ST12' + - Two-planar NV12-based format used by the video engine found on Allwinner + (codenamed sunxi) platforms, with 32x32 tiles for the luminance plane + and 32x64 tiles for the chrominance plane. The data in each tile is + stored in linear order, within the tile bounds. Each tile follows the + previous one linearly in memory (from left to right, top to bottom). + + The associated buffer dimensions are aligned to match an integer number + of tiles, resulting in 32-aligned resolutions for the luminance plane + and 16-aligned resolutions for the chrominance plane (with 2x2 + subsampling). .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 1a8feaf6c3f7..c148c44caffb 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1337,6 +1337,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; + case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break; default: WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); if (fmt->description[0]) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 314ec7a5f046..7412a255d9ce 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -677,6 +677,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ +#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */ /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ #define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ -- cgit v1.2.3 From a20625fb03df9d84378b63540c2ad6b34703af33 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 13 Sep 2018 10:51:54 -0400 Subject: media: dt-bindings: media: Document bindings for the Cedrus VPU driver This adds a device-tree binding document that specifies the properties used by the Cedrus VPU driver, as well as examples. Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring Signed-off-by: Maxime Ripard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/cedrus.txt | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/cedrus.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/cedrus.txt b/Documentation/devicetree/bindings/media/cedrus.txt new file mode 100644 index 000000000000..a089a0c1ff05 --- /dev/null +++ b/Documentation/devicetree/bindings/media/cedrus.txt @@ -0,0 +1,54 @@ +Device-tree bindings for the VPU found in Allwinner SoCs, referred to as the +Video Engine (VE) in Allwinner literature. + +The VPU can only access the first 256 MiB of DRAM, that are DMA-mapped starting +from the DRAM base. This requires specific memory allocation and handling. + +Required properties: +- compatible : must be one of the following compatibles: + - "allwinner,sun4i-a10-video-engine" + - "allwinner,sun5i-a13-video-engine" + - "allwinner,sun7i-a20-video-engine" + - "allwinner,sun8i-a33-video-engine" + - "allwinner,sun8i-h3-video-engine" +- reg : register base and length of VE; +- clocks : list of clock specifiers, corresponding to entries in + the clock-names property; +- clock-names : should contain "ahb", "mod" and "ram" entries; +- resets : phandle for reset; +- interrupts : VE interrupt number; +- allwinner,sram : SRAM region to use with the VE. + +Optional properties: +- memory-region : CMA pool to use for buffers allocation instead of the + default CMA pool. + +Example: + +reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Address must be kept in the lower 256 MiBs of DRAM for VE. */ + cma_pool: cma@4a000000 { + compatible = "shared-dma-pool"; + size = <0x6000000>; + alloc-ranges = <0x4a000000 0x6000000>; + reusable; + linux,cma-default; + }; +}; + +video-codec@1c0e000 { + compatible = "allwinner,sun7i-a20-video-engine"; + reg = <0x01c0e000 0x1000>; + + clocks = <&ccu CLK_AHB_VE>, <&ccu CLK_VE>, + <&ccu CLK_DRAM_VE>; + clock-names = "ahb", "mod", "ram"; + + resets = <&ccu RST_VE>; + interrupts = ; + allwinner,sram = <&ve_sram 1>; +}; -- cgit v1.2.3 From 40ad192f9e88d1376320399e49b9d978b56a9477 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Fri, 7 Sep 2018 12:59:25 +1200 Subject: dt-bindings: marvell,prestera: Add common compatible string Add "marvell,prestera" as a compatible string so that drivers can be written to account for any prestera variant without needing to specialise to the more specific values. Signed-off-by: Chris Packham Reviewed-by: Rob Herring Signed-off-by: Gregory CLEMENT --- Documentation/devicetree/bindings/net/marvell,prestera.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/marvell,prestera.txt b/Documentation/devicetree/bindings/net/marvell,prestera.txt index c329608fa887..83370ebf5b89 100644 --- a/Documentation/devicetree/bindings/net/marvell,prestera.txt +++ b/Documentation/devicetree/bindings/net/marvell,prestera.txt @@ -2,7 +2,7 @@ Marvell Prestera Switch Chip bindings ------------------------------------- Required properties: -- compatible: one of the following +- compatible: must be "marvell,prestera" and one of the following "marvell,prestera-98dx3236", "marvell,prestera-98dx3336", "marvell,prestera-98dx4251", @@ -21,7 +21,7 @@ switch { ranges = <0 MBUS_ID(0x03, 0x00) 0 0x100000>; packet-processor@0 { - compatible = "marvell,prestera-98dx3236"; + compatible = "marvell,prestera-98dx3236", "marvell,prestera"; reg = <0 0x4000000>; interrupts = <33>, <34>, <35>; dfx = <&dfx>; -- cgit v1.2.3 From fae210bb5bfbd29118e18881f7108c6bd59293b9 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 21 Sep 2018 16:52:58 +0100 Subject: dt-bindings: apmu: Document r8a7744 support Document APMU and SMP enable method for RZ/G1N (R8A7744) SoC. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/power/renesas,apmu.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt index e6f47c9b3d0e..5f24586c8cf3 100644 --- a/Documentation/devicetree/bindings/power/renesas,apmu.txt +++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt @@ -8,6 +8,7 @@ Required properties: - compatible: Should be "renesas,-apmu", "renesas,apmu" as fallback. Examples with soctypes are: - "renesas,r8a7743-apmu" (RZ/G1M) + - "renesas,r8a7744-apmu" (RZ/G1N) - "renesas,r8a7745-apmu" (RZ/G1E) - "renesas,r8a77470-apmu" (RZ/G1C) - "renesas,r8a7790-apmu" (R-Car H2) -- cgit v1.2.3 From f48097d294d6f76a38bf1a1cb579aa99ede44297 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 20 Aug 2018 17:07:25 +0300 Subject: dt-bindings: display: renesas: du: Document r8a77990 bindings Document the E3 (r8a77990) SoC in the R-Car DU bindings. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Rob Herring Reviewed-by: Ulrich Hecht --- Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index caae2348a292..9de67be632d1 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -16,6 +16,7 @@ Required Properties: - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU + - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU - reg: the memory-mapped I/O registers base address and length @@ -63,6 +64,7 @@ corresponding to each DU output. R8A77965 (R-Car M3-N) DPAD 0 HDMI 0 LVDS 0 - R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - - R8A77980 (R-Car V3H) DPAD 0 LVDS 0 - - + R8A77990 (R-Car E3) DPAD 0 LVDS 0 LVDS 1 - R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 - -- cgit v1.2.3 From f9c32db12e2439ec9553a1a4c43d0ee308387790 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 20 Aug 2018 17:12:49 +0300 Subject: dt-bindings: display: renesas: lvds: Document r8a77990 bindings The E3 (r8a77990) supports two LVDS channels. Extend the binding to support them. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Rob Herring Reviewed-by: Ulrich Hecht Reviewed-by: Kieran Bingham --- Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt index 5a4e379bb414..13af7e2ac7e8 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt @@ -15,6 +15,7 @@ Required properties: - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders + - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders - reg: Base address and length for the memory-mapped registers -- cgit v1.2.3 From 9734a7009de62c05e9b08fa65efb7c5214ab3f30 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 22 Aug 2018 15:27:16 +0300 Subject: dt-bindings: display: renesas: lvds: Add EXTAL and DU_DOTCLKIN clocks On the D3 and E3 SoCs, the LVDS encoder can derive its internal pixel clock from an externally supplied clock, either through the EXTAL pin or through one of the DU_DOTCLKINx pins. Add corresponding clocks to the DT bindings. To retain backward compatibility with DT that don't specify the clock-names property, the functional clock must always be specified first, and the clock-names property is optional when only the functional clock is specified. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Ulrich Hecht Reviewed-by: Kieran Bingham --- .../devicetree/bindings/display/bridge/renesas,lvds.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt index 13af7e2ac7e8..3aeb0ec06fd0 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt @@ -19,7 +19,17 @@ Required properties: - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders - reg: Base address and length for the memory-mapped registers -- clocks: A phandle + clock-specifier pair for the functional clock +- clocks: A list of phandles + clock-specifier pairs, one for each entry in + the clock-names property. +- clock-names: Name of the clocks. This property is model-dependent. + - The functional clock, which mandatory for all models, shall be listed + first, and shall be named "fck". + - On R8A77990 and R8A77995, the LVDS encoder can use the EXTAL or + DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be + named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN + numerical index. + - When the clocks property only contains the functional clock, the + clock-names property may be omitted. - resets: A phandle + reset specifier for the module reset Required nodes: -- cgit v1.2.3 From 6d0ca9dbb6d199cb2adeb40da3fea3c4ece6f092 Mon Sep 17 00:00:00 2001 From: Hsin-Hsiung Wang Date: Wed, 19 Sep 2018 15:25:58 +0800 Subject: dt-bindings: mediatek: add compatible for mt8183 pwrap This adds dt-binding documentation of pwrap for Mediatek MT8183 SoC Platform. Signed-off-by: Hsin-Hsiung Wang Reviewed-by: Rob Herring Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt index f9987c30f0d5..012fe3f4b5a4 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt @@ -23,6 +23,7 @@ Required properties in pwrap device node. "mediatek,mt7622-pwrap" for MT7622 SoCs "mediatek,mt8135-pwrap" for MT8135 SoCs "mediatek,mt8173-pwrap" for MT8173 SoCs + "mediatek,mt8183-pwrap" for MT8183 SoCs - interrupts: IRQ for pwrap in SOC - reg-names: Must include the following entries: "pwrap": Main registers base -- cgit v1.2.3 From 0db3bd82546039f4bf434d378bafe4416b82b757 Mon Sep 17 00:00:00 2001 From: Argus Lin Date: Tue, 4 Sep 2018 20:31:52 +0800 Subject: dt-bindings: pwrap: mediatek: add pwrap support for MT6765 Add binding document of pwrap for MT6765 SoCs. Signed-off-by: Argus Lin Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt index 012fe3f4b5a4..5a2ef1726e2a 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt @@ -19,6 +19,7 @@ IP Pairing Required properties in pwrap device node. - compatible: "mediatek,mt2701-pwrap" for MT2701/7623 SoCs + "mediatek,mt6765-pwrap" for MT6765 SoCs "mediatek,mt6797-pwrap" for MT6797 SoCs "mediatek,mt7622-pwrap" for MT7622 SoCs "mediatek,mt8135-pwrap" for MT8135 SoCs -- cgit v1.2.3 From 95bf69a22d97d6dc1802feef164b34d57280a77d Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Wed, 12 Sep 2018 12:38:35 -0700 Subject: dt-bindings: firmware: Add bindings for ZynqMP firmware Add documentation to describe Xilinx ZynqMP firmware driver bindings. Firmware driver provides an interface to firmware APIs. Interface APIs can be used by any driver to communicate to PMUFW (Platform Management Unit). Signed-off-by: Rajan Vaja Signed-off-by: Jolly Shah Reviewed-by: Rob Herring Signed-off-by: Michal Simek --- .../firmware/xilinx/xlnx,zynqmp-firmware.txt | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt new file mode 100644 index 000000000000..1b431d9bbe44 --- /dev/null +++ b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt @@ -0,0 +1,29 @@ +----------------------------------------------------------------- +Device Tree Bindings for the Xilinx Zynq MPSoC Firmware Interface +----------------------------------------------------------------- + +The zynqmp-firmware node describes the interface to platform firmware. +ZynqMP has an interface to communicate with secure firmware. Firmware +driver provides an interface to firmware APIs. Interface APIs can be +used by any driver to communicate to PMUFW(Platform Management Unit). +These requests include clock management, pin control, device control, +power management service, FPGA service and other platform management +services. + +Required properties: + - compatible: Must contain: "xlnx,zynqmp-firmware" + - method: The method of calling the PM-API firmware layer. + Permitted values are: + - "smc" : SMC #0, following the SMCCC + - "hvc" : HVC #0, following the SMCCC + +------- +Example +------- + +firmware { + zynqmp_firmware: zynqmp-firmware { + compatible = "xlnx,zynqmp-firmware"; + method = "smc"; + }; +}; -- cgit v1.2.3 From c00e7c07496827dbd1295798c12eb9733ed6e3b1 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 22 Sep 2018 17:09:59 +0200 Subject: dt-bindings: add vendor prefix for "Endless Mobile, Inc." Endless Mobile, Inc. started selling (small) computers in 2015. Signed-off-by: Martin Blumenstingl Reviewed-by: Rob Herring Signed-off-by: Kevin Hilman --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 2c3fc512e746..1c63d2c2d48f 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -114,6 +114,7 @@ elan Elan Microelectronic Corp. embest Shenzhen Embest Technology Co., Ltd. emmicro EM Microelectronic emtrion emtrion GmbH +endless Endless Mobile, Inc. energymicro Silicon Laboratories (formerly Energy Micro AS) engicam Engicam S.r.l. epcos EPCOS AG -- cgit v1.2.3 From 4265e28711a8b4b97471d1d3f496b8e10f544a95 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 22 Sep 2018 17:10:00 +0200 Subject: dt-bindings: arm: amlogic: Add the Endless Mobile Endless Mini (EC-100) Add bindings documentation for the Endless Mini (EC-100) from Endless Mobile. Signed-off-by: Martin Blumenstingl Reviewed-by: Rob Herring Signed-off-by: Kevin Hilman --- Documentation/devicetree/bindings/arm/amlogic.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index b5c2b5c35766..2c2eee206736 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -63,6 +63,7 @@ Board compatible values (alphabetically, grouped by SoC): - "minix,neo-x8" (Meson8) + - "endless,ec100" (Meson8b) - "hardkernel,odroid-c1" (Meson8b) - "tronfy,mxq" (Meson8b) -- cgit v1.2.3 From 28c9aa152134521a9dfb56ad02c46f7b99cad3b2 Mon Sep 17 00:00:00 2001 From: Jianxin Pan Date: Fri, 21 Sep 2018 16:34:40 +0800 Subject: dt-bindings: arm: amlogic: Add Meson G12A binding Introduce new bindings for the Meson G12A SoC Signed-off-by: Jianxin Pan Reviewed-by: Rob Herring Reviewed-by: Jerome Brunet Reviewed-by: Neil Armstrong Signed-off-by: Kevin Hilman --- Documentation/devicetree/bindings/arm/amlogic.txt | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index b5c2b5c35766..cf4bbc7ce961 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -57,6 +57,10 @@ Boards with the Amlogic Meson AXG A113D SoC shall have the following properties: Required root node property: compatible: "amlogic,a113d", "amlogic,meson-axg"; +Boards with the Amlogic Meson G12A S905D2 SoC shall have the following properties: + Required root node property: + compatible: "amlogic,g12a"; + Board compatible values (alphabetically, grouped by SoC): - "geniatech,atv1200" (Meson6) @@ -101,6 +105,8 @@ Board compatible values (alphabetically, grouped by SoC): - "amlogic,s400" (Meson axg a113d) + - "amlogic,u200" (Meson g12a s905d2) + Amlogic Meson Firmware registers Interface ------------------------------------------ -- cgit v1.2.3 From e4f3fb4909677c33f97a871af56b9115f3e178b4 Mon Sep 17 00:00:00 2001 From: Akash Gajjar Date: Wed, 26 Sep 2018 11:54:57 +0530 Subject: arm64: dts: rockchip: add initial dts support for Rockpro64 Rockpro64 is a rockchip RK3399 based board from pine64.org. This patch adds basic device node support for Rockpro64 board and make it able to bring up. Peripheral Works - Sdcard - USB 2.0, 3.0 - Leds - Ethernet - Debug console Not working: - USB Type-C Signed-off-by: Akash Gajjar Acked-by: Deepak Das Reviewed-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 + arch/arm64/boot/dts/rockchip/Makefile | 1 + arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 692 +++++++++++++++++++++ 3 files changed, 697 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 6bb80f2b7c5d..0b7e699628d6 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -168,6 +168,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "pine64,rock64", "rockchip,rk3328"; +- Pine64 RockPro64 board: + Required root node properties: + - compatible = "pine64,rockpro64", "rockchip,rk3399"; + - Rockchip PX3 Evaluation board: Required root node properties: - compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 357ff11c791d..49042c477870 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -17,5 +17,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts new file mode 100644 index 000000000000..1d35f5406b5e --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts @@ -0,0 +1,692 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * Copyright (c) 2018 Akash Gajjar + */ + +/dts-v1/; +#include +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Pine64 RockPro64"; + compatible = "pine64,rockpro64", "rockchip,rk3399"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn>; + + power { + debounce-interval = <100>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO Key Power"; + linux,code = ; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&work_led_gpio>, <&diy_led_gpio>; + + work-led { + label = "work"; + default-state = "on"; + gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + diy-led { + label = "diy"; + default-state = "off"; + gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + /* switched by pmic_sleep */ + vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8>; + }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pwr_en>; + regulator-name = "vcc3v3_pcie"; + regulator-always-on; + regulator-boot-on; + vin-supply = <&dc_12v>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */ + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc5v0_typec: vcc5v0-typec-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_typec_en>; + regulator-name = "vcc5v0_typec"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc_sys>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sys>; + vcc10-supply = <&vcc_sys>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc2v8_dvp: LDO_REG2 { + regulator-name = "vcc2v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: vcc_lan: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <0>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + i2c-scl-rising-time-ns = <300>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c4 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + fusb0: typec-portc@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio1>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&fusb0_int>; + vbus-supply = <&vcc5v0_typec>; + status = "okay"; + }; +}; + +&i2s0 { + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + status = "okay"; +}; + +&i2s1 { + rockchip,playback-channels = <2>; + rockchip,capture-channels = <2>; + status = "okay"; +}; + +&i2s2 { + status = "okay"; +}; + +&io_domains { + status = "okay"; + + bt656-supply = <&vcc1v8_dvp>; + audio-supply = <&vcca1v8_codec>; + sdmmc-supply = <&vcc_sdio>; + gpio1830-supply = <&vcc_3v0>; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwrbtn: pwrbtn { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + fusb302x { + fusb0_int: fusb0-int { + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + work_led_gpio: work_led-gpio { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + diy_led_gpio: diy_led-gpio { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + lcd-panel { + lcd_panel_reset: lcd-panel-reset { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pcie { + pcie_pwr_en: pcie-pwr-en { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb-typec { + vcc5v0_typec_en: vcc5v0_typec_en { + rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&tcphy0 { + status = "okay"; +}; + +&tcphy1 { + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; + dr_mode = "otg"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; -- cgit v1.2.3 From 186b45657b244ce865e01b65d73868a48252e1ff Mon Sep 17 00:00:00 2001 From: David Summers Date: Sun, 23 Sep 2018 13:38:07 +0200 Subject: ARM: dts: rockchip: add rk3288-based Tinker board S Add the actual dts for the tinker board S, which brings its own emmc device, not therefore not requiring an sd-card to boot. Signed-off-by: David Summers Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 ++++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/rk3288-tinker-s.dts | 26 ++++++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 arch/arm/boot/dts/rk3288-tinker-s.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index acfd3c773dd0..037ce94c3a73 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -13,6 +13,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "asus,rk3288-tinker", "rockchip,rk3288"; +- Asus Tinker board S + Required root node properties: + - compatible = "asus,rk3288-tinker-s", "rockchip,rk3288"; + - Kylin RK3036 board: Required root node properties: - compatible = "rockchip,kylin-rk3036", "rockchip,rk3036"; diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b5bd3de87c33..dc86080c60e3 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -864,6 +864,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3288-r89.dtb \ rk3288-rock2-square.dtb \ rk3288-tinker.dtb \ + rk3288-tinker-s.dtb \ rk3288-veyron-brain.dtb \ rk3288-veyron-jaq.dtb \ rk3288-veyron-jerry.dtb \ diff --git a/arch/arm/boot/dts/rk3288-tinker-s.dts b/arch/arm/boot/dts/rk3288-tinker-s.dts new file mode 100644 index 000000000000..37093922b482 --- /dev/null +++ b/arch/arm/boot/dts/rk3288-tinker-s.dts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rk3288-tinker.dtsi" + +/ { + model = "Rockchip RK3288 Asus Tinker Board S"; + compatible = "asus,rk3288-tinker-s", "rockchip,rk3288"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; + max-frequency = <150000000>; + mmc-hs200-1_8v; + mmc-ddr-1_8v; + status = "okay"; +}; -- cgit v1.2.3 From b0fa0105b496abf6c51bf79abf490ea4e0ee9855 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Fri, 31 Aug 2018 18:38:08 +0200 Subject: dt-bindings: add broadcom (formerly plx technology) vendor prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLX Technology meanwhile got bought by Broadcom Corporation but the vendor prefix plx is still used in 8 current device trees. This silences the following checkpatch.pl warning: WARNING: DT compatible string vendor "plx" appears un-documented -- check ./Documentation/devicetree/bindings/vendor-prefixes.txt Signed-off-by: Marcel Ziswiler Reviewed-by: Andreas Färber Acked-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 2c3fc512e746..e40312dcba7d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -297,6 +297,7 @@ pine64 Pine64 pixcir PIXCIR MICROELECTRONICS Co., Ltd plathome Plat'Home Co., Ltd. plda PLDA +plx Broadcom Corporation (formerly PLX Technology) portwell Portwell Inc. poslab Poslab Technology Co., Ltd. powervr PowerVR (deprecated, use img) -- cgit v1.2.3 From b57d6b996ebe25e7f1e92de0abc7a2da42005454 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Fri, 31 Aug 2018 18:38:16 +0200 Subject: ARM: tegra: apalis_t30: support v1.1 hardware revision Support the V1.1 hardware revisions with the following change: Changed power rail for MMC1 interface to a 3.3V/1.8V switchable rail in order to be able to run UHS SD cards in ultra high speed 1.8V mode. [ 207.502011] mmc2: host does not support reading read-only switch, assuming write-enable [ 207.517011] mmc2: new ultra high speed SDR104 SDHC card at address aaaa [ 207.534190] mmcblk2: mmc2:aaaa SE32G 29.7 GiB [ 207.545096] mmcblk2: p1 root@apalis-t30:~# cat /sys/kernel/debug/mmc2/ios clock: 208000000 Hz actual clock: 204000000 Hz vdd: 21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select: 0 (don't care) power mode: 2 (on) bus width: 2 (4 bits) timing spec: 6 (sd uhs SDR104) signal voltage: 1 (1.80 V) driver type: 0 (driver type B) root@apalis-t30:~# hdparm -t /dev/mmcblk2 /dev/mmcblk2: Timing buffered disk reads: 256 MB in 3.02 seconds = 84.71 MB/sec Signed-off-by: Marcel Ziswiler Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.txt | 2 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts | 266 +++++ arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi | 1189 +++++++++++++++++++++++ arch/arm/boot/dts/tegra30-apalis.dtsi | 3 +- 5 files changed, 1459 insertions(+), 2 deletions(-) create mode 100644 arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts create mode 100644 arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index 32f62bb7006d..1073a5e66122 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -47,6 +47,8 @@ board-specific compatible values: nvidia,ventana toradex,apalis_t30 toradex,apalis_t30-eval + toradex,apalis_t30-v1.1 + toradex,apalis_t30-v1.1-eval toradex,apalis-tk1 toradex,apalis-tk1-eval toradex,colibri_t20-512 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b5bd3de87c33..9d6d7790d627 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1071,6 +1071,7 @@ dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \ tegra20-ventana.dtb dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \ tegra30-apalis-eval.dtb \ + tegra30-apalis-v1.1-eval.dtb \ tegra30-beaver.dtb \ tegra30-cardhu-a02.dtb \ tegra30-cardhu-a04.dtb \ diff --git a/arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts b/arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts new file mode 100644 index 000000000000..0be50e881684 --- /dev/null +++ b/arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/dts-v1/; + +#include +#include "tegra30-apalis-v1.1.dtsi" + +/ { + model = "Toradex Apalis T30 on Apalis Evaluation Board"; + compatible = "toradex,apalis_t30-v1.1-eval", "toradex,apalis_t30-eval", + "toradex,apalis_t30-v1.1", "toradex,apalis_t30", + "nvidia,tegra30"; + + aliases { + rtc0 = "/i2c@7000c000/rtc@68"; + rtc1 = "/i2c@7000d000/pmic@2d"; + rtc2 = "/rtc@7000e000"; + serial0 = &uarta; + serial1 = &uartb; + serial2 = &uartc; + serial3 = &uartd; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + pcie@3000 { + pci@1,0 { + status = "okay"; + }; + + pci@2,0 { + status = "okay"; + }; + }; + + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + nvidia,panel = <&panel>; + }; + }; + + hdmi@54280000 { + status = "okay"; + hdmi-supply = <®_5v0>; + }; + }; + + /* Apalis UART1 */ + serial@70006000 { + status = "okay"; + }; + + /* Apalis UART2 */ + serial@70006040 { + status = "okay"; + }; + + /* Apalis UART3 */ + serial@70006200 { + status = "okay"; + }; + + /* Apalis UART4 */ + serial@70006300 { + status = "okay"; + }; + + pwm@7000a000 { + status = "okay"; + }; + + /* + * GEN1_I2C: I2C1_SDA/SCL on MXM3 pin 209/211 (e.g. RTC on carrier + * board) + */ + i2c@7000c000 { + status = "okay"; + clock-frequency = <400000>; + + pcie-switch@58 { + compatible = "plx,pex8605"; + reg = <0x58>; + }; + + /* M41T0M6 real time clock on carrier board */ + rtc@68 { + compatible = "st,m41t0"; + reg = <0x68>; + }; + }; + + /* GEN2_I2C: unused */ + + /* + * CAM_I2C: I2C3_SDA/SCL on MXM3 pin 201/203 (e.g. camera sensor on + * carrier board) + */ + i2c@7000c500 { + status = "okay"; + clock-frequency = <400000>; + }; + + /* DDC: I2C2_SDA/SCL on MXM3 pin 205/207 (e.g. display EDID) */ + i2c@7000c700 { + status = "okay"; + }; + + /* SPI1: Apalis SPI1 */ + spi@7000d400 { + status = "okay"; + spi-max-frequency = <25000000>; + }; + + /* SPI5: Apalis SPI2 */ + spi@7000dc00 { + status = "okay"; + spi-max-frequency = <25000000>; + }; + + /* Apalis SD1 */ + sdhci@78000000 { + status = "okay"; + bus-width = <4>; + /* SD1_CD# */ + cd-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_LOW>; + no-1-8-v; + }; + + /* Apalis MMC1 */ + sdhci@78000400 { + status = "okay"; + bus-width = <8>; + /* MMC1_CD# */ + cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>; + vqmmc-supply = <®_vddio_sdmmc3>; + }; + + /* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */ + usb@7d000000 { + status = "okay"; + dr_mode = "otg"; + }; + + usb-phy@7d000000 { + status = "okay"; + vbus-supply = <®_usbo1_vbus>; + }; + + /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */ + usb@7d004000 { + status = "okay"; + }; + + usb-phy@7d004000 { + status = "okay"; + vbus-supply = <®_usbh_vbus>; + }; + + /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */ + usb@7d008000 { + status = "okay"; + }; + + usb-phy@7d008000 { + status = "okay"; + vbus-supply = <®_usbh_vbus>; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <255 231 223 207 191 159 127 0>; + default-brightness-level = <6>; + /* BKL1_ON */ + enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; + power-supply = <®_3v3>; + pwms = <&pwm 0 5000000>; /* BKL1_PWM */ + }; + + gpio-keys { + compatible = "gpio-keys"; + + wakeup { + label = "WAKE1_MICO"; + gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu", "simple-panel"; + backlight = <&backlight>; + power-supply = <®_3v3>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V_SW"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V_SW"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + /* USBO1_EN */ + reg_usbo1_vbus: regulator-usbo1-vbus { + compatible = "regulator-fixed"; + regulator-name = "VCC_USBO1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <®_5v0>; + }; + + /* USBH_EN */ + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + regulator-name = "VCC_USBH(2A|2C|2D|3|4)"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <®_5v0>; + }; + + /* + * 1.8 volt resp. 3.3 volt VDDIO_SDMMC3 depending on + * EN_+3.3_SDMMC3 GPIO + */ + reg_vddio_sdmmc3: regulator-vddio-sdmmc3 { + compatible = "regulator-gpio"; + regulator-name = "VDDIO_SDMMC3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-type = "voltage"; + gpios = <&gpio TEGRA_GPIO(J, 5) GPIO_ACTIVE_HIGH>; + states = <1800000 0x0 + 3300000 0x1>; + startup-delay-us = <100000>; + vin-supply = <&vddio_sdmmc_1v8_reg>; + }; +}; + +&gpio { + /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */ + pex-perst-n { + gpio-hog; + gpios = ; + output-high; + line-name = "PEX_PERST_N"; + }; +}; diff --git a/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi b/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi new file mode 100644 index 000000000000..02f8126481a2 --- /dev/null +++ b/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi @@ -0,0 +1,1189 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +#include "tegra30.dtsi" + +/* + * Toradex Apalis T30 Module Device Tree + * Compatible for Revisions 1GB: V1.1A, V1.1B; 1GB IT: V1.1A, V1.1B; + * 2GB: V1.1A, V1.1B + */ +/ { + memory@80000000 { + reg = <0x80000000 0x40000000>; + }; + + pcie@3000 { + status = "okay"; + avdd-pexa-supply = <&vdd2_reg>; + avdd-pexb-supply = <&vdd2_reg>; + avdd-pex-pll-supply = <&vdd2_reg>; + avdd-plle-supply = <&ldo6_reg>; + hvdd-pex-supply = <®_module_3v3>; + vddio-pex-ctl-supply = <®_module_3v3>; + vdd-pexa-supply = <&vdd2_reg>; + vdd-pexb-supply = <&vdd2_reg>; + + /* Apalis type specific */ + pci@1,0 { + nvidia,num-lanes = <4>; + }; + + /* Apalis PCIe */ + pci@2,0 { + nvidia,num-lanes = <1>; + }; + + /* I210/I211 Gigabit Ethernet Controller (on-module) */ + pci@3,0 { + status = "okay"; + nvidia,num-lanes = <1>; + + pcie@0 { + reg = <0 0 0 0 0>; + local-mac-address = [00 00 00 00 00 00]; + }; + }; + }; + + host1x@50000000 { + hdmi@54280000 { + nvidia,ddc-i2c-bus = <&hdmi_ddc>; + nvidia,hpd-gpio = + <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>; + pll-supply = <®_1v8_avdd_hdmi_pll>; + vdd-supply = <®_3v3_avdd_hdmi>; + }; + }; + + pinmux@70000868 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + /* Analogue Audio (On-module) */ + clk1-out-pw4 { + nvidia,pins = "clk1_out_pw4"; + nvidia,function = "extperiph1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + dap3-fs-pp0 { + nvidia,pins = "dap3_fs_pp0", + "dap3_sclk_pp3", + "dap3_din_pp1", + "dap3_dout_pp2"; + nvidia,function = "i2s2"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis BKL1_ON */ + pv2 { + nvidia,pins = "pv2"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis BKL1_PWM */ + uart3-rts-n-pc0 { + nvidia,pins = "uart3_rts_n_pc0"; + nvidia,function = "pwm0"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* BKL1_PWM_EN#, disable TPS65911 PMIC PWM backlight */ + uart3-cts-n-pa1 { + nvidia,pins = "uart3_cts_n_pa1"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis CAN1 on SPI6 */ + spi2-cs0-n-px3 { + nvidia,pins = "spi2_cs0_n_px3", + "spi2_miso_px1", + "spi2_mosi_px0", + "spi2_sck_px2"; + nvidia,function = "spi6"; + nvidia,pull = ; + nvidia,tristate = ; + }; + /* CAN_INT1 */ + spi2-cs1-n-pw2 { + nvidia,pins = "spi2_cs1_n_pw2"; + nvidia,function = "spi3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis CAN2 on SPI4 */ + gmi-a16-pj7 { + nvidia,pins = "gmi_a16_pj7", + "gmi_a17_pb0", + "gmi_a18_pb1", + "gmi_a19_pk7"; + nvidia,function = "spi4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* CAN_INT2 */ + spi2-cs2-n-pw3 { + nvidia,pins = "spi2_cs2_n_pw3"; + nvidia,function = "spi3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis Digital Audio */ + clk1-req-pee2 { + nvidia,pins = "clk1_req_pee2"; + nvidia,function = "hda"; + nvidia,pull = ; + nvidia,tristate = ; + }; + clk2-out-pw5 { + nvidia,pins = "clk2_out_pw5"; + nvidia,function = "extperiph2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + dap1-fs-pn0 { + nvidia,pins = "dap1_fs_pn0", + "dap1_din_pn1", + "dap1_dout_pn2", + "dap1_sclk_pn3"; + nvidia,function = "hda"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis GPIO */ + kb-col0-pq0 { + nvidia,pins = "kb_col0_pq0", + "kb_col1_pq1", + "kb_row10_ps2", + "kb_row11_ps3", + "kb_row12_ps4", + "kb_row13_ps5", + "kb_row14_ps6", + "kb_row15_ps7"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* Multiplexed and therefore disabled */ + owr { + nvidia,pins = "owr"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis HDMI1 */ + hdmi-cec-pee3 { + nvidia,pins = "hdmi_cec_pee3"; + nvidia,function = "cec"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + hdmi-int-pn7 { + nvidia,pins = "hdmi_int_pn7"; + nvidia,function = "hdmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis I2C1 */ + gen1-i2c-scl-pc4 { + nvidia,pins = "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5"; + nvidia,function = "i2c1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + + /* Apalis I2C2 (DDC) */ + ddc-scl-pv4 { + nvidia,pins = "ddc_scl_pv4", + "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis I2C3 (CAM) */ + cam-i2c-scl-pbb1 { + nvidia,pins = "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + + /* Apalis LCD1 */ + lcd-d0-pe0 { + nvidia,pins = "lcd_d0_pe0", + "lcd_d1_pe1", + "lcd_d2_pe2", + "lcd_d3_pe3", + "lcd_d4_pe4", + "lcd_d5_pe5", + "lcd_d6_pe6", + "lcd_d7_pe7", + "lcd_d8_pf0", + "lcd_d9_pf1", + "lcd_d10_pf2", + "lcd_d11_pf3", + "lcd_d12_pf4", + "lcd_d13_pf5", + "lcd_d14_pf6", + "lcd_d15_pf7", + "lcd_d16_pm0", + "lcd_d17_pm1", + "lcd_d18_pm2", + "lcd_d19_pm3", + "lcd_d20_pm4", + "lcd_d21_pm5", + "lcd_d22_pm6", + "lcd_d23_pm7", + "lcd_de_pj1", + "lcd_hsync_pj3", + "lcd_pclk_pb3", + "lcd_vsync_pj4"; + nvidia,function = "displaya"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis MMC1 */ + sdmmc3-clk-pa6 { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3-dat0-pb7 { + nvidia,pins = "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "sdmmc3_dat4_pd1", + "sdmmc3_dat5_pd0", + "sdmmc3_dat6_pd3", + "sdmmc3_dat7_pd4"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + }; + /* Apalis MMC1_CD# */ + pv3 { + nvidia,pins = "pv3"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis Parallel Camera */ + cam-mclk-pcc0 { + nvidia,pins = "cam_mclk_pcc0"; + nvidia,function = "vi_alt3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + vi-vsync-pd6 { + nvidia,pins = "vi_d0_pt4", + "vi_d1_pd5", + "vi_d2_pl0", + "vi_d3_pl1", + "vi_d4_pl2", + "vi_d5_pl3", + "vi_d6_pl4", + "vi_d7_pl5", + "vi_d8_pl6", + "vi_d9_pl7", + "vi_d10_pt2", + "vi_d11_pt3", + "vi_hsync_pd7", + "vi_pclk_pt0", + "vi_vsync_pd6"; + nvidia,function = "vi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* Multiplexed and therefore disabled */ + kb-col2-pq2 { + nvidia,pins = "kb_col2_pq2", + "kb_col3_pq3", + "kb_col4_pq4", + "kb_row4_pr4"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb-row0-pr0 { + nvidia,pins = "kb_row0_pr0", + "kb_row1_pr1", + "kb_row2_pr2", + "kb_row3_pr3"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb-row5-pr5 { + nvidia,pins = "kb_row5_pr5", + "kb_row6_pr6", + "kb_row7_pr7"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* + * VI level-shifter direction + * (pull-down => default direction input) + */ + vi-mclk-pt1 { + nvidia,pins = "vi_mclk_pt1"; + nvidia,function = "vi_alt3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis PWM1 */ + pu6 { + nvidia,pins = "pu6"; + nvidia,function = "pwm3"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis PWM2 */ + pu5 { + nvidia,pins = "pu5"; + nvidia,function = "pwm2"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis PWM3 */ + pu4 { + nvidia,pins = "pu4"; + nvidia,function = "pwm1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis PWM4 */ + pu3 { + nvidia,pins = "pu3"; + nvidia,function = "pwm0"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis RESET_MOCI# */ + gmi-rst-n-pi4 { + nvidia,pins = "gmi_rst_n_pi4"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis SATA1_ACT# */ + pex-l0-prsnt-n-pdd0 { + nvidia,pins = "pex_l0_prsnt_n_pdd0"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis SD1 */ + sdmmc1-clk-pz0 { + nvidia,pins = "sdmmc1_clk_pz0"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc1-cmd-pz1 { + nvidia,pins = "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + /* Apalis SD1_CD# */ + clk2-req-pcc5 { + nvidia,pins = "clk2_req_pcc5"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis SPDIF1 */ + spdif-out-pk5 { + nvidia,pins = "spdif_out_pk5", + "spdif_in_pk6"; + nvidia,function = "spdif"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis SPI1 */ + spi1-sck-px5 { + nvidia,pins = "spi1_sck_px5", + "spi1_mosi_px4", + "spi1_miso_px7", + "spi1_cs0_n_px6"; + nvidia,function = "spi1"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis SPI2 */ + lcd-sck-pz4 { + nvidia,pins = "lcd_sck_pz4", + "lcd_sdout_pn5", + "lcd_sdin_pz2", + "lcd_cs0_n_pn4"; + nvidia,function = "spi5"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* + * Apalis TS (Low-speed type specific) + * pins may be used as GPIOs + */ + kb-col5-pq5 { + nvidia,pins = "kb_col5_pq5"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb-col6-pq6 { + nvidia,pins = "kb_col6_pq6", + "kb_col7_pq7", + "kb_row8_ps0", + "kb_row9_ps1"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis UART1 */ + ulpi-data0 { + nvidia,pins = "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0"; + nvidia,function = "uarta"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis UART2 */ + ulpi-clk-py0 { + nvidia,pins = "ulpi_clk_py0", + "ulpi_dir_py1", + "ulpi_nxt_py2", + "ulpi_stp_py3"; + nvidia,function = "uartd"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis UART3 */ + uart2-rxd-pc3 { + nvidia,pins = "uart2_rxd_pc3", + "uart2_txd_pc2"; + nvidia,function = "uartb"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis UART4 */ + uart3-rxd-pw7 { + nvidia,pins = "uart3_rxd_pw7", + "uart3_txd_pw6"; + nvidia,function = "uartc"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis USBH_EN */ + pex-l0-rst-n-pdd1 { + nvidia,pins = "pex_l0_rst_n_pdd1"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis USBH_OC# */ + pex-l0-clkreq-n-pdd2 { + nvidia,pins = "pex_l0_clkreq_n_pdd2"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis USBO1_EN */ + gen2-i2c-scl-pt5 { + nvidia,pins = "gen2_i2c_scl_pt5"; + nvidia,function = "rsvd4"; + nvidia,open-drain = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + + /* Apalis USBO1_OC# */ + gen2-i2c-sda-pt6 { + nvidia,pins = "gen2_i2c_sda_pt6"; + nvidia,function = "rsvd4"; + nvidia,open-drain = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis VGA1 not supported and therefore disabled */ + crt-hsync-pv6 { + nvidia,pins = "crt_hsync_pv6", + "crt_vsync_pv7"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Apalis WAKE1_MICO */ + pv1 { + nvidia,pins = "pv1"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* eMMC (On-module) */ + sdmmc4-clk-pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4", + "sdmmc4_cmd_pt7", + "sdmmc4_rst_n_pcc3"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + sdmmc4-dat0-paa0 { + nvidia,pins = "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* EN_+3.3_SDMMC3 */ + uart2-cts-n-pj5 { + nvidia,pins = "uart2_cts_n_pj5"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* LAN i210/i211 DEV_OFF_N, PE_RST_N (On-module) */ + pex-l2-prsnt-n-pdd7 { + nvidia,pins = "pex_l2_prsnt_n_pdd7", + "pex_l2_rst_n_pcc6"; + nvidia,function = "pcie"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* LAN i210/i211 PE_WAKE_N, SDP3 (On-module) */ + pex-wake-n-pdd3 { + nvidia,pins = "pex_wake_n_pdd3", + "pex_l2_clkreq_n_pcc7"; + nvidia,function = "pcie"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + /* LAN i210/i211 SMB_ALERT_N (On-module) */ + sys-clk-req-pz5 { + nvidia,pins = "sys_clk_req_pz5"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* LVDS Transceiver Configuration */ + pbb0 { + nvidia,pins = "pbb0", + "pbb7", + "pcc1", + "pcc2"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + pbb3 { + nvidia,pins = "pbb3", + "pbb4", + "pbb5", + "pbb6"; + nvidia,function = "displayb"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Not connected and therefore disabled */ + clk-32k-out-pa0 { + nvidia,pins = "clk3_out_pee0", + "clk3_req_pee1", + "clk_32k_out_pa0", + "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + dap2-fs-pa2 { + nvidia,pins = "dap2_fs_pa2", + "dap2_sclk_pa3", + "dap2_din_pa4", + "dap2_dout_pa5", + "lcd_dc0_pn6", + "lcd_m1_pw1", + "lcd_pwr1_pc1", + "pex_l1_clkreq_n_pdd6", + "pex_l1_prsnt_n_pdd4", + "pex_l1_rst_n_pdd5"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gmi-ad0-pg0 { + nvidia,pins = "gmi_ad0_pg0", + "gmi_ad2_pg2", + "gmi_ad3_pg3", + "gmi_ad4_pg4", + "gmi_ad5_pg5", + "gmi_ad6_pg6", + "gmi_ad7_pg7", + "gmi_ad8_ph0", + "gmi_ad9_ph1", + "gmi_ad10_ph2", + "gmi_ad11_ph3", + "gmi_ad12_ph4", + "gmi_ad13_ph5", + "gmi_ad14_ph6", + "gmi_ad15_ph7", + "gmi_adv_n_pk0", + "gmi_clk_pk1", + "gmi_cs4_n_pk2", + "gmi_cs2_n_pk3", + "gmi_dqs_pi2", + "gmi_iordy_pi5", + "gmi_oe_n_pi1", + "gmi_wait_pi7", + "gmi_wr_n_pi0", + "lcd_cs1_n_pw0", + "pu0", + "pu1", + "pu2"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gmi-cs0-n-pj0 { + nvidia,pins = "gmi_cs0_n_pj0", + "gmi_cs1_n_pj2", + "gmi_cs3_n_pk4"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gmi-cs6-n-pi3 { + nvidia,pins = "gmi_cs6_n_pi3"; + nvidia,function = "sata"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + gmi-cs7-n-pi6 { + nvidia,pins = "gmi_cs7_n_pi6"; + nvidia,function = "gmi_alt"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + lcd-pwr0-pb2 { + nvidia,pins = "lcd_pwr0_pb2", + "lcd_pwr2_pc6", + "lcd_wr_n_pz3"; + nvidia,function = "hdcp"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + uart2-rts-n-pj6 { + nvidia,pins = "uart2_rts_n_pj6"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Power I2C (On-module) */ + pwr-i2c-scl-pz6 { + nvidia,pins = "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + + /* + * THERMD_ALERT#, unlatched I2C address pin of LM95245 + * temperature sensor therefore requires disabling for + * now + */ + lcd-dc1-pd2 { + nvidia,pins = "lcd_dc1_pd2"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* TOUCH_PEN_INT# (On-module) */ + pv0 { + nvidia,pins = "pv0"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + }; + + serial@70006040 { + compatible = "nvidia,tegra30-hsuart"; + }; + + serial@70006200 { + compatible = "nvidia,tegra30-hsuart"; + }; + + serial@70006300 { + compatible = "nvidia,tegra30-hsuart"; + }; + + hdmi_ddc: i2c@7000c700 { + clock-frequency = <10000>; + }; + + /* + * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and + * touch screen controller + */ + i2c@7000d000 { + status = "okay"; + clock-frequency = <100000>; + + /* SGTL5000 audio codec */ + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_module_3v3_audio>; + VDDD-supply = <®_1v8_vio>; + VDDIO-supply = <®_module_3v3>; + clocks = <&tegra_car TEGRA30_CLK_EXTERN1>; + }; + + pmic: pmic@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + vcc1-supply = <®_module_3v3>; + vcc2-supply = <®_module_3v3>; + vcc3-supply = <®_1v8_vio>; + vcc4-supply = <®_module_3v3>; + vcc5-supply = <®_module_3v3>; + vcc6-supply = <®_1v8_vio>; + vcc7-supply = <®_5v0_charge_pump>; + vccio-supply = <®_module_3v3>; + + regulators { + vdd1_reg: vdd1 { + regulator-name = "+V1.35_VDDIO_DDR"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + }; + + vdd2_reg: vdd2 { + regulator-name = "+V1.05"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + }; + + vddctrl_reg: vddctrl { + regulator-name = "+V1.0_VDD_CPU"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + regulator-always-on; + }; + + reg_1v8_vio: vio { + regulator-name = "+V1.8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + /* + * 1.8 volt +VDDIO_SDMMC3 in case EN_+3.3_SDMMC3 + * is off + */ + vddio_sdmmc_1v8_reg: ldo1 { + regulator-name = "+VDDIO_SDMMC3_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + /* + * EN_+V3.3 switching via FET: + * +V3.3_AUDIO_AVDD_S, +V3.3 + * see also +V3.3 fixed supply + */ + ldo2_reg: ldo2 { + regulator-name = "EN_+V3.3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo3_reg: ldo3 { + regulator-name = "+V1.2_CSI"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo4_reg: ldo4 { + regulator-name = "+V1.2_VDD_RTC"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + /* + * +V2.8_AVDD_VDAC: + * only required for (unsupported) analog RGB + */ + ldo5_reg: ldo5 { + regulator-name = "+V2.8_AVDD_VDAC"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + /* + * +V1.05_AVDD_PLLE: avdd_plle should be 1.05V + * but LDO6 can't set voltage in 50mV + * granularity + */ + ldo6_reg: ldo6 { + regulator-name = "+V1.05_AVDD_PLLE"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo7_reg: ldo7 { + regulator-name = "+V1.2_AVDD_PLL"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo8_reg: ldo8 { + regulator-name = "+V1.0_VDD_DDR_HS"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + }; + }; + + /* STMPE811 touch screen controller */ + touchscreen@41 { + compatible = "st,stmpe811"; + reg = <0x41>; + irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + id = <0>; + blocks = <0x5>; + irq-trigger = <0x1>; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + /* 3.25 MHz ADC clock speed */ + st,adc-freq = <1>; + /* 8 sample average control */ + st,ave-ctrl = <3>; + /* 7 length fractional part in z */ + st,fraction-z = <7>; + /* + * 50 mA typical 80 mA max touchscreen drivers + * current limit value + */ + st,i-drive = <1>; + /* 12-bit ADC */ + st,mod-12b = <1>; + /* internal ADC reference */ + st,ref-sel = <0>; + /* ADC converstion time: 80 clocks */ + st,sample-time = <4>; + /* 1 ms panel driver settling time */ + st,settling = <3>; + /* 5 ms touch detect interrupt delay */ + st,touch-det-delay = <5>; + }; + }; + + /* + * LM95245 temperature sensor + * Note: OVERT1# directly connected to TPS65911 PMIC PWRDN + */ + temp-sensor@4c { + compatible = "national,lm95245"; + reg = <0x4c>; + }; + + /* SW: +V1.2_VDD_CORE */ + regulator@60 { + compatible = "ti,tps62362"; + reg = <0x60>; + + regulator-name = "tps62362-vout"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-low; + /* VSEL1: EN_CORE_DVFS_N low for DVFS */ + ti,vsel1-state-low; + }; + }; + + /* SPI4: CAN2 */ + spi@7000da00 { + status = "okay"; + spi-max-frequency = <10000000>; + + can@1 { + compatible = "microchip,mcp2515"; + reg = <1>; + clocks = <&clk16m>; + interrupt-parent = <&gpio>; + interrupts = ; + spi-max-frequency = <10000000>; + }; + }; + + /* SPI6: CAN1 */ + spi@7000de00 { + status = "okay"; + spi-max-frequency = <10000000>; + + can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + clocks = <&clk16m>; + interrupt-parent = <&gpio>; + interrupts = ; + spi-max-frequency = <10000000>; + }; + }; + + pmc@7000e400 { + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <0>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + + /* Set DEV_OFF bit in DCDC control register of TPS65911 PMIC */ + i2c-thermtrip { + nvidia,i2c-controller-id = <4>; + nvidia,bus-addr = <0x2d>; + nvidia,reg-addr = <0x3f>; + nvidia,reg-data = <0x1>; + }; + }; + + hda@70030000 { + status = "okay"; + }; + + ahub@70080000 { + i2s@70080500 { + status = "okay"; + }; + }; + + /* eMMC */ + sdhci@78000600 { + status = "okay"; + bus-width = <8>; + non-removable; + vmmc-supply = <®_module_3v3>; /* VCC */ + vqmmc-supply = <®_1v8_vio>; /* VCCQ */ + mmc-ddr-1_8v; + }; + + clk32k_in: xtal1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + clk16m: osc4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16000000>; + }; + + reg_1v8_avdd_hdmi_pll: regulator-1v8-avdd-hdmi-pll { + compatible = "regulator-fixed"; + regulator-name = "+V1.8_AVDD_HDMI_PLL"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + enable-active-high; + gpio = <&pmic 6 GPIO_ACTIVE_HIGH>; + vin-supply = <®_1v8_vio>; + }; + + reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi { + compatible = "regulator-fixed"; + regulator-name = "+V3.3_AVDD_HDMI"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&pmic 6 GPIO_ACTIVE_HIGH>; + vin-supply = <®_module_3v3>; + }; + + reg_5v0_charge_pump: regulator-5v0-charge-pump { + compatible = "regulator-fixed"; + regulator-name = "+V5.0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_module_3v3: regulator-module-3v3 { + compatible = "regulator-fixed"; + regulator-name = "+V3.3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_module_3v3_audio: regulator-module-3v3-audio { + compatible = "regulator-fixed"; + regulator-name = "+V3.3_AUDIO_AVDD_S"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + sound { + compatible = "toradex,tegra-audio-sgtl5000-apalis_t30", + "nvidia,tegra-audio-sgtl5000"; + nvidia,model = "Toradex Apalis T30"; + nvidia,audio-routing = + "Headphone Jack", "HP_OUT", + "LINE_IN", "Line In Jack", + "MIC_IN", "Mic Jack"; + nvidia,i2s-controller = <&tegra_i2s2>; + nvidia,audio-codec = <&sgtl5000>; + clocks = <&tegra_car TEGRA30_CLK_PLL_A>, + <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA30_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; + }; +}; diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi index 23cecd327172..7f112f192fe9 100644 --- a/arch/arm/boot/dts/tegra30-apalis.dtsi +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi @@ -3,8 +3,7 @@ /* * Toradex Apalis T30 Module Device Tree - * Compatible for Revisions 1GB: V1.0A, V1.1A; 1GB IT: V1.1A; - * 2GB: V1.0B, V1.0C, V1.0E, V1.1A + * Compatible for Revisions 1GB: V1.0A; 2GB: V1.0B, V1.0C, V1.0E */ / { memory@80000000 { -- cgit v1.2.3 From a052d2b67f00dfc6181d7dea6ff911bc7175f52a Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sat, 1 Sep 2018 15:04:56 +0200 Subject: ARM: tegra: apalis-tk1: add toradex, apalis-tk1-v1.2 compatible Add toradex,apalis-tk1-v1.2 compatible. Signed-off-by: Marcel Ziswiler Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.txt | 2 ++ arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index 1073a5e66122..1c90cb32da19 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -51,6 +51,8 @@ board-specific compatible values: toradex,apalis_t30-v1.1-eval toradex,apalis-tk1 toradex,apalis-tk1-eval + toradex,apalis-tk1-v1.2 + toradex,apalis-tk1-v1.2-eval toradex,colibri_t20-512 toradex,colibri_t30 toradex,colibri_t30-eval-v3 diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts index aafaf2c3e195..89783fe76f65 100644 --- a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts @@ -11,7 +11,8 @@ / { model = "Toradex Apalis TK1 on Apalis Evaluation Board"; compatible = "toradex,apalis-tk1-v1.2-eval", "toradex,apalis-tk1-eval", - "toradex,apalis-tk1", "nvidia,tegra124"; + "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1", + "nvidia,tegra124"; aliases { rtc0 = "/i2c@7000c000/rtc@68"; -- cgit v1.2.3 From 4f135281b32362a672fee7ddb5a356e600fb9ce4 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sun, 2 Sep 2018 12:08:57 +0200 Subject: ARM: tegra: colibri_t20: simplify model and compatible properties Simplify model and compatible by dropping the 256/512 MB from the model and -512 from the compatible properties to be more in-line with all our other device trees. Signed-off-by: Marcel Ziswiler Reviewed-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.txt | 2 +- arch/arm/boot/dts/tegra20-colibri-iris.dts | 4 ++-- arch/arm/boot/dts/tegra20-colibri.dtsi | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index 1c90cb32da19..5e1b0b30ece2 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -53,7 +53,7 @@ board-specific compatible values: toradex,apalis-tk1-eval toradex,apalis-tk1-v1.2 toradex,apalis-tk1-v1.2-eval - toradex,colibri_t20-512 + toradex,colibri_t20 toradex,colibri_t30 toradex,colibri_t30-eval-v3 toradex,iris diff --git a/arch/arm/boot/dts/tegra20-colibri-iris.dts b/arch/arm/boot/dts/tegra20-colibri-iris.dts index 1583d5118302..cd47ac5b528f 100644 --- a/arch/arm/boot/dts/tegra20-colibri-iris.dts +++ b/arch/arm/boot/dts/tegra20-colibri-iris.dts @@ -5,8 +5,8 @@ #include "tegra20-colibri.dtsi" / { - model = "Toradex Colibri T20 256/512 MB on Iris"; - compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20"; + model = "Toradex Colibri T20 on Iris"; + compatible = "toradex,iris", "toradex,colibri_t20", "nvidia,tegra20"; aliases { rtc0 = "/i2c@7000c000/rtc@68"; diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi index ea785f65c89f..53e06f31dbea 100644 --- a/arch/arm/boot/dts/tegra20-colibri.dtsi +++ b/arch/arm/boot/dts/tegra20-colibri.dtsi @@ -8,8 +8,8 @@ * Colibri T20 512MB IT V1.2A */ / { - model = "Toradex Colibri T20 256/512 MB"; - compatible = "toradex,colibri_t20-512", "nvidia,tegra20"; + model = "Toradex Colibri T20"; + compatible = "toradex,colibri_t20", "nvidia,tegra20"; memory@0 { /* -- cgit v1.2.3 From a7867ac8a11465be32324d896d81426f534b9a61 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sun, 2 Sep 2018 12:08:58 +0200 Subject: ARM: tegra: colibri_t20: iris: simplify model and compatible properties Simplify model and compatible by dropping the 256/512 MB from the model, -512 from the compatible and rename that property from toradex,iris to toradex,colibri_t20-iris to be more in-line with all our other device trees. Signed-off-by: Marcel Ziswiler Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.txt | 2 +- arch/arm/boot/dts/tegra20-colibri-iris.dts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index 5e1b0b30ece2..0909122a2bee 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -54,9 +54,9 @@ board-specific compatible values: toradex,apalis-tk1-v1.2 toradex,apalis-tk1-v1.2-eval toradex,colibri_t20 + toradex,colibri_t20-iris toradex,colibri_t30 toradex,colibri_t30-eval-v3 - toradex,iris Trusted Foundations ------------------------------------------- diff --git a/arch/arm/boot/dts/tegra20-colibri-iris.dts b/arch/arm/boot/dts/tegra20-colibri-iris.dts index cd47ac5b528f..dbdf596dd151 100644 --- a/arch/arm/boot/dts/tegra20-colibri-iris.dts +++ b/arch/arm/boot/dts/tegra20-colibri-iris.dts @@ -6,7 +6,8 @@ / { model = "Toradex Colibri T20 on Iris"; - compatible = "toradex,iris", "toradex,colibri_t20", "nvidia,tegra20"; + compatible = "toradex,colibri_t20-iris", "toradex,colibri_t20", + "nvidia,tegra20"; aliases { rtc0 = "/i2c@7000c000/rtc@68"; -- cgit v1.2.3 From fee8cdc2df088fa2ee4b7f86a803918a3664a26b Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sun, 2 Sep 2018 12:09:06 +0200 Subject: ARM: tegra: colibri_t20: add eval board device tree Add an evaluation board device tree more in-line with all our other device trees. Signed-off-by: Marcel Ziswiler Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/arm/tegra.txt | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/tegra20-colibri-eval-v3.dts | 262 ++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 arch/arm/boot/dts/tegra20-colibri-eval-v3.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index 0909122a2bee..c59b15f64346 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -54,6 +54,7 @@ board-specific compatible values: toradex,apalis-tk1-v1.2 toradex,apalis-tk1-v1.2-eval toradex,colibri_t20 + toradex,colibri_t20-eval-v3 toradex,colibri_t20-iris toradex,colibri_t30 toradex,colibri_t30-eval-v3 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 9d6d7790d627..d89c31088158 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1061,6 +1061,7 @@ dtb-$(CONFIG_ARCH_TANGO) += \ tango4-vantage-1172.dtb dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \ tegra20-harmony.dtb \ + tegra20-colibri-eval-v3.dtb \ tegra20-colibri-iris.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \ diff --git a/arch/arm/boot/dts/tegra20-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra20-colibri-eval-v3.dts new file mode 100644 index 000000000000..3c0f2681fcde --- /dev/null +++ b/arch/arm/boot/dts/tegra20-colibri-eval-v3.dts @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/dts-v1/; + +#include +#include "tegra20-colibri.dtsi" + +/ { + model = "Toradex Colibri T20 on Colibri Evaluation Board"; + compatible = "toradex,colibri_t20-eval-v3", "toradex,colibri_t20", + "nvidia,tegra20"; + + aliases { + rtc0 = "/i2c@7000c000/rtc@68"; + rtc1 = "/i2c@7000d000/pmic@34"; + rtc2 = "/rtc@7000e000"; + serial0 = &uarta; + serial1 = &uartd; + serial2 = &uartb; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + nvidia,panel = <&panel>; + }; + }; + + hdmi@54280000 { + status = "okay"; + hdmi-supply = <®_5v0>; + }; + }; + + pinmux@70000014 { + state_default: pinmux { + bl-on { + nvidia,tristate = ; + }; + + ddc { + nvidia,tristate = ; + }; + + hotplug-detect { + nvidia,tristate = ; + }; + + i2c { + nvidia,tristate = ; + }; + + lcd { + nvidia,tristate = ; + }; + + lm1 { + nvidia,tristate = ; + }; + + mmc { + nvidia,tristate = ; + }; + + mmccd { + nvidia,tristate = ; + }; + + pwm-a-b { + nvidia,tristate = ; + }; + + pwm-c-d { + nvidia,tristate = ; + }; + + ssp { + nvidia,tristate = ; + }; + + uart-a { + nvidia,tristate = ; + }; + + uart-b { + nvidia,tristate = ; + }; + + uart-c { + nvidia,tristate = ; + }; + + usbh-pen { + nvidia,tristate = ; + }; + }; + }; + + /* Colibri UART-A */ + serial@70006000 { + status = "okay"; + }; + + /* Colibri UART-C */ + serial@70006040 { + status = "okay"; + }; + + /* Colibri UART-B */ + serial@70006300 { + status = "okay"; + }; + + pwm@7000a000 { + status = "okay"; + }; + + /* + * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier + * board) + */ + i2c@7000c000 { + status = "okay"; + clock-frequency = <400000>; + + /* M41T0M6 real time clock on carrier board */ + rtc@68 { + compatible = "st,m41t0"; + reg = <0x68>; + }; + }; + + /* GEN2_I2C: unused */ + + /* CAM_I2C (I2C3): unused */ + + /* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */ + i2c@7000c400 { + status = "okay"; + }; + + /* EHCI instance 0: USB1_DP/N -> USBC_P/N */ + usb@c5000000 { + status = "okay"; + dr_mode = "otg"; + }; + + usb-phy@c5000000 { + status = "okay"; + vbus-supply = <®_usbc_vbus>; + }; + + /* EHCI instance 2: USB3_DP/N -> USBH_P/N */ + usb@c5008000 { + status = "okay"; + }; + + usb-phy@c5008000 { + status = "okay"; + vbus-supply = <®_usbh_vbus>; + }; + + /* SPI4: Colibri SSP */ + spi@7000da00 { + status = "okay"; + spi-max-frequency = <25000000>; + + can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + clocks = <&clk16m>; + interrupt-parent = <&gpio>; + /* CAN_INT */ + interrupts = ; + spi-max-frequency = <10000000>; + vdd-supply = <®_3v3>; + xceiver-supply = <®_5v0>; + }; + }; + + /* SD/MMC */ + sdhci@c8000600 { + status = "okay"; + bus-width = <4>; + cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; /* MMCD */ + no-1-8-v; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <255 128 64 32 16 8 4 0>; + default-brightness-level = <6>; + /* BL_ON */ + enable-gpios = <&gpio TEGRA_GPIO(T, 4) GPIO_ACTIVE_HIGH>; + power-supply = <®_3v3>; + pwms = <&pwm 0 5000000>; /* PWM */ + }; + + clk16m: osc3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + wakeup { + label = "SODIMM pin 45 wakeup"; + gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu", "simple-panel"; + backlight = <&backlight>; + power-supply = <®_3v3>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V_SW"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V_SW"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_usbc_vbus: regulator-usbc-vbus { + compatible = "regulator-fixed"; + regulator-name = "VCC_USB5"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_5v0>; + }; + + /* USBH_PEN resp. USB_P_EN */ + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; + vin-supply = <®_5v0>; + }; +}; -- cgit v1.2.3 From 10c3a0b76d4cf6ad21d3373ff5894daecc665bc9 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 13 Jul 2018 16:52:16 +0800 Subject: dt-bindings: arm: move berlin binding documentation to syna.txt Move berlin binding documentation as part of transition from Marvell berlin to Synaptics SoC. Signed-off-by: Jisheng Zhang Acked-by: Rob Herring --- .../bindings/arm/marvell/marvell,berlin.txt | 96 ---------------------- Documentation/devicetree/bindings/arm/syna.txt | 96 ++++++++++++++++++++++ 2 files changed, 96 insertions(+), 96 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt create mode 100644 Documentation/devicetree/bindings/arm/syna.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt deleted file mode 100644 index 3bab18409b7a..000000000000 --- a/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt +++ /dev/null @@ -1,96 +0,0 @@ -Marvell Berlin SoC Family Device Tree Bindings ---------------------------------------------------------------- - -Work in progress statement: - -Device tree files and bindings applying to Marvell Berlin SoCs and boards are -considered "unstable". Any Marvell Berlin device tree binding may change at any -time. Be sure to use a device tree binary and a kernel image generated from the -same source tree. - -Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a -stable binding/ABI. - ---------------------------------------------------------------- - -Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500 -shall have the following properties: - -* Required root node properties: -compatible: must contain "marvell,berlin" - -In addition, the above compatible shall be extended with the specific -SoC and board used. Currently known SoC compatibles are: - "marvell,berlin2" for Marvell Armada 1500 (BG2, 88DE3100), - "marvell,berlin2cd" for Marvell Armada 1500-mini (BG2CD, 88DE3005) - "marvell,berlin2ct" for Marvell Armada ? (BG2CT, 88DE????) - "marvell,berlin2q" for Marvell Armada 1500-pro (BG2Q, 88DE3114) - "marvell,berlin3" for Marvell Armada ? (BG3, 88DE????) - -* Example: - -/ { - model = "Sony NSZ-GS7"; - compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin"; - - ... -} - -* Marvell Berlin CPU control bindings - -CPU control register allows various operations on CPUs, like resetting them -independently. - -Required properties: -- compatible: should be "marvell,berlin-cpu-ctrl" -- reg: address and length of the register set - -Example: - -cpu-ctrl@f7dd0000 { - compatible = "marvell,berlin-cpu-ctrl"; - reg = <0xf7dd0000 0x10000>; -}; - -* Marvell Berlin2 chip control binding - -Marvell Berlin SoCs have a chip control register set providing several -individual registers dealing with pinmux, padmux, clock, reset, and secondary -CPU boot address. Unfortunately, the individual registers are spread among the -chip control registers, so there should be a single DT node only providing the -different functions which are described below. - -Required properties: -- compatible: - * the first and second values must be: - "simple-mfd", "syscon" -- reg: address and length of following register sets for - BG2/BG2CD: chip control register set - BG2Q: chip control register set and cpu pll registers - -* Marvell Berlin2 system control binding - -Marvell Berlin SoCs have a system control register set providing several -individual registers dealing with pinmux, padmux, and reset. - -Required properties: -- compatible: - * the first and second values must be: - "simple-mfd", "syscon" -- reg: address and length of the system control register set - -Example: - -chip: chip-control@ea0000 { - compatible = "simple-mfd", "syscon"; - reg = <0xea0000 0x400>; - - /* sub-device nodes */ -}; - -sysctrl: system-controller@d000 { - compatible = "simple-mfd", "syscon"; - reg = <0xd000 0x100>; - - /* sub-device nodes */ -}; diff --git a/Documentation/devicetree/bindings/arm/syna.txt b/Documentation/devicetree/bindings/arm/syna.txt new file mode 100644 index 000000000000..3bab18409b7a --- /dev/null +++ b/Documentation/devicetree/bindings/arm/syna.txt @@ -0,0 +1,96 @@ +Marvell Berlin SoC Family Device Tree Bindings +--------------------------------------------------------------- + +Work in progress statement: + +Device tree files and bindings applying to Marvell Berlin SoCs and boards are +considered "unstable". Any Marvell Berlin device tree binding may change at any +time. Be sure to use a device tree binary and a kernel image generated from the +same source tree. + +Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a +stable binding/ABI. + +--------------------------------------------------------------- + +Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500 +shall have the following properties: + +* Required root node properties: +compatible: must contain "marvell,berlin" + +In addition, the above compatible shall be extended with the specific +SoC and board used. Currently known SoC compatibles are: + "marvell,berlin2" for Marvell Armada 1500 (BG2, 88DE3100), + "marvell,berlin2cd" for Marvell Armada 1500-mini (BG2CD, 88DE3005) + "marvell,berlin2ct" for Marvell Armada ? (BG2CT, 88DE????) + "marvell,berlin2q" for Marvell Armada 1500-pro (BG2Q, 88DE3114) + "marvell,berlin3" for Marvell Armada ? (BG3, 88DE????) + +* Example: + +/ { + model = "Sony NSZ-GS7"; + compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin"; + + ... +} + +* Marvell Berlin CPU control bindings + +CPU control register allows various operations on CPUs, like resetting them +independently. + +Required properties: +- compatible: should be "marvell,berlin-cpu-ctrl" +- reg: address and length of the register set + +Example: + +cpu-ctrl@f7dd0000 { + compatible = "marvell,berlin-cpu-ctrl"; + reg = <0xf7dd0000 0x10000>; +}; + +* Marvell Berlin2 chip control binding + +Marvell Berlin SoCs have a chip control register set providing several +individual registers dealing with pinmux, padmux, clock, reset, and secondary +CPU boot address. Unfortunately, the individual registers are spread among the +chip control registers, so there should be a single DT node only providing the +different functions which are described below. + +Required properties: +- compatible: + * the first and second values must be: + "simple-mfd", "syscon" +- reg: address and length of following register sets for + BG2/BG2CD: chip control register set + BG2Q: chip control register set and cpu pll registers + +* Marvell Berlin2 system control binding + +Marvell Berlin SoCs have a system control register set providing several +individual registers dealing with pinmux, padmux, and reset. + +Required properties: +- compatible: + * the first and second values must be: + "simple-mfd", "syscon" +- reg: address and length of the system control register set + +Example: + +chip: chip-control@ea0000 { + compatible = "simple-mfd", "syscon"; + reg = <0xea0000 0x400>; + + /* sub-device nodes */ +}; + +sysctrl: system-controller@d000 { + compatible = "simple-mfd", "syscon"; + reg = <0xd000 0x100>; + + /* sub-device nodes */ +}; -- cgit v1.2.3 From 3da2937946d9c6510c5a65b6ddee1aa78b4f6676 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 13 Jul 2018 17:00:33 +0800 Subject: dt-bindings: arm: syna: add support for the AS370 SoC The AS370 SoC is a new derivative of the berlin family. However, the SoC isn't named as berlin*. Signed-off-by: Jisheng Zhang Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/arm/syna.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/syna.txt b/Documentation/devicetree/bindings/arm/syna.txt index 3bab18409b7a..2face46a5f64 100644 --- a/Documentation/devicetree/bindings/arm/syna.txt +++ b/Documentation/devicetree/bindings/arm/syna.txt @@ -1,4 +1,9 @@ -Marvell Berlin SoC Family Device Tree Bindings +Synaptics SoC Device Tree Bindings + +According to https://www.synaptics.com/company/news/conexant-marvell +Synaptics has acquired the Multimedia Solutions Business of Marvell, so +berlin SoCs are now Synaptics' SoCs now. + --------------------------------------------------------------- Work in progress statement: @@ -13,6 +18,10 @@ stable binding/ABI. --------------------------------------------------------------- +Boards with the Synaptics AS370 SoC shall have the following properties: + Required root node property: + compatible: "syna,as370" + Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500 shall have the following properties: -- cgit v1.2.3 From c2b70ffcd34eca60013d90bd6cd56e60b07adef8 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 25 Jun 2018 14:02:53 +0200 Subject: dt-bindings: display: sun4i-drm: Add R40 mixer compatibles R40 DE2 mixers are similar to those found in A83T, except it needs different clock settings. Add a compatibles for them. Reviewed-by: Chen-Yu Tsai Acked-by: Rob Herring Signed-off-by: Jernej Skrabec Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20180625120304.7543-14-jernej.skrabec@siol.net --- Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index 22d6dda587c5..7854fff4fc16 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -376,6 +376,8 @@ Required properties: * allwinner,sun8i-a83t-de2-mixer-0 * allwinner,sun8i-a83t-de2-mixer-1 * allwinner,sun8i-h3-de2-mixer-0 + * allwinner,sun8i-r40-de2-mixer-0 + * allwinner,sun8i-r40-de2-mixer-1 * allwinner,sun8i-v3s-de2-mixer * allwinner,sun50i-a64-de2-mixer-0 * allwinner,sun50i-a64-de2-mixer-1 -- cgit v1.2.3 From 0af936821185a8f61af85015395477b016dd3fab Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 27 Sep 2018 12:03:46 -0700 Subject: remoteproc: qcom: pas: Add QCS404 remoteprocs Add compatibles for the three PAS based remote processors found in QCS404. Reviewed-by: Sibi Sankar Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt | 3 +++ drivers/remoteproc/qcom_q6v5_pas.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt index b7d058228185..9c0cff3a5ed8 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt @@ -10,6 +10,9 @@ on the Qualcomm ADSP Hexagon core. "qcom,msm8974-adsp-pil" "qcom,msm8996-adsp-pil" "qcom,msm8996-slpi-pil" + "qcom,qcs404-adsp-pas" + "qcom,qcs404-cdsp-pas" + "qcom,qcs404-wcss-pas" "qcom,sdm845-adsp-pas" "qcom,sdm845-cdsp-pas" diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 03edf08c8a2f..b1e63fcd5fdf 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -362,10 +362,22 @@ static const struct adsp_data slpi_resource_init = { .ssctl_id = 0x16, }; +static const struct adsp_data wcss_resource_init = { + .crash_reason_smem = 421, + .firmware_name = "wcnss.mdt", + .pas_id = 6, + .ssr_name = "mpss", + .sysmon_name = "wcnss", + .ssctl_id = 0x12, +}; + static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init}, + { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, + { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, + { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init}, { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, { }, -- cgit v1.2.3 From 3d337848ecc7f1cb23ab6e851af86b907db06bfa Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Fri, 28 Sep 2018 17:12:55 -0700 Subject: Input: pwm-vibrator - correct pwms in DT binding example In the example for the pwm-vibrator bindings, pwm8 is the direction pin, and pwm9 is the enable pin. The pwms on the vibrator node has these two values swapped so this patch corrects it. Signed-off-by: Brian Masney Reviewed-by: Sebastian Reichel Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/pwm-vibrator.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/pwm-vibrator.txt b/Documentation/devicetree/bindings/input/pwm-vibrator.txt index 09145d18491d..88c775a3fe21 100644 --- a/Documentation/devicetree/bindings/input/pwm-vibrator.txt +++ b/Documentation/devicetree/bindings/input/pwm-vibrator.txt @@ -58,8 +58,8 @@ Example from Motorola Droid 4: vibrator { compatible = "pwm-vibrator"; - pwms = <&pwm8 0 1000000000 0>, - <&pwm9 0 1000000000 0>; + pwms = <&pwm9 0 1000000000 0>, + <&pwm8 0 1000000000 0>; pwm-names = "enable", "direction"; direction-duty-cycle-ns = <1000000000>; }; -- cgit v1.2.3 From 0a01fa940e7c1291476a65caecfbebf7beec1256 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 19 Sep 2018 18:44:08 -0700 Subject: mailbox: qcom: Add QCS404 APPS Global compatible Add support for the QCS404 APPS Global block with IPC register at offset 8. Signed-off-by: Bjorn Andersson Reviewed-by: Vinod Koul Reviewed-by: Rob Herring Signed-off-by: Jassi Brar --- Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt | 1 + drivers/mailbox/qcom-apcs-ipc-mailbox.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt index 6e8a9ab0fdae..1232fc9fc709 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt @@ -11,6 +11,7 @@ platforms. "qcom,msm8916-apcs-kpss-global", "qcom,msm8996-apcs-hmss-global" "qcom,msm8998-apcs-hmss-global" + "qcom,qcs404-apcs-apps-global" "qcom,sdm845-apss-shared" - reg: diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c index 333ed4a9d4b8..aed23ac9550d 100644 --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c @@ -126,6 +126,7 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = { { .compatible = "qcom,msm8916-apcs-kpss-global", .data = (void *)8 }, { .compatible = "qcom,msm8996-apcs-hmss-global", .data = (void *)16 }, { .compatible = "qcom,msm8998-apcs-hmss-global", .data = (void *)8 }, + { .compatible = "qcom,qcs404-apcs-apps-global", .data = (void *)8 }, { .compatible = "qcom,sdm845-apss-shared", .data = (void *)12 }, {} }; -- cgit v1.2.3 From 1e35455c43c528eb79fdee954525738b17811120 Mon Sep 17 00:00:00 2001 From: ryang Date: Sat, 22 Sep 2018 16:57:53 -0400 Subject: dt-bindings: iio: light: bh1750: Add device tree binding documentation Document device tree bindings for ROHM BH1750 ambient light sensor driver. Signed-off-by: ryang Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/light/bh1750.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/light/bh1750.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/light/bh1750.txt b/Documentation/devicetree/bindings/iio/light/bh1750.txt new file mode 100644 index 000000000000..1e7685797d7a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/bh1750.txt @@ -0,0 +1,18 @@ +ROHM BH1750 - ALS, Ambient light sensor + +Required properties: + +- compatible: Must be one of: + "rohm,bh1710" + "rohm,bh1715" + "rohm,bh1721" + "rohm,bh1750" + "rohm,bh1751" +- reg: the I2C address of the sensor + +Example: + +light-sensor@23 { + compatible = "rohm,bh1750"; + reg = <0x23>; +}; -- cgit v1.2.3 From ea2698597e13e2d812929d3ba33946e78a8db4d1 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 27 Jul 2018 13:52:04 +0200 Subject: nvmem: sunxi-sid: add support for H5's SID controller The H5 SoC have a SID controller that looks like the one in A64, the cells are in the same offset but doesn't contain the same data (thermal sensor calibration for example). Add a binding for it. Signed-off-by: Emmanuel Vadot Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt index e319fe5e205a..99c4ba6a3f61 100644 --- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt +++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt @@ -7,6 +7,7 @@ Required properties: "allwinner,sun8i-a83t-sid" "allwinner,sun8i-h3-sid" "allwinner,sun50i-a64-sid" + "allwinner,sun50i-h5-sid" - reg: Should contain registers location and length -- cgit v1.2.3 From fc37b408bf42db6d60985f83d2dbdc782eb15f83 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Sun, 30 Sep 2018 11:32:27 +0800 Subject: dt-bindings: arm: add compatible for i.MX6ULZ 14x14 EVK board This patch adds compatible for i.MX6ULZ 14x14 EVK board. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index 968f238c0801..7b964d8772e6 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -85,6 +85,10 @@ i.MX6 UltraLiteLite 14x14 EVK Board Required root node properties: - compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull"; +i.MX6 ULZ 14x14 EVK Board +Required root node properties: + - compatible = "fsl,imx6ulz-14x14-evk", "fsl,imx6ull", "fsl,imx6ulz"; + i.MX6 SoloX SDB Board Required root node properties: - compatible = "fsl,imx6sx-sdb", "fsl,imx6sx"; -- cgit v1.2.3 From d1ca7c56e1617ffeff71e9ba521254b8ffdeda59 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 11 Apr 2018 22:10:33 +0530 Subject: dt-bindings: power: Add Actions Semi S900 SPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define power domains for Actions Semi S900 SoC Smart Power System (SPS). Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Andreas Färber --- .../devicetree/bindings/power/actions,owl-sps.txt | 2 ++ include/dt-bindings/power/owl-s900-powergate.h | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 include/dt-bindings/power/owl-s900-powergate.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt index 78edd63641e8..a3571937b019 100644 --- a/Documentation/devicetree/bindings/power/actions,owl-sps.txt +++ b/Documentation/devicetree/bindings/power/actions,owl-sps.txt @@ -3,11 +3,13 @@ Actions Semi Owl Smart Power System (SPS) Required properties: - compatible : "actions,s500-sps" for S500 "actions,s700-sps" for S700 + "actions,s900-sps" for S900 - reg : Offset and length of the register set for the device. - #power-domain-cells : Must be 1. See macros in: include/dt-bindings/power/owl-s500-powergate.h for S500 include/dt-bindings/power/owl-s700-powergate.h for S700 + include/dt-bindings/power/owl-s900-powergate.h for S900 Example: diff --git a/include/dt-bindings/power/owl-s900-powergate.h b/include/dt-bindings/power/owl-s900-powergate.h new file mode 100644 index 000000000000..d939bd964657 --- /dev/null +++ b/include/dt-bindings/power/owl-s900-powergate.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) */ +/* + * Actions Semi S900 SPS + * + * Copyright (c) 2018 Linaro Ltd. + */ +#ifndef DT_BINDINGS_POWER_OWL_S900_POWERGATE_H +#define DT_BINDINGS_POWER_OWL_S900_POWERGATE_H + +#define S900_PD_GPU_B 0 +#define S900_PD_VCE 1 +#define S900_PD_SENSOR 2 +#define S900_PD_VDE 3 +#define S900_PD_HDE 4 +#define S900_PD_USB3 5 +#define S900_PD_DDR0 6 +#define S900_PD_DDR1 7 +#define S900_PD_DE 8 +#define S900_PD_NAND 9 +#define S900_PD_USB2_H0 10 +#define S900_PD_USB2_H1 11 + +#endif -- cgit v1.2.3 From f4089fcfdb3d31421bbe0b1f3c3d6c11cd0dcb4d Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Fri, 21 Sep 2018 18:36:58 +0100 Subject: dt-bindings: i2c: rcar: Add r8a77470 support Although the I2C IP found in the RZ/G1C is not exactly the same as the one found in the R-Car Gen2 family or R-Car Gen3 family, it can still be considered as compatible with R-Car Gen2 from a software perpective. This patch therefore documents the SoC specific compatible string, and the compatibility with Gen2 fallback is retained. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-rcar.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 39cd21d95810..671e2a14ddbb 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -4,6 +4,7 @@ Required properties: - compatible: "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC. "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. + "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC. "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC. "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC. "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC. -- cgit v1.2.3 From 8bca7089af56be53ecd87091b1f5bf81030e571b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 21 Sep 2018 18:36:59 +0100 Subject: dt-bindings: i2c: rcar: Document r8a7744 support Document i2c Device Tree support for RZ/G1N (R8A7744) SoC, which is compatible with R-Car Gen2 SoC family. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Reviewed-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-rcar.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 671e2a14ddbb..30c0485b167b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -3,6 +3,7 @@ I2C for R-Car platforms Required properties: - compatible: "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC. + "renesas,i2c-r8a7744" if the device is a part of a R8A7744 SoC. "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC. "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC. -- cgit v1.2.3 From f88c18ddb0903c49a6b999cd7fe05f06246d4a62 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 21 Sep 2018 18:37:00 +0100 Subject: dt-bindings: i2c: sh_mobile: Document r8a7744 support Document i2c Device Tree support for RZ/G1N (R8A7744) SoC, which is compatible with R-Car Gen2 SoC family. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Reviewed-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt index 872673adff5a..d81b62643655 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt @@ -5,6 +5,7 @@ Required properties: - "renesas,iic-r8a73a4" (R-Mobile APE6) - "renesas,iic-r8a7740" (R-Mobile A1) - "renesas,iic-r8a7743" (RZ/G1M) + - "renesas,iic-r8a7744" (RZ/G1N) - "renesas,iic-r8a7745" (RZ/G1E) - "renesas,iic-r8a774a1" (RZ/G2M) - "renesas,iic-r8a7790" (R-Car H2) -- cgit v1.2.3 From 18bd1963aef94e0186ad435f8a497b74c00b73de Mon Sep 17 00:00:00 2001 From: Jerry Hoemann Date: Mon, 20 Aug 2018 13:31:23 -0600 Subject: watchdog: hpwdt: Update Driver Documentation. Remove references to deprecated features like NMI sourcing and obsoleted module parameters. Add details concerning new module parameter pretimeout and tips to programming it. Signed-off-by: Jerry Hoemann Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/watchdog/hpwdt.txt | 93 ++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 62 deletions(-) (limited to 'Documentation') diff --git a/Documentation/watchdog/hpwdt.txt b/Documentation/watchdog/hpwdt.txt index 6d866c537127..55df692c5595 100644 --- a/Documentation/watchdog/hpwdt.txt +++ b/Documentation/watchdog/hpwdt.txt @@ -1,15 +1,12 @@ -Last reviewed: 05/20/2016 +Last reviewed: 08/20/2018 HPE iLO NMI Watchdog Driver - NMI sourcing for iLO based ProLiant Servers - Documentation and Driver by - Thomas Mingarelli + for iLO based ProLiant Servers The HPE iLO NMI Watchdog driver is a kernel module that provides basic - watchdog functionality and the added benefit of NMI sourcing. Both the - watchdog functionality and the NMI sourcing capability need to be enabled - by the user. Remember that the two modes are not dependent on one another. - A user can have the NMI sourcing without the watchdog timer and vice-versa. + watchdog functionality and handler for the iLO "Generate NMI to System" + virtual button. + All references to iLO in this document imply it also works on iLO2 and all subsequent generations. @@ -21,12 +18,16 @@ Last reviewed: 05/20/2016 not be updated in a timely fashion and a hardware system reset (also known as an Automatic Server Recovery (ASR)) event will occur. - The hpwdt driver also has three (3) module parameters. They are the following: + The hpwdt driver also has the following module parameters: soft_margin - allows the user to set the watchdog timer value. Default value is 30 seconds. - allow_kdump - allows the user to save off a kernel dump image after an NMI. - Default value is 1/ON + timeout - an alias of soft_margin. + pretimeout - allows the user to set the watchdog pretimeout value. + This is the number of seconds before timeout when an + NMI is delivered to the system. Setting the value to + zero disables the pretimeout NMI. + Default value is 9 seconds. nowayout - basic watchdog parameter that does not allow the timer to be restarted or an impending ASR to be escaped. Default value is set when compiling the kernel. If it is set @@ -37,61 +38,29 @@ Last reviewed: 05/20/2016 interface to /dev/watchdog can be found in Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt. - The NMI sourcing capability is disabled by default due to the inability to - distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the - Linux kernel. What this means is that the hpwdt nmi handler code is called - each time the NMI signal fires off. This could amount to several thousands of - NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and - confused" message in the logs or if the system gets into a hung state, then - the hpwdt driver can be reloaded. - - 1. If the kernel has not been booted with nmi_watchdog turned off then - edit and place the nmi_watchdog=0 at the end of the currently booting - kernel line. Depending on your Linux distribution and platform setup: - For non-UEFI systems - /boot/grub/grub.conf or - /boot/grub/menu.lst - For UEFI systems - /boot/efi/EFI/distroname/grub.conf or - /boot/efi/efi/distroname/elilo.conf - 2. reboot the sever - 3. Once the system comes up perform a modprobe -r hpwdt - 4. modprobe /lib/modules/`uname -r`/kernel/drivers/watchdog/hpwdt.ko - - Now, the hpwdt can successfully receive and source the NMI and provide a log - message that details the reason for the NMI (as determined by the HPE BIOS). - - Below is a list of NMIs the HPE BIOS understands along with the associated - code (reason): - - No source found 00h - - Uncorrectable Memory Error 01h - - ASR NMI 1Bh - - PCI Parity Error 20h - - NMI Button Press 27h - - SB_BUS_NMI 28h - - ILO Doorbell NMI 29h - - ILO IOP NMI 2Ah - - ILO Watchdog NMI 2Bh - - Proc Throt NMI 2Ch + Due to limitations in the iLO hardware, the NMI pretimeout if enabled, + can only be set to 9 seconds. Attempts to set pretimeout to other + non-zero values will be rounded, possibly to zero. Users should verify + the pretimeout value after attempting to set pretimeout or timeout. - Front Side Bus NMI 2Dh + Upon receipt of an NMI from the iLO, the hpwdt driver will initiate a + panic. This is to allow for a crash dump to be collected. It is incumbent + upon the user to have properly configured the system for kdump. - PCI Express Error 2Fh + The default Linux kernel behavior upon panic is to print a kernel tombstone + and loop forever. This is generally not what a watchdog user wants. - DMA controller NMI 30h + For those wishing to learn more please see: + Documentation/kdump/kdump.txt + Documentation/admin-guide/kernel-parameters.txt (panic=) + Your Linux Distribution specific documentation. - Hypertransport/CSI Error 31h + If the hpwdt does not receive the NMI associated with an expiring timer, + the iLO will proceed to reset the system at timeout if the timer hasn't + been updated. +-- + The HPE iLO NMI Watchdog Driver and documentation were originally developed + by Tom Mingarelli. - -- Tom Mingarelli -- cgit v1.2.3 From d72e8256c20971b12cddd71d87c32284de7108fa Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Sep 2018 08:58:16 -0500 Subject: dt-bindings: watchdog: renesas-wdt: Add support for R7S9210 Document support for RZ/A2 Signed-off-by: Chris Brandt Reviewed-by: Simon Horman Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/renesas-wdt.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt index 9407212a85a8..a9e49da6fa24 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt @@ -20,6 +20,7 @@ Required properties: - "renesas,r8a77990-wdt" (R-Car E3) - "renesas,r8a77995-wdt" (R-Car D3) - "renesas,r7s72100-wdt" (RZ/A1) + - "renesas,r7s9210-wdt" (RZ/A2) The generic compatible string must be: - "renesas,rza-wdt" for RZ/A - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G1 -- cgit v1.2.3 From c550f01c810f2197c98e6e3103f81797f5e063be Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 20 Sep 2018 09:20:34 -1000 Subject: serial:serial_core: Allow use of CTS for PPS line discipline Add a "pps_4wire" file to serial ports in sysfs in case the kernel is configured with CONFIG_PPS_CLIENT_LDISC. Writing 1 to the file enables the use of CTS instead of DCD for PPS signal input. This is necessary in case a serial port is not completely wired. Though this affects PPS processing the patch is against the serial core as the source of the serial port PPS event dispatching has to be modified. Furthermore it should be possible to modify the source of serial port PPS event dispatching before changing the line discipline. Signed-off-by: Andreas Steinmetz Signed-off-by: Steve Sakoman Tested-by: Steve Sakoman Tested-by: Eric Gallimore Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-tty | 9 +++++ drivers/tty/serial/serial_core.c | 70 ++++++++++++++++++++++++++++++++++++- include/linux/serial_core.h | 3 +- 3 files changed, 80 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 9eb3c2b6b040..441105a75d1f 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -154,3 +154,12 @@ Description: device specification. For example, when user sets 7bytes on 16550A, which has 1/4/8/14 bytes trigger, the RX trigger is automatically changed to 4 bytes. + +What: /sys/class/tty/ttyS0/pps_4wire +Date: September 2018 +Contact: Steve Sakoman +Description: + Shows/sets "4 wire" mode for the PPS input to the serial driver. + For fully implemented serial ports PPS is normally provided + on the DCD line. For partial "4 wire" implementations CTS is + used instead of DCD. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 80bb56facfb6..ed0133395cc7 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2664,6 +2664,57 @@ static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); } +static ssize_t pps_4wire_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tty_port *port = dev_get_drvdata(dev); + struct uart_state *state = container_of(port, struct uart_state, port); + struct uart_port *uport; + int mode = 0; + + mutex_lock(&port->mutex); + uport = uart_port_check(state); + if (!uport) + goto out; + + mode = uport->pps_4wire; + +out: + mutex_unlock(&port->mutex); + return sprintf(buf, mode ? "yes\n" : "no\n"); +} + +static ssize_t pps_4wire_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tty_port *port = dev_get_drvdata(dev); + struct uart_state *state = container_of(port, struct uart_state, port); + struct uart_port *uport; + bool mode; + int ret; + + if (!count) + return -EINVAL; + + ret = kstrtobool(buf, &mode); + if (ret < 0) + return ret; + + mutex_lock(&port->mutex); + uport = uart_port_check(state); + if (!uport) + goto out; + + spin_lock_irq(&uport->lock); + uport->pps_4wire = mode; + spin_unlock_irq(&uport->lock); + +out: + mutex_unlock(&port->mutex); + return count; +} +static DEVICE_ATTR_RW(pps_4wire); + static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL); static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL); static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); @@ -2692,6 +2743,7 @@ static struct attribute *tty_dev_attrs[] = { &dev_attr_io_type.attr, &dev_attr_iomem_base.attr, &dev_attr_iomem_reg_shift.attr, + &dev_attr_pps_4wire.attr, NULL, }; @@ -2748,6 +2800,9 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) goto out; } + /* assert that pps handling is done via DCD as default */ + uport->pps_4wire = 0; + /* * If this port is a console, then the spinlock is already * initialised. @@ -2923,7 +2978,7 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) lockdep_assert_held_once(&uport->lock); - if (tty) { + if (tty && !uport->pps_4wire) { ld = tty_ldisc_ref(tty); if (ld) { if (ld->ops->dcd_change) @@ -2952,8 +3007,21 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change); */ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) { + struct tty_port *port = &uport->state->port; + struct tty_struct *tty = port->tty; + struct tty_ldisc *ld; + lockdep_assert_held_once(&uport->lock); + if (tty && uport->pps_4wire) { + ld = tty_ldisc_ref(tty); + if (ld) { + if (ld->ops->dcd_change) + ld->ops->dcd_change(tty, status); + tty_ldisc_deref(ld); + } + } + uport->icount.cts++; if (uart_softcts_mode(uport)) { diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 406edae44ca3..079793e5d3fa 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -255,7 +255,8 @@ struct uart_port { struct device *dev; /* parent device */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; - unsigned char unused[2]; + unsigned char pps_4wire; /* CTS instead of DCD */ + unsigned char unused; const char *name; /* port name */ struct attribute_group *attr_group; /* port specific attributes */ const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ -- cgit v1.2.3 From ad8c0eaa0a418ae8ef3f9217638bb86439399eac Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 26 Sep 2018 14:58:47 +0200 Subject: tty/serial_core: add ISO7816 infrastructure Add the ISO7816 ioctl and associated accessors and data structure. Drivers can then use this common implementation to handle ISO7816 (smart cards). Signed-off-by: Nicolas Ferre [ludovic.desroches@microchip.com: squash and rebase, removal of gpios, checkpatch fixes] Signed-off-by: Ludovic Desroches Signed-off-by: Greg Kroah-Hartman --- Documentation/serial/serial-iso7816.txt | 83 +++++++++++++++++++++++++++++++++ arch/alpha/include/uapi/asm/ioctls.h | 2 + arch/mips/include/uapi/asm/ioctls.h | 2 + arch/parisc/include/uapi/asm/ioctls.h | 2 + arch/powerpc/include/uapi/asm/ioctls.h | 2 + arch/sh/include/uapi/asm/ioctls.h | 2 + arch/sparc/include/uapi/asm/ioctls.h | 2 + arch/xtensa/include/uapi/asm/ioctls.h | 2 + drivers/tty/serial/serial_core.c | 60 ++++++++++++++++++++++++ include/linux/serial_core.h | 3 ++ include/uapi/asm-generic/ioctls.h | 2 + include/uapi/linux/serial.h | 17 +++++++ 12 files changed, 179 insertions(+) create mode 100644 Documentation/serial/serial-iso7816.txt (limited to 'Documentation') diff --git a/Documentation/serial/serial-iso7816.txt b/Documentation/serial/serial-iso7816.txt new file mode 100644 index 000000000000..3193d24a2b0f --- /dev/null +++ b/Documentation/serial/serial-iso7816.txt @@ -0,0 +1,83 @@ + ISO7816 SERIAL COMMUNICATIONS + +1. INTRODUCTION + + ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC) + also known as smart cards. + +2. HARDWARE-RELATED CONSIDERATIONS + + Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of + handling communication with a smart card. + + For these microcontrollers, the Linux driver should be made capable of + working in both modes, and proper ioctls (see later) should be made + available at user-level to allow switching from one mode to the other, and + vice versa. + +3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL + + The Linux kernel provides the serial_iso7816 structure (see [1]) to handle + ISO7816 communications. This data structure is used to set and configure + ISO7816 parameters in ioctls. + + Any driver for devices capable of working both as RS232 and ISO7816 should + implement the iso7816_config callback in the uart_port structure. The + serial_core calls iso7816_config to do the device specific part in response + to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config + callback receives a pointer to struct serial_iso7816. + +4. USAGE FROM USER-LEVEL + + From user-level, ISO7816 configuration can be get/set using the previous + ioctls. For instance, to set ISO7816 you can use the following code: + + #include + + /* Include definition for ISO7816 ioctls: TIOCSISO7816 and TIOCGISO7816 */ + #include + + /* Open your specific device (e.g., /dev/mydevice): */ + int fd = open ("/dev/mydevice", O_RDWR); + if (fd < 0) { + /* Error handling. See errno. */ + } + + struct serial_iso7816 iso7816conf; + + /* Reserved fields as to be zeroed */ + memset(&iso7816conf, 0, sizeof(iso7816conf)); + + /* Enable ISO7816 mode: */ + iso7816conf.flags |= SER_ISO7816_ENABLED; + + /* Select the protocol: */ + /* T=0 */ + iso7816conf.flags |= SER_ISO7816_T(0); + /* or T=1 */ + iso7816conf.flags |= SER_ISO7816_T(1); + + /* Set the guard time: */ + iso7816conf.tg = 2; + + /* Set the clock frequency*/ + iso7816conf.clk = 3571200; + + /* Set transmission factors: */ + iso7816conf.sc_fi = 372; + iso7816conf.sc_di = 1; + + if (ioctl(fd_usart, TIOCSISO7816, &iso7816conf) < 0) { + /* Error handling. See errno. */ + } + + /* Use read() and write() syscalls here... */ + + /* Close the device when finished: */ + if (close (fd) < 0) { + /* Error handling. See errno. */ + } + +5. REFERENCES + + [1] include/uapi/linux/serial.h diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index 3729d92d3fa8..1e9121c9b3c7 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -102,6 +102,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 890245a9f0c4..16aa8a766aec 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h @@ -93,6 +93,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index aafb1c0ca0af..82d1148c6379 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -62,6 +62,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index 41b1a5c15734..2c145da3b774 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -102,6 +102,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h index cc62f6f98103..11866d4f60e1 100644 --- a/arch/sh/include/uapi/asm/ioctls.h +++ b/arch/sh/include/uapi/asm/ioctls.h @@ -95,6 +95,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 2df52711e170..7fd2f5873c9e 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h @@ -27,6 +27,8 @@ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485) #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485) +#define TIOCGISO7816 _IOR('T', 0x43, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x44, struct serial_iso7816) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h index ec43609cbfc5..6d4a87296c95 100644 --- a/arch/xtensa/include/uapi/asm/ioctls.h +++ b/arch/xtensa/include/uapi/asm/ioctls.h @@ -107,6 +107,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define TIOCSERCONFIG _IO('T', 83) #define TIOCSERGWILD _IOR('T', 84, int) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index ed0133395cc7..0a4e6eeb5ff3 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1308,6 +1308,58 @@ static int uart_set_rs485_config(struct uart_port *port, return 0; } +static int uart_get_iso7816_config(struct uart_port *port, + struct serial_iso7816 __user *iso7816) +{ + unsigned long flags; + struct serial_iso7816 aux; + + if (!port->iso7816_config) + return -ENOIOCTLCMD; + + spin_lock_irqsave(&port->lock, flags); + aux = port->iso7816; + spin_unlock_irqrestore(&port->lock, flags); + + if (copy_to_user(iso7816, &aux, sizeof(aux))) + return -EFAULT; + + return 0; +} + +static int uart_set_iso7816_config(struct uart_port *port, + struct serial_iso7816 __user *iso7816_user) +{ + struct serial_iso7816 iso7816; + int i, ret; + unsigned long flags; + + if (!port->iso7816_config) + return -ENOIOCTLCMD; + + if (copy_from_user(&iso7816, iso7816_user, sizeof(*iso7816_user))) + return -EFAULT; + + /* + * There are 5 words reserved for future use. Check that userspace + * doesn't put stuff in there to prevent breakages in the future. + */ + for (i = 0; i < 5; i++) + if (iso7816.reserved[i]) + return -EINVAL; + + spin_lock_irqsave(&port->lock, flags); + ret = port->iso7816_config(port, &iso7816); + spin_unlock_irqrestore(&port->lock, flags); + if (ret) + return ret; + + if (copy_to_user(iso7816_user, &port->iso7816, sizeof(port->iso7816))) + return -EFAULT; + + return 0; +} + /* * Called via sys_ioctl. We can use spin_lock_irq() here. */ @@ -1392,6 +1444,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) case TIOCSRS485: ret = uart_set_rs485_config(uport, uarg); break; + + case TIOCSISO7816: + ret = uart_set_iso7816_config(state->uart_port, uarg); + break; + + case TIOCGISO7816: + ret = uart_get_iso7816_config(state->uart_port, uarg); + break; default: if (uport->ops->ioctl) ret = uport->ops->ioctl(uport, cmd, arg); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 079793e5d3fa..4e2ba4894dcc 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -144,6 +144,8 @@ struct uart_port { void (*handle_break)(struct uart_port *); int (*rs485_config)(struct uart_port *, struct serial_rs485 *rs485); + int (*iso7816_config)(struct uart_port *, + struct serial_iso7816 *iso7816); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ @@ -261,6 +263,7 @@ struct uart_port { struct attribute_group *attr_group; /* port specific attributes */ const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ struct serial_rs485 rs485; + struct serial_iso7816 iso7816; void *private_data; /* generic platform data pointer */ }; diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h index 040651735662..cdc9f4ca8c27 100644 --- a/include/uapi/asm-generic/ioctls.h +++ b/include/uapi/asm-generic/ioctls.h @@ -79,6 +79,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ +#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) +#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h index 3fdd0dee8b41..93eb3c496ff1 100644 --- a/include/uapi/linux/serial.h +++ b/include/uapi/linux/serial.h @@ -132,4 +132,21 @@ struct serial_rs485 { are a royal PITA .. */ }; +/* + * Serial interface for controlling ISO7816 settings on chips with suitable + * support. Set with TIOCSISO7816 and get with TIOCGISO7816 if supported by + * your platform. + */ +struct serial_iso7816 { + __u32 flags; /* ISO7816 feature flags */ +#define SER_ISO7816_ENABLED (1 << 0) +#define SER_ISO7816_T_PARAM (0x0f << 4) +#define SER_ISO7816_T(t) (((t) & 0x0f) << 4) + __u32 tg; + __u32 sc_fi; + __u32 sc_di; + __u32 clk; + __u32 reserved[5]; +}; + #endif /* _UAPI_LINUX_SERIAL_H */ -- cgit v1.2.3 From 9e3eb4eabdb6f652ca8a99f58f3eccf29610839d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 21 Sep 2018 15:45:54 +0100 Subject: dt-bindings: serial: sh-sci: Document r8a7744 bindings RZ/G1N (R8A7744) SoC also has the R-Car gen2 compatible SCIF, SCIFA, SCIFB, and HSCIF ports, so document the SoC specific bindings. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index eaca9da79d83..723abe02fac3 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -14,6 +14,10 @@ Required properties: - "renesas,scifa-r8a7743" for R8A7743 (RZ/G1M) SCIFA compatible UART. - "renesas,scifb-r8a7743" for R8A7743 (RZ/G1M) SCIFB compatible UART. - "renesas,hscif-r8a7743" for R8A7743 (RZ/G1M) HSCIF compatible UART. + - "renesas,scif-r8a7744" for R8A7744 (RZ/G1N) SCIF compatible UART. + - "renesas,scifa-r8a7744" for R8A7744 (RZ/G1N) SCIFA compatible UART. + - "renesas,scifb-r8a7744" for R8A7744 (RZ/G1N) SCIFB compatible UART. + - "renesas,hscif-r8a7744" for R8A7744 (RZ/G1N) HSCIF compatible UART. - "renesas,scif-r8a7745" for R8A7745 (RZ/G1E) SCIF compatible UART. - "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART. - "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART. -- cgit v1.2.3 From 2fd8e454189d580bcfc198fee60e51655945b986 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 28 Sep 2018 11:05:07 +0900 Subject: serial: 8250_uniphier: remove unused "fifo-size" property The FIFO size of the UART devices is 64 on almost all UniPhier SoCs with the exception Pro4TV SoC (MN2WS0235), which used 128 FIFO size. However, Pro4TV SoC was never upstreamed, and out of production. So, this property has never been used in a useful way. Let's remove old unused code. Signed-off-by: Masahiro Yamada Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/uniphier-uart.txt | 4 ---- drivers/tty/serial/8250/8250_uniphier.c | 10 +--------- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/uniphier-uart.txt b/Documentation/devicetree/bindings/serial/uniphier-uart.txt index 0b3892a7a528..811c479b373d 100644 --- a/Documentation/devicetree/bindings/serial/uniphier-uart.txt +++ b/Documentation/devicetree/bindings/serial/uniphier-uart.txt @@ -6,9 +6,6 @@ Required properties: - interrupts: a single interrupt specifier. - clocks: phandle to the input clock. -Optional properties: -- fifo-size: the RX/TX FIFO size. Defaults to 64 if not specified. - Example: aliases { serial0 = &serial0; @@ -19,5 +16,4 @@ Example: reg = <0x54006800 0x40>; interrupts = <0 33 4>; clocks = <&uart_clk>; - fifo-size = <64>; }; diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 28d88ccf5a0c..d292654422b2 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -12,9 +12,6 @@ #include "8250.h" -/* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */ -#define UNIPHIER_UART_DEFAULT_FIFO_SIZE 64 - /* * This hardware is similar to 8250, but its register map is a bit different: * - MMIO32 (regshift = 2) @@ -185,12 +182,6 @@ static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, port->uartclk = clk_get_rate(priv->clk); - /* Check for fifo size */ - if (of_property_read_u32(np, "fifo-size", &prop) == 0) - port->fifosize = prop; - else - port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE; - return 0; } @@ -241,6 +232,7 @@ static int uniphier_uart_probe(struct platform_device *pdev) up.port.type = PORT_16550A; up.port.iotype = UPIO_MEM32; + up.port.fifosize = 64; up.port.regshift = UNIPHIER_UART_REGSHIFT; up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE; up.capabilities = UART_CAP_FIFO; -- cgit v1.2.3 From aad2d4952d24d8910d9fc64da9107df0fb780a09 Mon Sep 17 00:00:00 2001 From: Dai Okamura Date: Fri, 28 Sep 2018 11:05:09 +0900 Subject: serial: 8250_uniphier: add auto-flow-control support Add selective auto-flow-control support for UniPhier serial driver. Signed-off-by: Dai Okamura Signed-off-by: Masahiro Yamada Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/uniphier-uart.txt | 3 +++ drivers/tty/serial/8250/8250_uniphier.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/uniphier-uart.txt b/Documentation/devicetree/bindings/serial/uniphier-uart.txt index 811c479b373d..7a1bf02bb869 100644 --- a/Documentation/devicetree/bindings/serial/uniphier-uart.txt +++ b/Documentation/devicetree/bindings/serial/uniphier-uart.txt @@ -6,6 +6,9 @@ Required properties: - interrupts: a single interrupt specifier. - clocks: phandle to the input clock. +Optional properties: +-auto-flow-control: enable automatic flow control support. + Example: aliases { serial0 = &serial0; diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 1028c02c5d83..164ba133437a 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -222,6 +222,9 @@ static int uniphier_uart_probe(struct platform_device *pdev) up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE; up.capabilities = UART_CAP_FIFO; + if (of_property_read_bool(dev->of_node, "auto-flow-control")) + up.capabilities |= UART_CAP_AFE; + up.port.serial_in = uniphier_serial_in; up.port.serial_out = uniphier_serial_out; up.dl_read = uniphier_serial_dl_read; -- cgit v1.2.3 From 817e9bc8cc04e5c70592525b96812c46c1aa1c46 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Oct 2018 09:57:23 -0700 Subject: Revert "serial:serial_core: Allow use of CTS for PPS line discipline" This reverts commit c550f01c810f2197c98e6e3103f81797f5e063be. Turns out the samsung tty driver is mucking around in the "unused" port fields and this patch breaks that code :( So we need to fix that driver up before this can be accepted. Reported-by: Stephen Rothwell Cc: Steve Sakoman Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-tty | 9 ----- drivers/tty/serial/serial_core.c | 70 +------------------------------------ include/linux/serial_core.h | 3 +- 3 files changed, 2 insertions(+), 80 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 441105a75d1f..9eb3c2b6b040 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -154,12 +154,3 @@ Description: device specification. For example, when user sets 7bytes on 16550A, which has 1/4/8/14 bytes trigger, the RX trigger is automatically changed to 4 bytes. - -What: /sys/class/tty/ttyS0/pps_4wire -Date: September 2018 -Contact: Steve Sakoman -Description: - Shows/sets "4 wire" mode for the PPS input to the serial driver. - For fully implemented serial ports PPS is normally provided - on the DCD line. For partial "4 wire" implementations CTS is - used instead of DCD. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0a4e6eeb5ff3..70402cdb4d8c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2724,57 +2724,6 @@ static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); } -static ssize_t pps_4wire_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tty_port *port = dev_get_drvdata(dev); - struct uart_state *state = container_of(port, struct uart_state, port); - struct uart_port *uport; - int mode = 0; - - mutex_lock(&port->mutex); - uport = uart_port_check(state); - if (!uport) - goto out; - - mode = uport->pps_4wire; - -out: - mutex_unlock(&port->mutex); - return sprintf(buf, mode ? "yes\n" : "no\n"); -} - -static ssize_t pps_4wire_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct tty_port *port = dev_get_drvdata(dev); - struct uart_state *state = container_of(port, struct uart_state, port); - struct uart_port *uport; - bool mode; - int ret; - - if (!count) - return -EINVAL; - - ret = kstrtobool(buf, &mode); - if (ret < 0) - return ret; - - mutex_lock(&port->mutex); - uport = uart_port_check(state); - if (!uport) - goto out; - - spin_lock_irq(&uport->lock); - uport->pps_4wire = mode; - spin_unlock_irq(&uport->lock); - -out: - mutex_unlock(&port->mutex); - return count; -} -static DEVICE_ATTR_RW(pps_4wire); - static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL); static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL); static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); @@ -2803,7 +2752,6 @@ static struct attribute *tty_dev_attrs[] = { &dev_attr_io_type.attr, &dev_attr_iomem_base.attr, &dev_attr_iomem_reg_shift.attr, - &dev_attr_pps_4wire.attr, NULL, }; @@ -2860,9 +2808,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) goto out; } - /* assert that pps handling is done via DCD as default */ - uport->pps_4wire = 0; - /* * If this port is a console, then the spinlock is already * initialised. @@ -3038,7 +2983,7 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) lockdep_assert_held_once(&uport->lock); - if (tty && !uport->pps_4wire) { + if (tty) { ld = tty_ldisc_ref(tty); if (ld) { if (ld->ops->dcd_change) @@ -3067,21 +3012,8 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change); */ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) { - struct tty_port *port = &uport->state->port; - struct tty_struct *tty = port->tty; - struct tty_ldisc *ld; - lockdep_assert_held_once(&uport->lock); - if (tty && uport->pps_4wire) { - ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->ops->dcd_change) - ld->ops->dcd_change(tty, status); - tty_ldisc_deref(ld); - } - } - uport->icount.cts++; if (uart_softcts_mode(uport)) { diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 4e2ba4894dcc..047fa67d039b 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -257,8 +257,7 @@ struct uart_port { struct device *dev; /* parent device */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; - unsigned char pps_4wire; /* CTS instead of DCD */ - unsigned char unused; + unsigned char unused[2]; const char *name; /* port name */ struct attribute_group *attr_group; /* port specific attributes */ const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ -- cgit v1.2.3 From 1611c686c1245408c3ddb451b2a5fff1dc088d6e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2018 07:37:18 -0400 Subject: media: vidioc-dqevent.rst: clarify V4L2_EVENT_SRC_CH_RESOLUTION Clarify that when you receive V4L2_EVENT_SOURCE_CHANGE with flag V4L2_EVENT_SRC_CH_RESOLUTION set, and the new resolution appears identical to the old resolution, then you still must restart the streaming I/O. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/vidioc-dqevent.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst index cb3565f36793..04416b6943c0 100644 --- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst +++ b/Documentation/media/uapi/v4l/vidioc-dqevent.rst @@ -379,7 +379,17 @@ call. - 0x0001 - This event gets triggered when a resolution change is detected at an input. This can come from an input connector or from a video - decoder. + decoder. Applications will have to query the new resolution (if + any, the signal may also have been lost). + + *Important*: even if the new video timings appear identical to the old + ones, receiving this event indicates that there was an issue with the + video signal and you must stop and restart streaming + (:ref:`VIDIOC_STREAMOFF ` + followed by :ref:`VIDIOC_STREAMON `). The reason is + that many devices are not able to recover from a temporary loss of + signal and so restarting streaming I/O is required in order for the + hardware to synchronize to the video signal. Return Value -- cgit v1.2.3 From c4a570179cf4eb19a75ee27debd541d2f442da44 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:20 -0400 Subject: media: v4l2-subdev.rst: Update doc regarding subdev descriptors Update the doc to describe the new method of adding subdevice descriptors to async notifiers. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/v4l2-subdev.rst | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/kapi/v4l2-subdev.rst b/Documentation/media/kapi/v4l2-subdev.rst index e1f0b726e438..1280e05b662b 100644 --- a/Documentation/media/kapi/v4l2-subdev.rst +++ b/Documentation/media/kapi/v4l2-subdev.rst @@ -247,20 +247,28 @@ performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices registered this way are stored in a global list of subdevices, ready to be picked up by bridge drivers. -Bridge drivers in turn have to register a notifier object with an array of -subdevice descriptors that the bridge device needs for its operation. This is +Bridge drivers in turn have to register a notifier object. This is performed using the :c:func:`v4l2_async_notifier_register` call. To unregister the notifier the driver has to call :c:func:`v4l2_async_notifier_unregister`. The former of the two functions -takes two arguments: a pointer to struct :c:type:`v4l2_device` and a pointer to -struct :c:type:`v4l2_async_notifier`. The latter contains a pointer to an array -of pointers to subdevice descriptors of type struct :c:type:`v4l2_async_subdev` -type. The V4L2 core will then use these descriptors to match asynchronously -registered -subdevices to them. If a match is detected the ``.bound()`` notifier callback -is called. After all subdevices have been located the .complete() callback is -called. When a subdevice is removed from the system the .unbind() method is -called. All three callbacks are optional. +takes two arguments: a pointer to struct :c:type:`v4l2_device` and a +pointer to struct :c:type:`v4l2_async_notifier`. + +Before registering the notifier, bridge drivers must do two things: +first, the notifier must be initialized using the +:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then +begin to form a list of subdevice descriptors that the bridge device +needs for its operation. Subdevice descriptors are added to the notifier +using the :c:func:`v4l2_async_notifier_add_subdev` call. This function +takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`, +and a pointer to the subdevice descripter, which is of type struct +:c:type:`v4l2_async_subdev`. + +The V4L2 core will then use these descriptors to match asynchronously +registered subdevices to them. If a match is detected the ``.bound()`` +notifier callback is called. After all subdevices have been located the +.complete() callback is called. When a subdevice is removed from the +system the .unbind() method is called. All three callbacks are optional. V4L2 sub-device userspace API ----------------------------- -- cgit v1.2.3 From 7e84dd0b15e66a6962aae08c1e2c93075ef5c21d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 2 Jan 2018 08:12:35 -0500 Subject: media: dt-bindings: media: Specify bus type for MIPI D-PHY, others, explicitly Allow specifying the bus type explicitly for MIPI D-PHY, parallel and Bt.656 busses. This is useful for devices that can make use of different bus types. There are CSI-2 transmitters and receivers but the PHY selection needs to be made between C-PHY and D-PHY; many devices also support parallel and Bt.656 interfaces but the means to pass that information to software wasn't there. Autodetection (value 0) is removed as an option as the property could be simply omitted in that case. Signed-off-by: Sakari Ailus Reviewed-by: Rob Herring Acked-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/video-interfaces.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt index baf9d9756b3c..f884ada0bffc 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.txt +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt @@ -100,10 +100,12 @@ Optional endpoint properties slave device (data source) by the master device (data sink). In the master mode the data source device is also the source of the synchronization signals. - bus-type: data bus type. Possible values are: - 0 - autodetect based on other properties (MIPI CSI-2 D-PHY, parallel or Bt656) 1 - MIPI CSI-2 C-PHY 2 - MIPI CSI1 3 - CCP2 + 4 - MIPI CSI-2 D-PHY + 5 - Parallel + 6 - Bt.656 - bus-width: number of data lines actively used, valid for the parallel busses. - data-shift: on the parallel data busses, if bus-width is used to specify the number of data lines, data-shift can be used to specify which data lines are -- cgit v1.2.3 From 59e7d5112799f32702f16fe388743c59e5513f08 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Thu, 13 Sep 2018 09:59:49 -0400 Subject: media: dt-bindings: media: renesas-ceu: Refer to video-interfaces.txt Refer to video-interfaces.txt when describing standard properties. Signed-off-by: Jacopo Mondi Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/renesas,ceu.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.txt b/Documentation/devicetree/bindings/media/renesas,ceu.txt index 8a7a616e9019..23e911067c8f 100644 --- a/Documentation/devicetree/bindings/media/renesas,ceu.txt +++ b/Documentation/devicetree/bindings/media/renesas,ceu.txt @@ -17,15 +17,15 @@ Required properties: The CEU supports a single parallel input and should contain a single 'port' subnode with a single 'endpoint'. Connection to input devices are modeled according to the video interfaces OF bindings specified in: -Documentation/devicetree/bindings/media/video-interfaces.txt +[1] Documentation/devicetree/bindings/media/video-interfaces.txt Optional endpoint properties applicable to parallel input bus described in the above mentioned "video-interfaces.txt" file are supported. -- hsync-active: Active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. - If property is not present, default is active high. -- vsync-active: Active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. - If property is not present, default is active high. +- hsync-active: See [1] for description. If property is not present, + default is active high. +- vsync-active: See [1] for description. If property is not present, + default is active high. Example: -- cgit v1.2.3 From 6a3da2e2a43aeb295f2d4541e7e7efb0b6349b3a Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Thu, 13 Sep 2018 09:59:50 -0400 Subject: media: dt-bindings: media: renesas-ceu: Add more endpoint properties As the v4l2-fwnode framework now allows specifying defaults configurations, expand the description of the optional endpoint properties for the CEU interface to better explain which are their defaults values. Signed-off-by: Jacopo Mondi Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/renesas,ceu.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.txt b/Documentation/devicetree/bindings/media/renesas,ceu.txt index 23e911067c8f..3e2a2652eb19 100644 --- a/Documentation/devicetree/bindings/media/renesas,ceu.txt +++ b/Documentation/devicetree/bindings/media/renesas,ceu.txt @@ -26,6 +26,10 @@ the above mentioned "video-interfaces.txt" file are supported. default is active high. - vsync-active: See [1] for description. If property is not present, default is active high. +- bus-width: See [1] for description. Accepted values are '8' and '16'. + If property is not present, default is '8'. +- field-even-active: See [1] for description. If property is not present, + an even field is identified by a logic 0 (active-low signal). Example: -- cgit v1.2.3 From fd2a9f18fce11f09747f1807d1298a6d9dfe8f9b Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Wed, 3 Oct 2018 11:09:09 +0200 Subject: dt-bindings: clock: mediatek: add support for MT7623 This patch adds bindings for apmixedsys, audsys, bpsys, ethsys, hifsys, imgsys, infracfg, mmsys, pericfg, topckgen and vdecsys for MT6723. Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt | 1 + Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt | 1 + 11 files changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt index b404d592ce58..4e4a3c0ab9ab 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt @@ -10,6 +10,7 @@ Required Properties: - "mediatek,mt2712-apmixedsys", "syscon" - "mediatek,mt6797-apmixedsys" - "mediatek,mt7622-apmixedsys" + - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys" - "mediatek,mt8135-apmixedsys" - "mediatek,mt8173-apmixedsys" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index 34a69ba67f13..d1606b2c3e63 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-audsys", "syscon" - "mediatek,mt7622-audsys", "syscon" + - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" - #clock-cells: Must be 1 The AUDSYS controller uses the common clk binding from diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt index 4010e37c53a0..149567a38215 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be: - "mediatek,mt2701-bdpsys", "syscon" - "mediatek,mt2712-bdpsys", "syscon" + - "mediatek,mt7623-bdpsys", "mediatek,mt2701-bdpsys", "syscon" - #clock-cells: Must be 1 The bdpsys controller uses the common clk binding from diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt index 8f5335b480ac..f17cfe64255d 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be: - "mediatek,mt2701-ethsys", "syscon" - "mediatek,mt7622-ethsys", "syscon" + - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon" - #clock-cells: Must be 1 - #reset-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt index f5629d64cef2..323905af82c3 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt @@ -9,6 +9,7 @@ Required Properties: - compatible: Should be: - "mediatek,mt2701-hifsys", "syscon" - "mediatek,mt7622-hifsys", "syscon" + - "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon" - #clock-cells: Must be 1 The hifsys controller uses the common clk binding from diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt index 868bd51a98be..3f99672163e3 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt @@ -9,6 +9,7 @@ Required Properties: - "mediatek,mt2701-imgsys", "syscon" - "mediatek,mt2712-imgsys", "syscon" - "mediatek,mt6797-imgsys", "syscon" + - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon" - "mediatek,mt8173-imgsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt index 566f153f9f83..89f4272a1441 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt @@ -11,6 +11,7 @@ Required Properties: - "mediatek,mt2712-infracfg", "syscon" - "mediatek,mt6797-infracfg", "syscon" - "mediatek,mt7622-infracfg", "syscon" + - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon" - "mediatek,mt8135-infracfg", "syscon" - "mediatek,mt8173-infracfg", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt index 4eb8bbe15c01..15d977afad31 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt @@ -9,6 +9,7 @@ Required Properties: - "mediatek,mt2701-mmsys", "syscon" - "mediatek,mt2712-mmsys", "syscon" - "mediatek,mt6797-mmsys", "syscon" + - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon" - "mediatek,mt8173-mmsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt index fb58ca8c2770..6755514deb80 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt @@ -10,6 +10,7 @@ Required Properties: - "mediatek,mt2701-pericfg", "syscon" - "mediatek,mt2712-pericfg", "syscon" - "mediatek,mt7622-pericfg", "syscon" + - "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon" - "mediatek,mt8135-pericfg", "syscon" - "mediatek,mt8173-pericfg", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt index 24014a7e2332..d849465b8c99 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt @@ -10,6 +10,7 @@ Required Properties: - "mediatek,mt2712-topckgen", "syscon" - "mediatek,mt6797-topckgen" - "mediatek,mt7622-topckgen" + - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen" - "mediatek,mt8135-topckgen" - "mediatek,mt8173-topckgen" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt index ea40d05089f8..3212afc753c8 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt @@ -9,6 +9,7 @@ Required Properties: - "mediatek,mt2701-vdecsys", "syscon" - "mediatek,mt2712-vdecsys", "syscon" - "mediatek,mt6797-vdecsys", "syscon" + - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon" - "mediatek,mt8173-vdecsys", "syscon" - #clock-cells: Must be 1 -- cgit v1.2.3 From 0dd807f52e6fd225c19e26683406a6e5d475370e Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Wed, 3 Oct 2018 11:09:10 +0200 Subject: dt-bindings: iommu: mediatek: Add binding for MT7623 This patch adds binding documentation for MT7623 SoC. Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/iommu/mediatek,iommu.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt index df5db732138d..6922db598def 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt @@ -41,6 +41,8 @@ Required properties: - compatible : must be one of the following string: "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW. "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW. + "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses + generation one m4u HW. "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. - reg : m4u register base and size. - interrupts : the interrupt of m4u. @@ -51,7 +53,7 @@ Required properties: according to the local arbiter index, like larb0, larb1, larb2... - iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. Specifies the mtk_m4u_id as defined in - dt-binding/memory/mt2701-larb-port.h for mt2701, + dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623 dt-binding/memory/mt2712-larb-port.h for mt2712, and dt-binding/memory/mt8173-larb-port.h for mt8173. -- cgit v1.2.3 From 1892e120e8ecac868f9ddde988152c3499c9b04b Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Wed, 3 Oct 2018 11:09:11 +0200 Subject: dt-bindings: mediatek: Add JPEG Decoder binding for MT7623 This patch adds a binding documentation for the JPEG Decoder of the MT7623 SoC. Signed-off-by: Matthias Brugger --- Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt index 3813947b4d4f..044b11913c49 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt @@ -5,6 +5,7 @@ Mediatek JPEG Decoder is the JPEG decode hardware present in Mediatek SoCs Required properties: - compatible : must be one of the following string: "mediatek,mt8173-jpgdec" + "mediatek,mt7623-jpgdec", "mediatek,mt2701-jpgdec" "mediatek,mt2701-jpgdec" - reg : physical base address of the jpeg decoder registers and length of memory mapped region. -- cgit v1.2.3 From f5e489e6ee7a7c8fb7c3ed3997597a109f0813aa Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Wed, 3 Oct 2018 11:09:12 +0200 Subject: dt-bindings: mediatek: Add bindig for MT7623 IOMMU and SMI This patch add the binding documentation for the iommu and smi devices on the MT7623 SoC. Signed-off-by: Matthias Brugger --- .../devicetree/bindings/memory-controllers/mediatek,smi-common.txt | 1 + .../devicetree/bindings/memory-controllers/mediatek,smi-larb.txt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt index 615abdd0eb0d..e937ddd871a6 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt @@ -17,6 +17,7 @@ Required properties: - compatible : must be one of : "mediatek,mt2701-smi-common" "mediatek,mt2712-smi-common" + "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common" "mediatek,mt8173-smi-common" - reg : the register and size of the SMI block. - power-domains : a phandle to the power domain of this local arbiter. diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt index 083155cdc2a0..94eddcae77ab 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -6,6 +6,7 @@ Required properties: - compatible : must be one of : "mediatek,mt2701-smi-larb" "mediatek,mt2712-smi-larb" + "mediatek,mt7623-smi-larb", "mediatek,mt2701-smi-larb" "mediatek,mt8173-smi-larb" - reg : the register and size of this local arbiter. - mediatek,smi : a phandle to the smi_common node. @@ -16,7 +17,7 @@ Required properties: the register. - "smi" : It's the clock for transfer data and command. -Required property for mt2701 and mt2712: +Required property for mt2701, mt2712 and mt7623: - mediatek,larb-id :the hardware id of this larb. Example: -- cgit v1.2.3 From 032f11638ff8e0a02d9cd49ef85e185cd0326d03 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 30 Aug 2018 00:42:10 +0530 Subject: dt-bindings: reset: Add PDC Global binding for SDM845 SoCs Add PDC Global (Power Domain Controller) binding for SDM845 SoCs. Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Signed-off-by: Sibi Sankar Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/qcom,pdc-global.txt | 52 ++++++++++++++++++++++ include/dt-bindings/reset/qcom,sdm845-pdc.h | 20 +++++++++ 2 files changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/qcom,pdc-global.txt create mode 100644 include/dt-bindings/reset/qcom,sdm845-pdc.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt b/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt new file mode 100644 index 000000000000..a62a492843e7 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt @@ -0,0 +1,52 @@ +PDC Global +====================================== + +This binding describes a reset-controller found on PDC-Global (Power Domain +Controller) block for Qualcomm Technologies Inc SDM845 SoCs. + +Required properties: +- compatible: + Usage: required + Value type: + Definition: must be: + "qcom,sdm845-pdc-global" + +- reg: + Usage: required + Value type: + Definition: must specify the base address and size of the register + space. + +- #reset-cells: + Usage: required + Value type: + Definition: must be 1; cell entry represents the reset index. + +Example: + +pdc_reset: reset-controller@b2e0000 { + compatible = "qcom,sdm845-pdc-global"; + reg = <0xb2e0000 0x20000>; + #reset-cells = <1>; +}; + +PDC reset clients +====================================== + +Device nodes that need access to reset lines should +specify them as a reset phandle in their corresponding node as +specified in reset.txt. + +For a list of all valid reset indices see + + +Example: + +modem-pil@4080000 { + ... + + resets = <&pdc_reset PDC_MODEM_SYNC_RESET>; + reset-names = "pdc_reset"; + + ... +}; diff --git a/include/dt-bindings/reset/qcom,sdm845-pdc.h b/include/dt-bindings/reset/qcom,sdm845-pdc.h new file mode 100644 index 000000000000..53c37f9c319a --- /dev/null +++ b/include/dt-bindings/reset/qcom,sdm845-pdc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_RESET_PDC_SDM_845_H +#define _DT_BINDINGS_RESET_PDC_SDM_845_H + +#define PDC_APPS_SYNC_RESET 0 +#define PDC_SP_SYNC_RESET 1 +#define PDC_AUDIO_SYNC_RESET 2 +#define PDC_SENSORS_SYNC_RESET 3 +#define PDC_AOP_SYNC_RESET 4 +#define PDC_DEBUG_SYNC_RESET 5 +#define PDC_GPU_SYNC_RESET 6 +#define PDC_DISPLAY_SYNC_RESET 7 +#define PDC_COMPUTE_SYNC_RESET 8 +#define PDC_MODEM_SYNC_RESET 9 + +#endif -- cgit v1.2.3 From e4183d3256e3cd668e899d06af66da5aac3a51af Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 4 Oct 2018 20:12:21 -0400 Subject: media: dt-bindings: Document the Rockchip VPU bindings Add devicetree binding documentation for Rockchip Video Processing Unit IP. Reviewed-by: Rob Herring Signed-off-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/rockchip-vpu.txt | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/rockchip-vpu.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.txt b/Documentation/devicetree/bindings/media/rockchip-vpu.txt new file mode 100644 index 000000000000..35dc464ad7c8 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip-vpu.txt @@ -0,0 +1,29 @@ +device-tree bindings for rockchip VPU codec + +Rockchip (Video Processing Unit) present in various Rockchip platforms, +such as RK3288 and RK3399. + +Required properties: +- compatible: value should be one of the following + "rockchip,rk3288-vpu"; + "rockchip,rk3399-vpu"; +- interrupts: encoding and decoding interrupt specifiers +- interrupt-names: should be "vepu" and "vdpu" +- clocks: phandle to VPU aclk, hclk clocks +- clock-names: should be "aclk" and "hclk" +- power-domains: phandle to power domain node +- iommus: phandle to a iommu node + +Example: +SoC-specific DT entry: + vpu: video-codec@ff9a0000 { + compatible = "rockchip,rk3288-vpu"; + reg = <0x0 0xff9a0000 0x0 0x800>; + interrupts = , + ; + interrupt-names = "vepu", "vdpu"; + clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; + clock-names = "aclk", "hclk"; + power-domains = <&power RK3288_PD_VIDEO>; + iommus = <&vpu_mmu>; + }; -- cgit v1.2.3 From 81e33279d154599db64d608b2a1db619f3b56ce1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Oct 2018 08:58:12 -0400 Subject: media: cec-core.rst: improve cec_transmit_done documentation Clarify that calling cec_transmit_done can start a new transmit and that you should put the hardware in a state that allows for a new transmit before calling this function. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/cec-core.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 1d989c544370..bca1d9d1d223 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -268,6 +268,10 @@ to 1, if the hardware does support retry then either set these counters to 0 if the hardware provides no feedback of which errors occurred and how many times, or fill in the correct values as reported by the hardware. +Be aware that calling these functions can immediately start a new transmit +if there is one pending in the queue. So make sure that the hardware is in +a state where new transmits can be started *before* calling these functions. + The cec_transmit_attempt_done() function is a helper for cases where the hardware never retries, so the transmit is always for just a single attempt. It will call cec_transmit_done() in turn, filling in 1 for the -- cgit v1.2.3 From 7ec2b3b941a666a942859684281b5f6460a0c234 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 4 Oct 2018 03:28:21 -0400 Subject: media: cec: add new tx/rx status bits to detect aborts/timeouts If the HDMI cable is disconnected or the CEC adapter is manually unconfigured, then all pending transmits and wait-for-replies are aborted. Signal this with new status bits (CEC_RX/TX_STATUS_ABORTED). If due to (usually) a driver bug a transmit never ends (i.e. the transmit_done was never called by the driver), then when this times out the message is marked with CEC_TX_STATUS_TIMEOUT. This should not happen and is an indication of a driver bug. Without a separate status bit for this it was impossible to detect this from userspace. The 'transmit timed out' kernel message is now a warning, so this should be more prominent in the kernel log as well. Signed-off-by: Hans Verkuil Cc: # for v4.18 and up Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-receive.rst | 25 ++++++++- drivers/media/cec/cec-adap.c | 66 +++++++----------------- include/uapi/linux/cec.h | 3 ++ 3 files changed, 44 insertions(+), 50 deletions(-) (limited to 'Documentation') diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index e964074cd15b..b25e48afaa08 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -16,10 +16,10 @@ CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message Synopsis ======== -.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg *argp ) +.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg \*argp ) :name: CEC_RECEIVE -.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg *argp ) +.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg \*argp ) :name: CEC_TRANSMIT Arguments @@ -272,6 +272,19 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - The transmit failed after one or more retries. This status bit is mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still be set to explain which failures were seen. + * .. _`CEC-TX-STATUS-ABORTED`: + + - ``CEC_TX_STATUS_ABORTED`` + - 0x40 + - The transmit was aborted due to an HDMI disconnect, or the adapter + was unconfigured, or a transmit was interrupted, or the driver + returned an error when attempting to start a transmit. + * .. _`CEC-TX-STATUS-TIMEOUT`: + + - ``CEC_TX_STATUS_TIMEOUT`` + - 0x80 + - The transmit timed out. This should not normally happen and this + indicates a driver problem. .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| @@ -300,6 +313,14 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - The message was received successfully but the reply was ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message was the reply to an earlier transmitted message. + * .. _`CEC-RX-STATUS-ABORTED`: + + - ``CEC_RX_STATUS_ABORTED`` + - 0x08 + - The wait for a reply to an earlier transmitted message was aborted + because the HDMI cable was disconnected, the adapter was unconfigured + or the :ref:`CEC_TRANSMIT ` that waited for a + reply was interrupted. diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 829878356e1e..e6e82b504e56 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -354,7 +354,7 @@ static void cec_data_completed(struct cec_data *data) * * This function is called with adap->lock held. */ -static void cec_data_cancel(struct cec_data *data) +static void cec_data_cancel(struct cec_data *data, u8 tx_status) { /* * It's either the current transmit, or it is a pending @@ -369,13 +369,11 @@ static void cec_data_cancel(struct cec_data *data) } if (data->msg.tx_status & CEC_TX_STATUS_OK) { - /* Mark the canceled RX as a timeout */ data->msg.rx_ts = ktime_get_ns(); - data->msg.rx_status = CEC_RX_STATUS_TIMEOUT; + data->msg.rx_status = CEC_RX_STATUS_ABORTED; } else { - /* Mark the canceled TX as an error */ data->msg.tx_ts = ktime_get_ns(); - data->msg.tx_status |= CEC_TX_STATUS_ERROR | + data->msg.tx_status |= tx_status | CEC_TX_STATUS_MAX_RETRIES; data->msg.tx_error_cnt++; data->attempts = 0; @@ -403,15 +401,15 @@ static void cec_flush(struct cec_adapter *adap) while (!list_empty(&adap->transmit_queue)) { data = list_first_entry(&adap->transmit_queue, struct cec_data, list); - cec_data_cancel(data); + cec_data_cancel(data, CEC_TX_STATUS_ABORTED); } if (adap->transmitting) - cec_data_cancel(adap->transmitting); + cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED); /* Cancel the pending timeout work. */ list_for_each_entry_safe(data, n, &adap->wait_queue, list) { if (cancel_delayed_work(&data->work)) - cec_data_cancel(data); + cec_data_cancel(data, CEC_TX_STATUS_OK); /* * If cancel_delayed_work returned false, then * the cec_wait_timeout function is running, @@ -487,12 +485,13 @@ int cec_thread_func(void *_adap) * so much traffic on the bus that the adapter was * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). */ - dprintk(1, "%s: message %*ph timed out\n", __func__, + pr_warn("cec-%s: message %*ph timed out\n", adap->name, adap->transmitting->msg.len, adap->transmitting->msg.msg); adap->tx_timeouts++; /* Just give up on this. */ - cec_data_cancel(adap->transmitting); + cec_data_cancel(adap->transmitting, + CEC_TX_STATUS_TIMEOUT); goto unlock; } @@ -543,7 +542,7 @@ int cec_thread_func(void *_adap) /* Tell the adapter to transmit, cancel on error */ if (adap->ops->adap_transmit(adap, data->attempts, signal_free_time, &data->msg)) - cec_data_cancel(data); + cec_data_cancel(data, CEC_TX_STATUS_ABORTED); unlock: mutex_unlock(&adap->lock); @@ -715,8 +714,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, { struct cec_data *data; u8 last_initiator = 0xff; - unsigned int timeout; - int res = 0; msg->rx_ts = 0; msg->tx_ts = 0; @@ -858,48 +855,21 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, if (!block) return 0; - /* - * If we don't get a completion before this time something is really - * wrong and we time out. - */ - timeout = CEC_XFER_TIMEOUT_MS; - /* Add the requested timeout if we have to wait for a reply as well */ - if (msg->timeout) - timeout += msg->timeout; - /* * Release the lock and wait, retake the lock afterwards. */ mutex_unlock(&adap->lock); - res = wait_for_completion_killable_timeout(&data->c, - msecs_to_jiffies(timeout)); + wait_for_completion_killable(&data->c); mutex_lock(&adap->lock); - if (data->completed) { - /* The transmit completed (possibly with an error) */ - *msg = data->msg; - kfree(data); - return 0; - } - /* - * The wait for completion timed out or was interrupted, so mark this - * as non-blocking and disconnect from the filehandle since it is - * still 'in flight'. When it finally completes it will just drop the - * result silently. - */ - data->blocking = false; - if (data->fh) - list_del(&data->xfer_list); - data->fh = NULL; + /* Cancel the transmit if it was interrupted */ + if (!data->completed) + cec_data_cancel(data, CEC_TX_STATUS_ABORTED); - if (res == 0) { /* timed out */ - /* Check if the reply or the transmit failed */ - if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK)) - msg->rx_status = CEC_RX_STATUS_TIMEOUT; - else - msg->tx_status = CEC_TX_STATUS_MAX_RETRIES; - } - return res > 0 ? 0 : res; + /* The transmit completed (possibly with an error) */ + *msg = data->msg; + kfree(data); + return 0; } /* Helper function to be used by drivers and this framework. */ diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index 097fcd812471..3094af68b6e7 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -152,10 +152,13 @@ static inline void cec_msg_set_reply_to(struct cec_msg *msg, #define CEC_TX_STATUS_LOW_DRIVE (1 << 3) #define CEC_TX_STATUS_ERROR (1 << 4) #define CEC_TX_STATUS_MAX_RETRIES (1 << 5) +#define CEC_TX_STATUS_ABORTED (1 << 6) +#define CEC_TX_STATUS_TIMEOUT (1 << 7) #define CEC_RX_STATUS_OK (1 << 0) #define CEC_RX_STATUS_TIMEOUT (1 << 1) #define CEC_RX_STATUS_FEATURE_ABORT (1 << 2) +#define CEC_RX_STATUS_ABORTED (1 << 3) static inline int cec_msg_status_is_ok(const struct cec_msg *msg) { -- cgit v1.2.3 From f861164526d99e0f161e709da56736d29d1b781c Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 30 Aug 2018 00:42:12 +0530 Subject: dt-bindings: remoteproc: qcom: Remove additional definition tag Remove the additional definition tag declared for WCSS sub-system under reset-names. Reviewed-by: Rob Herring Reviewed-by: Matthias Kaehlcke Signed-off-by: Sibi Sankar Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt index 601dd9f389aa..3a66cde5895a 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -58,8 +58,8 @@ on the Qualcomm Hexagon core. Usage: required Value type: Definition: must be "mss_restart" for the modem sub-system - Definition: must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset" - for the wcss syb-system + must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset" + for the wcss sub-system - cx-supply: - mss-supply: -- cgit v1.2.3 From 9a6696155f0dd85173ec079000386935682773aa Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 30 Aug 2018 00:42:13 +0530 Subject: dt-bindings: remoteproc: Add PDC reset binding for Q6V5 PIL Add additional pdc_reset binding required for Q6V5 Modem PIL on SDM845 SoCs. Reviewed-by: Rob Herring Signed-off-by: Sibi Sankar Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt index 3a66cde5895a..9ff5b0309417 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -53,6 +53,8 @@ on the Qualcomm Hexagon core. Definition: reference to the reset-controller for the modem sub-system reference to the list of 3 reset-controllers for the wcss sub-system + reference to the list of 2 reset-controllers for the modem + sub-system on SDM845 SoCs - reset-names: Usage: required @@ -60,6 +62,8 @@ on the Qualcomm Hexagon core. Definition: must be "mss_restart" for the modem sub-system must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset" for the wcss sub-system + must be "mss_restart", "pdc_reset" for the modem + sub-system on SDM845 SoCs - cx-supply: - mss-supply: -- cgit v1.2.3 From 159accc4d05de234f485366163e9084a73baa63b Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 11 Sep 2018 09:24:01 +0530 Subject: dt-binding: remoteproc: Add QTI ADSP PIL bindings Add devicetree bindings documentation file for Qualcomm Technolgies Inc ADSP Peripheral Image Loader. Reviewed-by: Rob Herring Signed-off-by: Rohit kumar Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,adsp-pil.txt | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt new file mode 100644 index 000000000000..a842a782b557 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt @@ -0,0 +1,126 @@ +Qualcomm Technology Inc. ADSP Peripheral Image Loader + +This document defines the binding for a component that loads and boots firmware +on the Qualcomm Technology Inc. ADSP Hexagon core. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,sdm845-adsp-pil" + +- reg: + Usage: required + Value type: + Definition: must specify the base address and size of the qdsp6ss register + +- interrupts-extended: + Usage: required + Value type: + Definition: must list the watchdog, fatal IRQs ready, handover and + stop-ack IRQs + +- interrupt-names: + Usage: required + Value type: + Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack" + +- clocks: + Usage: required + Value type: + Definition: List of 8 phandle and clock specifier pairs for the adsp. + +- clock-names: + Usage: required + Value type: + Definition: List of clock input name strings sorted in the same + order as the clocks property. Definition must have + "xo", "sway_cbcr", "lpass_aon", "lpass_ahbs_aon_cbcr", + "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep" + and "qdsp6ss_core". + +- power-domains: + Usage: required + Value type: + Definition: reference to cx power domain node. + +- resets: + Usage: required + Value type: + Definition: reference to the list of 2 reset-controller for the adsp. + +- reset-names: + Usage: required + Value type: + Definition: must be "pdc_sync" and "cc_lpass" + +- qcom,halt-regs: + Usage: required + Value type: + Definition: a phandle reference to a syscon representing TCSR followed + by the offset within syscon for lpass halt register. + +- memory-region: + Usage: required + Value type: + Definition: reference to the reserved-memory for the ADSP + +- qcom,smem-states: + Usage: required + Value type: + Definition: reference to the smem state for requesting the ADSP to + shut down + +- qcom,smem-state-names: + Usage: required + Value type: + Definition: must be "stop" + + += SUBNODES +The adsp node may have an subnode named "glink-edge" that describes the +communication edge, channels and devices related to the ADSP. +See ../soc/qcom/qcom,glink.txt for details on how to describe these. + += EXAMPLE +The following example describes the resources needed to boot control the +ADSP, as it is found on SDM845 boards. + + remoteproc@17300000 { + compatible = "qcom,sdm845-adsp-pil"; + reg = <0x17300000 0x40c>; + + interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_LPASS_SWAY_CLK>, + <&lpasscc LPASS_AUDIO_WRAPPER_AON_CLK>, + <&lpasscc LPASS_Q6SS_AHBS_AON_CLK>, + <&lpasscc LPASS_Q6SS_AHBM_AON_CLK>, + <&lpasscc LPASS_QDSP6SS_XO_CLK>, + <&lpasscc LPASS_QDSP6SS_SLEEP_CLK>, + <&lpasscc LPASS_QDSP6SS_CORE_CLK>; + clock-names = "xo", "sway_cbcr", "lpass_aon", + "lpass_ahbs_aon_cbcr", + "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", + "qdsp6ss_sleep", "qdsp6ss_core"; + + power-domains = <&rpmhpd SDM845_CX>; + + resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>, + <&aoss_reset AOSS_CC_LPASS_RESTART>; + reset-names = "pdc_sync", "cc_lpass"; + + qcom,halt-regs = <&tcsr_mutex_regs 0x22000>; + + memory-region = <&pil_adsp_mem>; + + qcom,smem-states = <&adsp_smp2p_out 0>; + qcom,smem-state-names = "stop"; + }; -- cgit v1.2.3 From c6c2ee00fe2fb003cd95ac89526511a537103e2d Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Sun, 7 Oct 2018 21:04:41 +0800 Subject: dt-bindings: arm: fsl: add scu binding doc The System Controller Firmware (SCFW) is a low-level system function which runs on a dedicated Cortex-M core to provide power, clock, and resource management. It exists on some i.MX8 processors. e.g. i.MX8QM (QM, QP), and i.MX8QX (QXP, DX). Cc: Shawn Guo Cc: Sascha Hauer Cc: Fabio Estevam Cc: Mark Rutland Cc: devicetree@vger.kernel.org Reviewed-by: Rob Herring Reviewed-by: Sascha Hauer Signed-off-by: Dong Aisheng Signed-off-by: Shawn Guo --- .../devicetree/bindings/arm/freescale/fsl,scu.txt | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt new file mode 100644 index 000000000000..46d0af1f0872 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt @@ -0,0 +1,183 @@ +NXP i.MX System Controller Firmware (SCFW) +-------------------------------------------------------------------- + +The System Controller Firmware (SCFW) is a low-level system function +which runs on a dedicated Cortex-M core to provide power, clock, and +resource management. It exists on some i.MX8 processors. e.g. i.MX8QM +(QM, QP), and i.MX8QX (QXP, DX). + +The AP communicates with the SC using a multi-ported MU module found +in the LSIO subsystem. The current definition of this MU module provides +5 remote AP connections to the SC to support up to 5 execution environments +(TZ, HV, standard Linux, etc.). The SC side of this MU module interfaces +with the LSIO DSC IP bus. The SC firmware will communicate with this MU +using the MSI bus. + +System Controller Device Node: +============================================================ + +The scu node with the following properties shall be under the /firmware/ node. + +Required properties: +------------------- +- compatible: should be "fsl,imx-scu". +- mbox-names: should include "tx0", "tx1", "tx2", "tx3", + "rx0", "rx1", "rx2", "rx3". +- mboxes: List of phandle of 4 MU channels for tx and 4 MU channels + for rx. All 8 MU channels must be in the same MU instance. + Cross instances are not allowed. The MU instance can only + be one of LSIO MU0~M4 for imx8qxp and imx8qm. Users need + to make sure use the one which is not conflict with other + execution environments. e.g. ATF. + Note: + Channel 0 must be "tx0" or "rx0". + Channel 1 must be "tx1" or "rx1". + Channel 2 must be "tx2" or "rx2". + Channel 3 must be "tx3" or "rx3". + e.g. + mboxes = <&lsio_mu1 0 0 + &lsio_mu1 0 1 + &lsio_mu1 0 2 + &lsio_mu1 0 3 + &lsio_mu1 1 0 + &lsio_mu1 1 1 + &lsio_mu1 1 2 + &lsio_mu1 1 3>; + See Documentation/devicetree/bindings/mailbox/fsl,mu.txt + for detailed mailbox binding. + +i.MX SCU Client Device Node: +============================================================ + +Client nodes are maintained as children of the relevant IMX-SCU device node. + +Power domain bindings based on SCU Message Protocol +------------------------------------------------------------ + +This binding for the SCU power domain providers uses the generic power +domain binding[2]. + +Required properties: +- compatible: Should be "fsl,scu-pd". +- #address-cells: Should be 1. +- #size-cells: Should be 0. + +Required properties for power domain sub nodes: +- #power-domain-cells: Must be 0. + +Optional Properties: +- reg: Resource ID of this power domain. + No exist means uncontrollable by user. + See detailed Resource ID list from: + include/dt-bindings/power/imx-rsrc.h +- power-domains: phandle pointing to the parent power domain. + +Clock bindings based on SCU Message Protocol +------------------------------------------------------------ + +This binding uses the common clock binding[1]. + +Required properties: +- compatible: Should be "fsl,imx8qxp-clock". +- #clock-cells: Should be 1. Contains the Clock ID value. +- clocks: List of clock specifiers, must contain an entry for + each required entry in clock-names +- clock-names: Should include entries "xtal_32KHz", "xtal_24MHz" + +The clock consumer should specify the desired clock by having the clock +ID in its "clocks" phandle cell. + +See the full list of clock IDs from: +include/dt-bindings/clock/imx8qxp-clock.h + +Pinctrl bindings based on SCU Message Protocol +------------------------------------------------------------ + +This binding uses the i.MX common pinctrl binding[3]. + +Required properties: +- compatible: Should be "fsl,imx8qxp-iomuxc". + +Required properties for Pinctrl sub nodes: +- fsl,pins: Each entry consists of 3 integers which represents + the mux and config setting for one pin. The first 2 + integers are specified using a + PIN_FUNC_ID macro, which can be found in + . + The last integer CONFIG is the pad setting value like + pull-up on this pin. + + Please refer to i.MX8QXP Reference Manual for detailed + CONFIG settings. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/power/power_domain.txt +[3] Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt + +Example (imx8qxp): +------------- +lsio_mu1: mailbox@5d1c0000 { + ... + #mbox-cells = <2>; +}; + +firmware { + scu { + compatible = "fsl,imx-scu"; + mbox-names = "tx0", "tx1", "tx2", "tx3", + "rx0", "rx1", "rx2", "rx3"; + mboxes = <&lsio_mu1 0 0 + &lsio_mu1 0 1 + &lsio_mu1 0 2 + &lsio_mu1 0 3 + &lsio_mu1 1 0 + &lsio_mu1 1 1 + &lsio_mu1 1 2 + &lsio_mu1 1 3>; + + clk: clk { + compatible = "fsl,imx8qxp-clk"; + #clock-cells = <1>; + }; + + iomuxc { + compatible = "fsl,imx8qxp-iomuxc"; + + pinctrl_lpuart0: lpuart0grp { + fsl,pins = < + SC_P_UART0_RX_ADMA_UART0_RX 0x06000020 + SC_P_UART0_TX_ADMA_UART0_TX 0x06000020 + >; + }; + ... + }; + + imx8qx-pm { + compatible = "fsl,scu-pd"; + #address-cells = <1>; + #size-cells = <0>; + + pd_dma: dma-power-domain { + #power-domain-cells = <0>; + + pd_dma_lpuart0: dma-lpuart0@57 { + reg = ; + #power-domain-cells = <0>; + power-domains = <&pd_dma>; + }; + ... + }; + ... + }; + }; +}; + +serial@5a060000 { + ... + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart0>; + clocks = <&clk IMX8QXP_UART0_CLK>, + <&clk IMX8QXP_UART0_IPG_CLK>; + clock-names = "per", "ipg"; + power-domains = <&pd_dma_lpuart0>; +}; -- cgit v1.2.3 From 8cc7bc8ee21f539ffabf4ff7f30a0c6be9ac5ba9 Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Mon, 8 Oct 2018 11:21:43 -0700 Subject: Documentation: xilinx: Add documentation for eemi APIs Add documentation for embedded energy management interface (EEMI) APIs. It includes information about eemi ops and how to use them. It also includes API information and supported IOCTL IDs which can be used for device and control configuration. Signed-off-by: Rajan Vaja Signed-off-by: Jolly Shah Acked-by: Olof Johansson Signed-off-by: Michal Simek --- Documentation/xilinx/eemi.txt | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/xilinx/eemi.txt (limited to 'Documentation') diff --git a/Documentation/xilinx/eemi.txt b/Documentation/xilinx/eemi.txt new file mode 100644 index 000000000000..0ab686c173be --- /dev/null +++ b/Documentation/xilinx/eemi.txt @@ -0,0 +1,67 @@ +--------------------------------------------------------------------- +Xilinx Zynq MPSoC EEMI Documentation +--------------------------------------------------------------------- + +Xilinx Zynq MPSoC Firmware Interface +------------------------------------- +The zynqmp-firmware node describes the interface to platform firmware. +ZynqMP has an interface to communicate with secure firmware. Firmware +driver provides an interface to firmware APIs. Interface APIs can be +used by any driver to communicate with PMC(Platform Management Controller). + +Embedded Energy Management Interface (EEMI) +---------------------------------------------- +The embedded energy management interface is used to allow software +components running across different processing clusters on a chip or +device to communicate with a power management controller (PMC) on a +device to issue or respond to power management requests. + +EEMI ops is a structure containing all eemi APIs supported by Zynq MPSoC. +The zynqmp-firmware driver maintain all EEMI APIs in zynqmp_eemi_ops +structure. Any driver who want to communicate with PMC using EEMI APIs +can call zynqmp_pm_get_eemi_ops(). + +Example of EEMI ops: + + /* zynqmp-firmware driver maintain all EEMI APIs */ + struct zynqmp_eemi_ops { + int (*get_api_version)(u32 *version); + int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out); + }; + + static const struct zynqmp_eemi_ops eemi_ops = { + .get_api_version = zynqmp_pm_get_api_version, + .query_data = zynqmp_pm_query_data, + }; + +Example of EEMI ops usage: + + static const struct zynqmp_eemi_ops *eemi_ops; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + eemi_ops = zynqmp_pm_get_eemi_ops(); + if (!eemi_ops) + return -ENXIO; + + ret = eemi_ops->query_data(qdata, ret_payload); + +IOCTL +------ +IOCTL API is for device control and configuration. It is not a system +IOCTL but it is an EEMI API. This API can be used by master to control +any device specific configuration. IOCTL definitions can be platform +specific. This API also manage shared device configuration. + +The following IOCTL IDs are valid for device control: +- IOCTL_SET_PLL_FRAC_MODE 8 +- IOCTL_GET_PLL_FRAC_MODE 9 +- IOCTL_SET_PLL_FRAC_DATA 10 +- IOCTL_GET_PLL_FRAC_DATA 11 + +Refer EEMI API guide [0] for IOCTL specific parameters and other EEMI APIs. + +References +---------- +[0] Embedded Energy Management Interface (EEMI) API guide: + https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf -- cgit v1.2.3 From 26372d0973febfc62f20a4afd38fc51623682459 Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Mon, 8 Oct 2018 11:21:45 -0700 Subject: dt-bindings: clock: Add bindings for ZynqMP clock driver Add documentation to describe Xilinx ZynqMP clock driver bindings. Signed-off-by: Rajan Vaja Signed-off-by: Jolly Shah Reviewed-by: Rob Herring Reviewed-by: Stephen Boyd Signed-off-by: Michal Simek --- .../firmware/xilinx/xlnx,zynqmp-firmware.txt | 53 ++++++++++ include/dt-bindings/clock/xlnx,zynqmp-clk.h | 116 +++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 include/dt-bindings/clock/xlnx,zynqmp-clk.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt index 1b431d9bbe44..614bac55df86 100644 --- a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt +++ b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt @@ -17,6 +17,53 @@ Required properties: - "smc" : SMC #0, following the SMCCC - "hvc" : HVC #0, following the SMCCC +-------------------------------------------------------------------------- +Device Tree Clock bindings for the Zynq Ultrascale+ MPSoC controlled using +Zynq MPSoC firmware interface +-------------------------------------------------------------------------- +The clock controller is a h/w block of Zynq Ultrascale+ MPSoC clock +tree. It reads required input clock frequencies from the devicetree and acts +as clock provider for all clock consumers of PS clocks. + +See clock_bindings.txt for more information on the generic clock bindings. + +Required properties: + - #clock-cells: Must be 1 + - compatible: Must contain: "xlnx,zynqmp-clk" + - clocks: List of clock specifiers which are external input + clocks to the given clock controller. Please refer + the next section to find the input clocks for a + given controller. + - clock-names: List of clock names which are exteral input clocks + to the given clock controller. Please refer to the + clock bindings for more details. + +Input clocks for zynqmp Ultrascale+ clock controller: + +The Zynq UltraScale+ MPSoC has one primary and four alternative reference clock +inputs. These required clock inputs are: + - pss_ref_clk (PS reference clock) + - video_clk (reference clock for video system ) + - pss_alt_ref_clk (alternative PS reference clock) + - aux_ref_clk + - gt_crx_ref_clk (transceiver reference clock) + +The following strings are optional parameters to the 'clock-names' property in +order to provide an optional (E)MIO clock source: + - swdt0_ext_clk + - swdt1_ext_clk + - gem0_emio_clk + - gem1_emio_clk + - gem2_emio_clk + - gem3_emio_clk + - mio_clk_XX # with XX = 00..77 + - mio_clk_50_or_51 #for the mux clock to gem tsu from 50 or 51 + + +Output clocks are registered based on clock information received +from firmware. Output clocks indexes are mentioned in +include/dt-bindings/clock/xlnx,zynqmp-clk.h. + ------- Example ------- @@ -25,5 +72,11 @@ firmware { zynqmp_firmware: zynqmp-firmware { compatible = "xlnx,zynqmp-firmware"; method = "smc"; + zynqmp_clk: clock-controller { + #clock-cells = <1>; + compatible = "xlnx,zynqmp-clk"; + clocks = <&pss_ref_clk>, <&video_clk>, <&pss_alt_ref_clk>, <&aux_ref_clk>, <>_crx_ref_clk>; + clock-names = "pss_ref_clk", "video_clk", "pss_alt_ref_clk","aux_ref_clk", "gt_crx_ref_clk"; + }; }; }; diff --git a/include/dt-bindings/clock/xlnx,zynqmp-clk.h b/include/dt-bindings/clock/xlnx,zynqmp-clk.h new file mode 100644 index 000000000000..4aebe6e2049e --- /dev/null +++ b/include/dt-bindings/clock/xlnx,zynqmp-clk.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx Zynq MPSoC Firmware layer + * + * Copyright (C) 2014-2018 Xilinx, Inc. + * + */ + +#ifndef _DT_BINDINGS_CLK_ZYNQMP_H +#define _DT_BINDINGS_CLK_ZYNQMP_H + +#define IOPLL 0 +#define RPLL 1 +#define APLL 2 +#define DPLL 3 +#define VPLL 4 +#define IOPLL_TO_FPD 5 +#define RPLL_TO_FPD 6 +#define APLL_TO_LPD 7 +#define DPLL_TO_LPD 8 +#define VPLL_TO_LPD 9 +#define ACPU 10 +#define ACPU_HALF 11 +#define DBF_FPD 12 +#define DBF_LPD 13 +#define DBG_TRACE 14 +#define DBG_TSTMP 15 +#define DP_VIDEO_REF 16 +#define DP_AUDIO_REF 17 +#define DP_STC_REF 18 +#define GDMA_REF 19 +#define DPDMA_REF 20 +#define DDR_REF 21 +#define SATA_REF 22 +#define PCIE_REF 23 +#define GPU_REF 24 +#define GPU_PP0_REF 25 +#define GPU_PP1_REF 26 +#define TOPSW_MAIN 27 +#define TOPSW_LSBUS 28 +#define GTGREF0_REF 29 +#define LPD_SWITCH 30 +#define LPD_LSBUS 31 +#define USB0_BUS_REF 32 +#define USB1_BUS_REF 33 +#define USB3_DUAL_REF 34 +#define USB0 35 +#define USB1 36 +#define CPU_R5 37 +#define CPU_R5_CORE 38 +#define CSU_SPB 39 +#define CSU_PLL 40 +#define PCAP 41 +#define IOU_SWITCH 42 +#define GEM_TSU_REF 43 +#define GEM_TSU 44 +#define GEM0_REF 45 +#define GEM1_REF 46 +#define GEM2_REF 47 +#define GEM3_REF 48 +#define GEM0_TX 49 +#define GEM1_TX 50 +#define GEM2_TX 51 +#define GEM3_TX 52 +#define QSPI_REF 53 +#define SDIO0_REF 54 +#define SDIO1_REF 55 +#define UART0_REF 56 +#define UART1_REF 57 +#define SPI0_REF 58 +#define SPI1_REF 59 +#define NAND_REF 60 +#define I2C0_REF 61 +#define I2C1_REF 62 +#define CAN0_REF 63 +#define CAN1_REF 64 +#define CAN0 65 +#define CAN1 66 +#define DLL_REF 67 +#define ADMA_REF 68 +#define TIMESTAMP_REF 69 +#define AMS_REF 70 +#define PL0_REF 71 +#define PL1_REF 72 +#define PL2_REF 73 +#define PL3_REF 74 +#define WDT 75 +#define IOPLL_INT 76 +#define IOPLL_PRE_SRC 77 +#define IOPLL_HALF 78 +#define IOPLL_INT_MUX 79 +#define IOPLL_POST_SRC 80 +#define RPLL_INT 81 +#define RPLL_PRE_SRC 82 +#define RPLL_HALF 83 +#define RPLL_INT_MUX 84 +#define RPLL_POST_SRC 85 +#define APLL_INT 86 +#define APLL_PRE_SRC 87 +#define APLL_HALF 88 +#define APLL_INT_MUX 89 +#define APLL_POST_SRC 90 +#define DPLL_INT 91 +#define DPLL_PRE_SRC 92 +#define DPLL_HALF 93 +#define DPLL_INT_MUX 94 +#define DPLL_POST_SRC 95 +#define VPLL_INT 96 +#define VPLL_PRE_SRC 97 +#define VPLL_HALF 98 +#define VPLL_INT_MUX 99 +#define VPLL_POST_SRC 100 +#define CAN0_MIO 101 +#define CAN1_MIO 102 + +#endif -- cgit v1.2.3 From d07d9195c950d1cd16ec32a0819b2b98084c0753 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 4 Oct 2018 11:58:11 -0400 Subject: media: dt-bindings: media: rcar_vin: add device tree support for r8a7744 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add compatible strings for r8a7744. No driver change is needed as "renesas,rcar-gen2-vin" will activate the right code.However, it is good practice to document compatible strings for the specific SoC as this allows SoC specific changes to the driver if needed, in addition to document SoC support and therefore allow checkpatch.pl to validate compatible string values. Signed-off-by: Biju Das Reviewed-by: Chris Paterson Acked-by: Niklas Söderlund Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/rcar_vin.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 2f420050d57f..d329a4e8ac58 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -11,6 +11,7 @@ on Gen3 platforms to a CSI-2 receiver. - compatible: Must be one or more of the following - "renesas,vin-r8a7743" for the R8A7743 device + - "renesas,vin-r8a7744" for the R8A7744 device - "renesas,vin-r8a7745" for the R8A7745 device - "renesas,vin-r8a7778" for the R8A7778 device - "renesas,vin-r8a7779" for the R8A7779 device -- cgit v1.2.3 From 60c2e0cebfd01bd1bc5e8843f063264148d6b2bb Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 25 Apr 2018 21:20:28 +0900 Subject: tracing: probeevent: Add symbol type Add "symbol" type to probeevent, which is an alias of u32 or u64 (depends on BITS_PER_LONG). This shows the result value in symbol+offset style. This type is only available with kprobe events. Link: http://lkml.kernel.org/r/152465882860.26224.14779072294412467338.stgit@devbox Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- Documentation/trace/kprobetrace.rst | 2 ++ kernel/trace/trace.c | 2 +- kernel/trace/trace_probe.c | 8 ++++++++ kernel/trace/trace_probe.h | 12 +++++++++--- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst index 8bfc75c90806..6224ddf34508 100644 --- a/Documentation/trace/kprobetrace.rst +++ b/Documentation/trace/kprobetrace.rst @@ -72,6 +72,8 @@ offset, and container-size (usually 32). The syntax is:: b@/ +Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG) +which shows given pointer in "symbol+offset" style. For $comm, the default type is "string"; any other type is invalid. diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 147be8523560..1e3f28b1fa07 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4626,7 +4626,7 @@ static const char readme_msg[] = "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @
, @[+|-],\n" "\t $stack, $stack, $retval, $comm\n" - "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string,\n" + "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t b@/\n" #endif " events/\t\t- Directory containing all trace event subsystems:\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d119bf8c3b4f..1e7e0618577d 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -46,6 +46,13 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x") DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x") DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx") +int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent) +{ + trace_seq_printf(s, "%pS", (void *)*(unsigned long *)data); + return !trace_seq_has_overflowed(s); +} +const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS"; + /* Print type function for string type */ int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent) { @@ -79,6 +86,7 @@ static const struct fetch_type probe_fetch_types[] = { ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0), ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0), ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0), + ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0), ASSIGN_FETCH_TYPE_END }; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index c4e9d3d3216d..469110e0790b 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -145,6 +145,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(x32); DECLARE_BASIC_PRINT_TYPE_FUNC(x64); DECLARE_BASIC_PRINT_TYPE_FUNC(string); +DECLARE_BASIC_PRINT_TYPE_FUNC(symbol); /* Default (unsigned long) fetch type */ #define __DEFAULT_FETCH_TYPE(t) x##t @@ -152,6 +153,10 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(string); #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG) #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE) +#define __ADDR_FETCH_TYPE(t) u##t +#define _ADDR_FETCH_TYPE(t) __ADDR_FETCH_TYPE(t) +#define ADDR_FETCH_TYPE _ADDR_FETCH_TYPE(BITS_PER_LONG) + #define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ {.name = _name, \ .size = _size, \ @@ -160,13 +165,14 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(string); .fmt = PRINT_TYPE_FMT_NAME(ptype), \ .fmttype = _fmttype, \ } - +#define _ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ + __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, #_fmttype) #define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \ - __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype) + _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, ptype) /* If ptype is an alias of atype, use this macro (show atype in format) */ #define ASSIGN_FETCH_TYPE_ALIAS(ptype, atype, ftype, sign) \ - __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #atype) + _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, atype) #define ASSIGN_FETCH_TYPE_END {} -- cgit v1.2.3 From 40b53b771806b1770837169cd32d1bf167fbccaf Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 25 Apr 2018 21:21:55 +0900 Subject: tracing: probeevent: Add array type support Add array type support for probe events. This allows user to get arraied types from memory address. The array type syntax is TYPE[N] Where TYPE is one of types (u8/16/32/64,s8/16/32/64, x8/16/32/64, symbol, string) and N is a fixed value less than 64. The string array type is a bit different from other types. For other base types, [1] is equal to (e.g. +0(%di):x32[1] is same as +0(%di):x32.) But string[1] is not equal to string. The string type itself represents "char array", but string array type represents "char * array". So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string. Link: http://lkml.kernel.org/r/152465891533.26224.6150658225601339931.stgit@devbox Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- Documentation/trace/kprobetrace.rst | 11 +++ kernel/trace/trace.c | 3 +- kernel/trace/trace_probe.c | 130 +++++++++++++++++++++++++++--------- kernel/trace/trace_probe.h | 14 ++++ kernel/trace/trace_probe_tmpl.h | 63 ++++++++++++++--- 5 files changed, 181 insertions(+), 40 deletions(-) (limited to 'Documentation') diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst index 6224ddf34508..2dfed7a1ea6f 100644 --- a/Documentation/trace/kprobetrace.rst +++ b/Documentation/trace/kprobetrace.rst @@ -64,9 +64,20 @@ respectively. 'x' prefix implies it is unsigned. Traced arguments are shown in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32' or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and x86-64 uses x64). +These value types can be an array. To record array data, you can add '[N]' +(where N is a fixed number, less than 64) to the base type. +E.g. 'x16[4]' means an array of x16 (2bytes hex) with 4 elements. +Note that the array can be applied to memory type fetchargs, you can not +apply it to registers/stack-entries etc. (for example, '$stack1:x8[8]' is +wrong, but '+8($stack):x8[8]' is OK.) String type is a special type, which fetches a "null-terminated" string from kernel space. This means it will fail and store NULL if the string container has been paged out. +The string array type is a bit different from other types. For other base +types, [1] is equal to (e.g. +0(%di):x32[1] is same +as +0(%di):x32.) But string[1] is not equal to string. The string type itself +represents "char array", but string array type represents "char * array". +So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string. Bitfield is another special type, which takes 3 parameters, bit-width, bit- offset, and container-size (usually 32). The syntax is:: diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1e3f28b1fa07..e7f99f513959 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4627,7 +4627,8 @@ static const char readme_msg[] = "\t fetcharg: %, @
, @[+|-],\n" "\t $stack, $stack, $retval, $comm\n" "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" - "\t b@/\n" + "\t b@/,\n" + "\t \\[\\]\n" #endif " events/\t\t- Directory containing all trace event subsystems:\n" " enable\t\t- Write 0/1 to enable/disable tracing of all events\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 1e7e0618577d..dfd096031305 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -341,9 +341,9 @@ static int __parse_bitfield_probe_arg(const char *bf, int traceprobe_parse_probe_arg(char *arg, ssize_t *size, struct probe_arg *parg, bool is_return, bool is_kprobe) { - struct fetch_insn *code, *tmp = NULL; - const char *t; - int ret; + struct fetch_insn *code, *scode, *tmp = NULL; + char *t, *t2; + int ret, len; if (strlen(arg) > MAX_ARGSTR_LEN) { pr_info("Argument is too long.: %s\n", arg); @@ -354,24 +354,42 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, pr_info("Failed to allocate memory for command '%s'.\n", arg); return -ENOMEM; } - t = strchr(parg->comm, ':'); + t = strchr(arg, ':'); if (t) { - arg[t - parg->comm] = '\0'; - t++; + *t = '\0'; + t2 = strchr(++t, '['); + if (t2) { + *t2 = '\0'; + parg->count = simple_strtoul(t2 + 1, &t2, 0); + if (strcmp(t2, "]") || parg->count == 0) + return -EINVAL; + if (parg->count > MAX_ARRAY_LEN) + return -E2BIG; + } } /* * The default type of $comm should be "string", and it can't be * dereferenced. */ if (!t && strcmp(arg, "$comm") == 0) - t = "string"; - parg->type = find_fetch_type(t); + parg->type = find_fetch_type("string"); + else + parg->type = find_fetch_type(t); if (!parg->type) { pr_info("Unsupported type: %s\n", t); return -EINVAL; } parg->offset = *size; - *size += parg->type->size; + *size += parg->type->size * (parg->count ?: 1); + + if (parg->count) { + len = strlen(parg->type->fmttype) + 6; + parg->fmt = kmalloc(len, GFP_KERNEL); + if (!parg->fmt) + return -ENOMEM; + snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype, + parg->count); + } code = tmp = kzalloc(sizeof(*code) * FETCH_INSN_MAX, GFP_KERNEL); if (!code) @@ -391,10 +409,20 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, ret = -EINVAL; goto fail; } - /* Since IMM or COMM must be the 1st insn, this is safe */ - if (code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM) + if (code->op != FETCH_OP_DEREF || parg->count) { + /* + * IMM and COMM is pointing actual address, those must + * be kept, and if parg->count != 0, this is an array + * of string pointers instead of string address itself. + */ code++; + if (code->op != FETCH_OP_NOP) { + ret = -E2BIG; + goto fail; + } + } code->op = FETCH_OP_ST_STRING; /* In DEREF case, replace it */ + code->size = parg->type->size; parg->dynamic = true; } else if (code->op == FETCH_OP_DEREF) { code->op = FETCH_OP_ST_MEM; @@ -408,12 +436,29 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, code->op = FETCH_OP_ST_RAW; code->size = parg->type->size; } + scode = code; /* Modify operation */ if (t != NULL) { ret = __parse_bitfield_probe_arg(t, parg->type, &code); if (ret) goto fail; } + /* Loop(Array) operation */ + if (parg->count) { + if (scode->op != FETCH_OP_ST_MEM && + scode->op != FETCH_OP_ST_STRING) { + pr_info("array only accepts memory or address\n"); + ret = -EINVAL; + goto fail; + } + code++; + if (code->op != FETCH_OP_NOP) { + ret = -E2BIG; + goto fail; + } + code->op = FETCH_OP_LP_ARRAY; + code->param = parg->count; + } code++; code->op = FETCH_OP_END; @@ -452,14 +497,17 @@ void traceprobe_free_probe_arg(struct probe_arg *arg) kfree(arg->code); kfree(arg->name); kfree(arg->comm); + kfree(arg->fmt); } +/* When len=0, we just calculate the needed length */ +#define LEN_OR_ZERO (len ? len - pos : 0) static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, bool is_return) { - int i; + struct probe_arg *parg; + int i, j; int pos = 0; - const char *fmt, *arg; if (!is_return) { @@ -470,33 +518,49 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP; } - /* When len=0, we just calculate the needed length */ -#define LEN_OR_ZERO (len ? len - pos : 0) - pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt); for (i = 0; i < tp->nr_args; i++) { - pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s", - tp->args[i].name, tp->args[i].type->fmt); + parg = tp->args + i; + pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=", parg->name); + if (parg->count) { + pos += snprintf(buf + pos, LEN_OR_ZERO, "{%s", + parg->type->fmt); + for (j = 1; j < parg->count; j++) + pos += snprintf(buf + pos, LEN_OR_ZERO, ",%s", + parg->type->fmt); + pos += snprintf(buf + pos, LEN_OR_ZERO, "}"); + } else + pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", + parg->type->fmt); } pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); for (i = 0; i < tp->nr_args; i++) { - if (strcmp(tp->args[i].type->name, "string") == 0) + parg = tp->args + i; + if (parg->count) { + if (strcmp(parg->type->name, "string") == 0) + fmt = ", __get_str(%s[%d])"; + else + fmt = ", REC->%s[%d]"; + for (j = 0; j < parg->count; j++) + pos += snprintf(buf + pos, LEN_OR_ZERO, + fmt, parg->name, j); + } else { + if (strcmp(parg->type->name, "string") == 0) + fmt = ", __get_str(%s)"; + else + fmt = ", REC->%s"; pos += snprintf(buf + pos, LEN_OR_ZERO, - ", __get_str(%s)", - tp->args[i].name); - else - pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", - tp->args[i].name); + fmt, parg->name); + } } -#undef LEN_OR_ZERO - /* return the length of print_fmt */ return pos; } +#undef LEN_OR_ZERO int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return) { @@ -524,11 +588,15 @@ int traceprobe_define_arg_fields(struct trace_event_call *event_call, /* Set argument names as fields */ for (i = 0; i < tp->nr_args; i++) { struct probe_arg *parg = &tp->args[i]; - - ret = trace_define_field(event_call, parg->type->fmttype, - parg->name, - offset + parg->offset, - parg->type->size, + const char *fmt = parg->type->fmttype; + int size = parg->type->size; + + if (parg->fmt) + fmt = parg->fmt; + if (parg->count) + size *= parg->count; + ret = trace_define_field(event_call, fmt, parg->name, + offset + parg->offset, size, parg->type->is_signed, FILTER_OTHER); if (ret) diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 469110e0790b..1f456fd82483 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -30,6 +30,7 @@ #define MAX_TRACE_ARGS 128 #define MAX_ARGSTR_LEN 63 +#define MAX_ARRAY_LEN 64 #define MAX_STRING_SIZE PATH_MAX /* Reserved field names */ @@ -65,6 +66,14 @@ static nokprobe_inline void *get_loc_data(u32 *dl, void *ent) return (u8 *)ent + get_loc_offs(*dl); } +static nokprobe_inline u32 update_data_loc(u32 loc, int consumed) +{ + u32 maxlen = get_loc_len(loc); + u32 offset = get_loc_offs(loc); + + return make_data_loc(maxlen - consumed, offset + consumed); +} + /* Printing function type */ typedef int (*print_type_func_t)(struct trace_seq *, void *, void *); @@ -86,6 +95,8 @@ enum fetch_op { FETCH_OP_ST_STRING, /* String: .offset, .size */ // Stage 4 (modify) op FETCH_OP_MOD_BF, /* Bitfield: .basesize, .lshift, .rshift */ + // Stage 5 (loop) op + FETCH_OP_LP_ARRAY, /* Array: .param = loop count */ FETCH_OP_END, }; @@ -175,6 +186,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(symbol); _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, atype) #define ASSIGN_FETCH_TYPE_END {} +#define MAX_ARRAY_LEN 64 #ifdef CONFIG_KPROBE_EVENTS bool trace_kprobe_on_func_entry(struct trace_event_call *call); @@ -195,8 +207,10 @@ struct probe_arg { struct fetch_insn *code; bool dynamic;/* Dynamic array (string) is used */ unsigned int offset; /* Offset from argument entry */ + unsigned int count; /* Array count */ const char *name; /* Name of this argument */ const char *comm; /* Command of this argument */ + char *fmt; /* Format string if needed */ const struct fetch_type *type; /* Type of this argument */ }; diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h index b4075f3e3a29..5c56afc17cf8 100644 --- a/kernel/trace/trace_probe_tmpl.h +++ b/kernel/trace/trace_probe_tmpl.h @@ -67,10 +67,15 @@ static nokprobe_inline int process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, void *dest, void *base) { - int ret = 0; + struct fetch_insn *s3 = NULL; + int total = 0, ret = 0, i = 0; + u32 loc = 0; + unsigned long lval = val; +stage2: /* 2nd stage: dereference memory if needed */ while (code->op == FETCH_OP_DEREF) { + lval = val; ret = probe_mem_read(&val, (void *)val + code->offset, sizeof(val)); if (ret) @@ -78,11 +83,15 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, code++; } + s3 = code; +stage3: /* 3rd stage: store value to buffer */ if (unlikely(!dest)) { - if (code->op == FETCH_OP_ST_STRING) - return fetch_store_strlen(val + code->offset); - else + if (code->op == FETCH_OP_ST_STRING) { + ret += fetch_store_strlen(val + code->offset); + code++; + goto array; + } else return -EILSEQ; } @@ -94,6 +103,7 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, probe_mem_read(dest, (void *)val + code->offset, code->size); break; case FETCH_OP_ST_STRING: + loc = *(u32 *)dest; ret = fetch_store_string(val + code->offset, dest, base); break; default: @@ -107,6 +117,29 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, code++; } +array: + /* the last stage: Loop on array */ + if (code->op == FETCH_OP_LP_ARRAY) { + total += ret; + if (++i < code->param) { + code = s3; + if (s3->op != FETCH_OP_ST_STRING) { + dest += s3->size; + val += s3->size; + goto stage3; + } + code--; + val = lval + sizeof(char *); + if (dest) { + dest += sizeof(u32); + *(u32 *)dest = update_data_loc(loc, ret); + } + goto stage2; + } + code++; + ret = total; + } + return code->op == FETCH_OP_END ? ret : -EILSEQ; } @@ -158,12 +191,26 @@ static inline int print_probe_args(struct trace_seq *s, struct probe_arg *args, int nr_args, u8 *data, void *field) { - int i; + void *p; + int i, j; for (i = 0; i < nr_args; i++) { - trace_seq_printf(s, " %s=", args[i].name); - if (!args[i].type->print(s, data + args[i].offset, field)) - return -ENOMEM; + struct probe_arg *a = args + i; + + trace_seq_printf(s, " %s=", a->name); + if (likely(!a->count)) { + if (!a->type->print(s, data + a->offset, field)) + return -ENOMEM; + continue; + } + trace_seq_putc(s, '{'); + p = data + a->offset; + for (j = 0; j < a->count; j++) { + if (!a->type->print(s, p, field)) + return -ENOMEM; + trace_seq_putc(s, j == a->count - 1 ? '}' : ','); + p += a->type->size; + } } return 0; } -- cgit v1.2.3 From a1303af5d79eb13a658633a9fb0ce3aed0f7decf Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 25 Apr 2018 21:21:26 +0900 Subject: tracing: probeevent: Add $argN for accessing function args Add $argN special fetch variable for accessing function arguments. This allows user to trace the Nth argument easily at the function entry. Note that this returns most probably assignment of registers and stacks. In some case, it may not work well. If you need to access correct registers or stacks you should use perf-probe. Link: http://lkml.kernel.org/r/152465888632.26224.3412465701570253696.stgit@devbox Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- Documentation/trace/kprobetrace.rst | 10 ++++++---- kernel/trace/trace.c | 4 ++++ kernel/trace/trace_kprobe.c | 18 +++++++++++++----- kernel/trace/trace_probe.c | 36 +++++++++++++++++++++++------------- kernel/trace/trace_probe.h | 9 ++++++++- kernel/trace/trace_uprobe.c | 2 +- 6 files changed, 55 insertions(+), 24 deletions(-) (limited to 'Documentation') diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst index 2dfed7a1ea6f..47e765c2f2c3 100644 --- a/Documentation/trace/kprobetrace.rst +++ b/Documentation/trace/kprobetrace.rst @@ -45,16 +45,18 @@ Synopsis of kprobe_events @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol) $stackN : Fetch Nth entry of stack (N >= 0) $stack : Fetch stack address. - $retval : Fetch return value.(*) + $argN : Fetch the Nth function argument. (N >= 1) (\*1) + $retval : Fetch return value.(\*2) $comm : Fetch current task comm. - +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) + +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(\*3) NAME=FETCHARG : Set NAME as the argument name of FETCHARG. FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (x8/x16/x32/x64), "string" and bitfield are supported. - (*) only for return probe. - (**) this is useful for fetching a field of data structures. + (\*1) only for the probe on function entry (offs == 0). + (\*2) only for return probe. + (\*3) this is useful for fetching a field of data structures. Types ----- diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e7f99f513959..ec5b21778806 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4625,7 +4625,11 @@ static const char readme_msg[] = #endif "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @
, @[+|-],\n" +#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API + "\t $stack, $stack, $retval, $comm, $arg\n" +#else "\t $stack, $stack, $retval, $comm\n" +#endif "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t b@/,\n" "\t \\[\\]\n" diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index fdd43f2f1fd1..3faaadbddf54 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -533,13 +533,15 @@ static int create_trace_kprobe(int argc, char **argv) long offset = 0; void *addr = NULL; char buf[MAX_EVENT_NAME_LEN]; + unsigned int flags = TPARG_FL_KERNEL; /* argc must be >= 1 */ if (argv[0][0] == 'p') is_return = false; - else if (argv[0][0] == 'r') + else if (argv[0][0] == 'r') { is_return = true; - else if (argv[0][0] == '-') + flags |= TPARG_FL_RETURN; + } else if (argv[0][0] == '-') is_delete = true; else { pr_info("Probe definition must be started with 'p', 'r' or" @@ -625,8 +627,9 @@ static int create_trace_kprobe(int argc, char **argv) pr_info("Failed to parse either an address or a symbol.\n"); return ret; } - if (offset && is_return && - !kprobe_on_func_entry(NULL, symbol, offset)) { + if (kprobe_on_func_entry(NULL, symbol, offset)) + flags |= TPARG_FL_FENTRY; + if (offset && is_return && !(flags & TPARG_FL_FENTRY)) { pr_info("Given offset is not valid for return probe.\n"); return -EINVAL; } @@ -696,7 +699,7 @@ static int create_trace_kprobe(int argc, char **argv) /* Parse fetch argument */ ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg, - is_return, true); + flags); if (ret) { pr_info("Parse error at argument[%d]. (%d)\n", i, ret); goto error; @@ -932,6 +935,11 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, case FETCH_OP_COMM: val = (unsigned long)current->comm; break; +#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API + case FETCH_OP_ARG: + val = regs_get_kernel_argument(regs, code->param); + break; +#endif default: return -EILSEQ; } diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index dfd096031305..333cda6d2633 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -157,14 +157,13 @@ int traceprobe_split_symbol_offset(char *symbol, long *offset) #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) static int parse_probe_vars(char *arg, const struct fetch_type *t, - struct fetch_insn *code, bool is_return, - bool is_kprobe) + struct fetch_insn *code, unsigned int flags) { int ret = 0; unsigned long param; if (strcmp(arg, "retval") == 0) { - if (is_return) + if (flags & TPARG_FL_RETURN) code->op = FETCH_OP_RETVAL; else ret = -EINVAL; @@ -173,7 +172,8 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, code->op = FETCH_OP_STACKP; } else if (isdigit(arg[5])) { ret = kstrtoul(arg + 5, 10, ¶m); - if (ret || (is_kprobe && param > PARAM_MAX_STACK)) + if (ret || ((flags & TPARG_FL_KERNEL) && + param > PARAM_MAX_STACK)) ret = -EINVAL; else { code->op = FETCH_OP_STACK; @@ -183,6 +183,18 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, ret = -EINVAL; } else if (strcmp(arg, "comm") == 0) { code->op = FETCH_OP_COMM; +#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API + } else if (((flags & TPARG_FL_MASK) == + (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) && + strncmp(arg, "arg", 3) == 0) { + if (!isdigit(arg[3])) + return -EINVAL; + ret = kstrtoul(arg + 3, 10, ¶m); + if (ret || !param || param > PARAM_MAX_STACK) + return -EINVAL; + code->op = FETCH_OP_ARG; + code->param = (unsigned int)param - 1; +#endif } else ret = -EINVAL; @@ -193,7 +205,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, static int parse_probe_arg(char *arg, const struct fetch_type *type, struct fetch_insn **pcode, struct fetch_insn *end, - bool is_return, bool is_kprobe) + unsigned int flags) { struct fetch_insn *code = *pcode; unsigned long param; @@ -203,8 +215,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, switch (arg[0]) { case '$': - ret = parse_probe_vars(arg + 1, type, code, - is_return, is_kprobe); + ret = parse_probe_vars(arg + 1, type, code, flags); break; case '%': /* named register */ @@ -226,7 +237,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, code->immediate = param; } else if (arg[1] == '+') { /* kprobes don't support file offsets */ - if (is_kprobe) + if (flags & TPARG_FL_KERNEL) return -EINVAL; ret = kstrtol(arg + 2, 0, &offset); @@ -237,7 +248,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, code->immediate = (unsigned long)offset; // imm64? } else { /* uprobes don't support symbols */ - if (!is_kprobe) + if (!(flags & TPARG_FL_KERNEL)) return -EINVAL; ret = traceprobe_split_symbol_offset(arg + 1, &offset); @@ -278,8 +289,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, const struct fetch_type *t2 = find_fetch_type(NULL); *tmp = '\0'; - ret = parse_probe_arg(arg, t2, &code, end, is_return, - is_kprobe); + ret = parse_probe_arg(arg, t2, &code, end, flags); if (ret) break; if (code->op == FETCH_OP_COMM) @@ -339,7 +349,7 @@ static int __parse_bitfield_probe_arg(const char *bf, /* String length checking wrapper */ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, - struct probe_arg *parg, bool is_return, bool is_kprobe) + struct probe_arg *parg, unsigned int flags) { struct fetch_insn *code, *scode, *tmp = NULL; char *t, *t2; @@ -397,7 +407,7 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, code[FETCH_INSN_MAX - 1].op = FETCH_OP_END; ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1], - is_return, is_kprobe); + flags); if (ret) goto fail; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 1f456fd82483..09f62171cc23 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "trace.h" @@ -86,6 +87,7 @@ enum fetch_op { FETCH_OP_RETVAL, /* Return value */ FETCH_OP_IMM, /* Immediate : .immediate */ FETCH_OP_COMM, /* Current comm */ + FETCH_OP_ARG, /* Function argument : .param */ FETCH_OP_FOFFS, /* File offset: .immediate */ // Stage 2 (dereference) op FETCH_OP_DEREF, /* Dereference: .offset */ @@ -263,8 +265,13 @@ find_event_file_link(struct trace_probe *tp, struct trace_event_file *file) return NULL; } +#define TPARG_FL_RETURN BIT(0) +#define TPARG_FL_KERNEL BIT(1) +#define TPARG_FL_FENTRY BIT(2) +#define TPARG_FL_MASK GENMASK(2, 0) + extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size, - struct probe_arg *parg, bool is_return, bool is_kprobe); + struct probe_arg *parg, unsigned int flags); extern int traceprobe_conflict_field_name(const char *name, struct probe_arg *args, int narg); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 7154473ffaa4..394b93572506 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -557,7 +557,7 @@ static int create_trace_uprobe(int argc, char **argv) /* Parse fetch argument */ ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg, - is_return, false); + is_return ? TPARG_FL_RETURN : 0); if (ret) { pr_info("Parse error at argument[%d]. (%d)\n", i, ret); goto error; -- cgit v1.2.3 From 05156e0a1261c056e58c8c6e53442f324af8293b Mon Sep 17 00:00:00 2001 From: Hiromitsu Yamasaki Date: Wed, 3 Oct 2018 13:12:19 +0200 Subject: serial: sh-sci: Add r8a77990 support This patch adds the R-Car E3 serial documentation. Signed-off-by: Hiromitsu Yamasaki Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 723abe02fac3..e52e16c6bc57 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -54,6 +54,8 @@ Required properties: - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. - "renesas,scif-r8a77980" for R8A77980 (R-Car V3H) SCIF compatible UART. - "renesas,hscif-r8a77980" for R8A77980 (R-Car V3H) HSCIF compatible UART. + - "renesas,scif-r8a77990" for R8A77990 (R-Car E3) SCIF compatible UART. + - "renesas,hscif-r8a77990" for R8A77990 (R-Car E3) HSCIF compatible UART. - "renesas,scif-r8a77995" for R8A77995 (R-Car D3) SCIF compatible UART. - "renesas,hscif-r8a77995" for R8A77995 (R-Car D3) HSCIF compatible UART. - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. -- cgit v1.2.3 From d9265e8a878aa19898667ab32f6b8936170cf1f9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 11 Oct 2018 17:04:13 -0700 Subject: Input: of_touchscreen - add support for touchscreen-min-x|y Some touchscreens, depending on the firmware and/or the digitizer, report coordinates which never reach 0 along one or both of their axis. This has been seen for example on the Silead touchscreens on a Onda V891w and a Point of View mobii TAB-P800w(v2.0). This commit adds support for touchscreen-min-x and touchscreen-min-y device-properties which can be set to communicate the actual start coordinates (rather then 0,0) to userspace. This commit also drop the "(in pixels)" comment from the documentation of the touchscreen-size-x and touchscreen-size-y properties. The comment suggested that there is a relation between the range of reported coordinates and the display resolution, which is only true for some devices. The "(in pixels)" comment is replaced with "(maximum x coordinate reported + 1)" to mirror the language describing the new touchscreen-min-x and -min-y properties. When set this fixes e.g. not being able to click things in the GNOME3 top-bar on the 2 example tablets. Signed-off-by: Hans de Goede Reviewed-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/touchscreen.txt | 6 ++-- drivers/input/touchscreen/of_touchscreen.c | 36 +++++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt index 537643e86f61..8aff9551259f 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt @@ -1,10 +1,12 @@ General Touchscreen Properties: Optional properties for Touchscreens: + - touchscreen-min-x : minimum x coordinate reported (0 if not set) + - touchscreen-min-y : minimum y coordinate reported (0 if not set) - touchscreen-size-x : horizontal resolution of touchscreen - (in pixels) + (maximum x coordinate reported + 1) - touchscreen-size-y : vertical resolution of touchscreen - (in pixels) + (maximum y coordinate reported + 1) - touchscreen-max-pressure : maximum reported pressure (arbitrary range dependent on the controller) - touchscreen-fuzz-x : horizontal noise value of the absolute input diff --git a/drivers/input/touchscreen/of_touchscreen.c b/drivers/input/touchscreen/of_touchscreen.c index 9642f103b726..6d241d45e312 100644 --- a/drivers/input/touchscreen/of_touchscreen.c +++ b/drivers/input/touchscreen/of_touchscreen.c @@ -35,7 +35,7 @@ static bool touchscreen_get_prop_u32(struct device *dev, static void touchscreen_set_params(struct input_dev *dev, unsigned long axis, - int max, int fuzz) + int min, int max, int fuzz) { struct input_absinfo *absinfo; @@ -47,6 +47,7 @@ static void touchscreen_set_params(struct input_dev *dev, } absinfo = &dev->absinfo[axis]; + absinfo->minimum = min; absinfo->maximum = max; absinfo->fuzz = fuzz; } @@ -68,8 +69,9 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, struct touchscreen_properties *prop) { struct device *dev = input->dev.parent; + struct input_absinfo *absinfo; unsigned int axis; - unsigned int maximum, fuzz; + unsigned int minimum, maximum, fuzz; bool data_present; input_alloc_absinfo(input); @@ -77,7 +79,10 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, return; axis = multitouch ? ABS_MT_POSITION_X : ABS_X; - data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-x", + data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x", + input_abs_get_min(input, axis), + &minimum) | + touchscreen_get_prop_u32(dev, "touchscreen-size-x", input_abs_get_max(input, axis) + 1, &maximum) | @@ -85,10 +90,13 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, input_abs_get_fuzz(input, axis), &fuzz); if (data_present) - touchscreen_set_params(input, axis, maximum - 1, fuzz); + touchscreen_set_params(input, axis, minimum, maximum - 1, fuzz); axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y; - data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-y", + data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y", + input_abs_get_min(input, axis), + &minimum) | + touchscreen_get_prop_u32(dev, "touchscreen-size-y", input_abs_get_max(input, axis) + 1, &maximum) | @@ -96,7 +104,7 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, input_abs_get_fuzz(input, axis), &fuzz); if (data_present) - touchscreen_set_params(input, axis, maximum - 1, fuzz); + touchscreen_set_params(input, axis, minimum, maximum - 1, fuzz); axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE; data_present = touchscreen_get_prop_u32(dev, @@ -108,7 +116,7 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, input_abs_get_fuzz(input, axis), &fuzz); if (data_present) - touchscreen_set_params(input, axis, maximum, fuzz); + touchscreen_set_params(input, axis, 0, maximum, fuzz); if (!prop) return; @@ -117,13 +125,25 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, prop->max_x = input_abs_get_max(input, axis); prop->max_y = input_abs_get_max(input, axis + 1); + prop->invert_x = device_property_read_bool(dev, "touchscreen-inverted-x"); + if (prop->invert_x) { + absinfo = &input->absinfo[axis]; + absinfo->maximum -= absinfo->minimum; + absinfo->minimum = 0; + } + prop->invert_y = device_property_read_bool(dev, "touchscreen-inverted-y"); + if (prop->invert_y) { + absinfo = &input->absinfo[axis + 1]; + absinfo->maximum -= absinfo->minimum; + absinfo->minimum = 0; + } + prop->swap_x_y = device_property_read_bool(dev, "touchscreen-swapped-x-y"); - if (prop->swap_x_y) swap(input->absinfo[axis], input->absinfo[axis + 1]); } -- cgit v1.2.3 From 270c4265f259e4f9695b86b1ded00f7f202ecba4 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 17 Sep 2018 06:22:53 +0000 Subject: dt-bindings: watchdog: add mpc8xxx-wdt support Add description of DT bindings for mpc8xxx-wdt driver which handles the CPU watchdog timer on the mpc83xx, mpc86xx and mpc8xx. Signed-off-by: Christophe Leroy Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/mpc8xxx-wdt.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt new file mode 100644 index 000000000000..a384ff5b3ce8 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt @@ -0,0 +1,25 @@ +* Freescale mpc8xxx watchdog driver (For 83xx, 86xx and 8xx) + +Required properties: +- compatible: Shall contain one of the following: + "mpc83xx_wdt" for an mpc83xx + "fsl,mpc8610-wdt" for an mpc86xx + "fsl,mpc823-wdt" for an mpc8xx +- reg: base physical address and length of the area hosting the + watchdog registers. + On the 83xx, "Watchdog Timer Registers" area: <0x200 0x100> + On the 86xx, "Watchdog Timer Registers" area: <0xe4000 0x100> + On the 8xx, "General System Interface Unit" area: <0x0 0x10> + +Optional properties: +- reg: additional physical address and length (4) of location of the + Reset Status Register (called RSTRSCR on the mpc86xx) + On the 83xx, it is located at offset 0x910 + On the 86xx, it is located at offset 0xe0094 + On the 8xx, it is located at offset 0x288 + +Example: + WDT: watchdog@0 { + compatible = "fsl,mpc823-wdt"; + reg = <0x0 0x10 0x288 0x4>; + }; -- cgit v1.2.3 From 8562205592a69dd8817f9ff361fc0ffc55f5e9fe Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Mon, 24 Sep 2018 13:06:52 +0200 Subject: dt-bindings: watchdog: Document armada-37xx-wdt binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds device tree binding documentation for the CPU watchdog found on Armada 37xx SOCs (EspressoBin, Turris Mox). Signed-off-by: Marek Behún Cc: Rob Herring Cc: devicetree@vger.kernel.org Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/armada-37xx-wdt.txt | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt b/Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt new file mode 100644 index 000000000000..a8d00c31a1d8 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt @@ -0,0 +1,23 @@ +* Armada 37xx CPU Watchdog Timer Controller + +Required properties: +- compatible : must be "marvell,armada-3700-wdt" +- reg : base physical address of the controller and length of memory mapped + region. +- clocks : the clock feeding the watchdog timer. See clock-bindings.txt +- marvell,system-controller : reference to syscon node for the CPU Miscellaneous + Registers + +Example: + + cpu_misc: system-controller@d000 { + compatible = "marvell,armada-3700-cpu-misc", "syscon"; + reg = <0xd000 0x1000>; + }; + + wdt: watchdog@8300 { + compatible = "marvell,armada-3700-wdt"; + reg = <0x8300 0x40>; + marvell,system-controller = <&cpu_misc>; + clocks = <&xtalclk>; + }; -- cgit v1.2.3 From cd69606ad05e1d6a930e2d29ac277c00108ef908 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Mon, 24 Sep 2018 13:06:53 +0200 Subject: documentation: watchdog: add documentation for armada-37xx-wdt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation for the kernel module parameters accepted by armada-37xx-wdt. Signed-off-by: Marek Behún Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/watchdog/watchdog-parameters.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index 6d6200ea27b8..0b88e333f9e1 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -40,6 +40,11 @@ margin: Watchdog margin in seconds (default=60) nowayout: Disable watchdog shutdown on close (default=kernel config parameter) ------------------------------------------------- +armada_37xx_wdt: +timeout: Watchdog timeout in seconds. (default=120) +nowayout: Disable watchdog shutdown on close + (default=kernel config parameter) +------------------------------------------------- at91rm9200_wdt: wdt_time: Watchdog time in seconds. (default=5) nowayout: Watchdog cannot be stopped once started -- cgit v1.2.3 From 46b5dfab75eea06b84480d0b6fcecbfc7120801f Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 10 Aug 2018 15:21:06 +0530 Subject: dt-bindings: clock: Add reset controller bindings for Actions Semi Owl SoCs Add Reset Controller bindings to clock bindings for Actions Semi Owl SoCs, S700 and S900. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/actions,owl-cmu.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt index d1e60d297387..2ef86ae96df8 100644 --- a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt +++ b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt @@ -13,6 +13,7 @@ Required Properties: region. - clocks: Reference to the parent clocks ("hosc", "losc") - #clock-cells: should be 1. +- #reset-cells: should be 1. Each clock is assigned an identifier, and client nodes can use this identifier to specify the clock which they consume. @@ -36,6 +37,7 @@ Example: Clock Management Unit node: reg = <0x0 0xe0160000 0x0 0x1000>; clocks = <&hosc>, <&losc>; #clock-cells = <1>; + #reset-cells = <1>; }; Example: UART controller node that consumes clock generated by the clock -- cgit v1.2.3 From 3b6b13ede0e3129e4449a83dced7d7fd1cd32e8a Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 20 Sep 2018 23:01:00 -0700 Subject: dt-bindings: clk: hisilicon: Add bindings for Hi3670 clk Add devicetree bindings for HiSilicon Hi3670 clock controller. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/hi3670-clock.txt | 43 +++ include/dt-bindings/clock/hi3670-clock.h | 348 +++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hi3670-clock.txt create mode 100644 include/dt-bindings/clock/hi3670-clock.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/hi3670-clock.txt b/Documentation/devicetree/bindings/clock/hi3670-clock.txt new file mode 100644 index 000000000000..66f3697eca78 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/hi3670-clock.txt @@ -0,0 +1,43 @@ +* Hisilicon Hi3670 Clock Controller + +The Hi3670 clock controller generates and supplies clock to various +controllers within the Hi3670 SoC. + +Required Properties: + +- compatible: the compatible should be one of the following strings to + indicate the clock controller functionality. + + - "hisilicon,hi3670-crgctrl" + - "hisilicon,hi3670-pctrl" + - "hisilicon,hi3670-pmuctrl" + - "hisilicon,hi3670-sctrl" + - "hisilicon,hi3670-iomcu" + - "hisilicon,hi3670-media1-crg" + - "hisilicon,hi3670-media2-crg" + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in . + +Examples: + crg_ctrl: clock-controller@fff35000 { + compatible = "hisilicon,hi3670-crgctrl", "syscon"; + reg = <0x0 0xfff35000 0x0 0x1000>; + #clock-cells = <1>; + }; + + uart0: serial@fdf02000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0xfdf02000 0x0 0x1000>; + interrupts = ; + clocks = <&crg_ctrl HI3670_CLK_GATE_UART0>, + <&crg_ctrl HI3670_PCLK>; + clock-names = "uartclk", "apb_pclk"; + }; diff --git a/include/dt-bindings/clock/hi3670-clock.h b/include/dt-bindings/clock/hi3670-clock.h new file mode 100644 index 000000000000..fa48583f87d6 --- /dev/null +++ b/include/dt-bindings/clock/hi3670-clock.h @@ -0,0 +1,348 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Device Tree binding constants for HiSilicon Hi3670 SoC + * + * Copyright (c) 2001-2021, Huawei Tech. Co., Ltd. + * Copyright (c) 2018 Linaro Ltd. + */ + +#ifndef __DT_BINDINGS_CLOCK_HI3670_H +#define __DT_BINDINGS_CLOCK_HI3670_H + +/* clk in stub clock */ +#define HI3670_CLK_STUB_CLUSTER0 0 +#define HI3670_CLK_STUB_CLUSTER1 1 +#define HI3670_CLK_STUB_GPU 2 +#define HI3670_CLK_STUB_DDR 3 +#define HI3670_CLK_STUB_DDR_VOTE 4 +#define HI3670_CLK_STUB_DDR_LIMIT 5 +#define HI3670_CLK_STUB_NUM 6 + +/* clk in crg clock */ +#define HI3670_CLKIN_SYS 0 +#define HI3670_CLKIN_REF 1 +#define HI3670_CLK_FLL_SRC 2 +#define HI3670_CLK_PPLL0 3 +#define HI3670_CLK_PPLL1 4 +#define HI3670_CLK_PPLL2 5 +#define HI3670_CLK_PPLL3 6 +#define HI3670_CLK_PPLL4 7 +#define HI3670_CLK_PPLL6 8 +#define HI3670_CLK_PPLL7 9 +#define HI3670_CLK_PPLL_PCIE 10 +#define HI3670_CLK_PCIEPLL_REV 11 +#define HI3670_CLK_SCPLL 12 +#define HI3670_PCLK 13 +#define HI3670_CLK_UART0_DBG 14 +#define HI3670_CLK_UART6 15 +#define HI3670_OSC32K 16 +#define HI3670_OSC19M 17 +#define HI3670_CLK_480M 18 +#define HI3670_CLK_INVALID 19 +#define HI3670_CLK_DIV_SYSBUS 20 +#define HI3670_CLK_FACTOR_MMC 21 +#define HI3670_CLK_SD_SYS 22 +#define HI3670_CLK_SDIO_SYS 23 +#define HI3670_CLK_DIV_A53HPM 24 +#define HI3670_CLK_DIV_320M 25 +#define HI3670_PCLK_GATE_UART0 26 +#define HI3670_CLK_FACTOR_UART0 27 +#define HI3670_CLK_FACTOR_USB3PHY_PLL 28 +#define HI3670_CLK_GATE_ABB_USB 29 +#define HI3670_CLK_GATE_UFSPHY_REF 30 +#define HI3670_ICS_VOLT_HIGH 31 +#define HI3670_ICS_VOLT_MIDDLE 32 +#define HI3670_VENC_VOLT_HOLD 33 +#define HI3670_VDEC_VOLT_HOLD 34 +#define HI3670_EDC_VOLT_HOLD 35 +#define HI3670_CLK_ISP_SNCLK_FAC 36 +#define HI3670_CLK_FACTOR_RXDPHY 37 +#define HI3670_AUTODIV_SYSBUS 38 +#define HI3670_AUTODIV_EMMC0BUS 39 +#define HI3670_PCLK_ANDGT_MMC1_PCIE 40 +#define HI3670_CLK_GATE_VCODECBUS_GT 41 +#define HI3670_CLK_ANDGT_SD 42 +#define HI3670_CLK_SD_SYS_GT 43 +#define HI3670_CLK_ANDGT_SDIO 44 +#define HI3670_CLK_SDIO_SYS_GT 45 +#define HI3670_CLK_A53HPM_ANDGT 46 +#define HI3670_CLK_320M_PLL_GT 47 +#define HI3670_CLK_ANDGT_UARTH 48 +#define HI3670_CLK_ANDGT_UARTL 49 +#define HI3670_CLK_ANDGT_UART0 50 +#define HI3670_CLK_ANDGT_SPI 51 +#define HI3670_CLK_ANDGT_PCIEAXI 52 +#define HI3670_CLK_DIV_AO_ASP_GT 53 +#define HI3670_CLK_GATE_CSI_TRANS 54 +#define HI3670_CLK_GATE_DSI_TRANS 55 +#define HI3670_CLK_ANDGT_PTP 56 +#define HI3670_CLK_ANDGT_OUT0 57 +#define HI3670_CLK_ANDGT_OUT1 58 +#define HI3670_CLKGT_DP_AUDIO_PLL_AO 59 +#define HI3670_CLK_ANDGT_VDEC 60 +#define HI3670_CLK_ANDGT_VENC 61 +#define HI3670_CLK_ISP_SNCLK_ANGT 62 +#define HI3670_CLK_ANDGT_RXDPHY 63 +#define HI3670_CLK_ANDGT_ICS 64 +#define HI3670_AUTODIV_DMABUS 65 +#define HI3670_CLK_MUX_SYSBUS 66 +#define HI3670_CLK_MUX_VCODECBUS 67 +#define HI3670_CLK_MUX_SD_SYS 68 +#define HI3670_CLK_MUX_SD_PLL 69 +#define HI3670_CLK_MUX_SDIO_SYS 70 +#define HI3670_CLK_MUX_SDIO_PLL 71 +#define HI3670_CLK_MUX_A53HPM 72 +#define HI3670_CLK_MUX_320M 73 +#define HI3670_CLK_MUX_UARTH 74 +#define HI3670_CLK_MUX_UARTL 75 +#define HI3670_CLK_MUX_UART0 76 +#define HI3670_CLK_MUX_I2C 77 +#define HI3670_CLK_MUX_SPI 78 +#define HI3670_CLK_MUX_PCIEAXI 79 +#define HI3670_CLK_MUX_AO_ASP 80 +#define HI3670_CLK_MUX_VDEC 81 +#define HI3670_CLK_MUX_VENC 82 +#define HI3670_CLK_ISP_SNCLK_MUX0 83 +#define HI3670_CLK_ISP_SNCLK_MUX1 84 +#define HI3670_CLK_ISP_SNCLK_MUX2 85 +#define HI3670_CLK_MUX_RXDPHY_CFG 86 +#define HI3670_CLK_MUX_ICS 87 +#define HI3670_CLK_DIV_CFGBUS 88 +#define HI3670_CLK_DIV_MMC0BUS 89 +#define HI3670_CLK_DIV_MMC1BUS 90 +#define HI3670_PCLK_DIV_MMC1_PCIE 91 +#define HI3670_CLK_DIV_VCODECBUS 92 +#define HI3670_CLK_DIV_SD 93 +#define HI3670_CLK_DIV_SDIO 94 +#define HI3670_CLK_DIV_UARTH 95 +#define HI3670_CLK_DIV_UARTL 96 +#define HI3670_CLK_DIV_UART0 97 +#define HI3670_CLK_DIV_I2C 98 +#define HI3670_CLK_DIV_SPI 99 +#define HI3670_CLK_DIV_PCIEAXI 100 +#define HI3670_CLK_DIV_AO_ASP 101 +#define HI3670_CLK_DIV_CSI_TRANS 102 +#define HI3670_CLK_DIV_DSI_TRANS 103 +#define HI3670_CLK_DIV_PTP 104 +#define HI3670_CLK_DIV_CLKOUT0_PLL 105 +#define HI3670_CLK_DIV_CLKOUT1_PLL 106 +#define HI3670_CLKDIV_DP_AUDIO_PLL_AO 107 +#define HI3670_CLK_DIV_VDEC 108 +#define HI3670_CLK_DIV_VENC 109 +#define HI3670_CLK_ISP_SNCLK_DIV0 110 +#define HI3670_CLK_ISP_SNCLK_DIV1 111 +#define HI3670_CLK_ISP_SNCLK_DIV2 112 +#define HI3670_CLK_DIV_ICS 113 +#define HI3670_PPLL1_EN_ACPU 114 +#define HI3670_PPLL2_EN_ACPU 115 +#define HI3670_PPLL3_EN_ACPU 116 +#define HI3670_PPLL1_GT_CPU 117 +#define HI3670_PPLL2_GT_CPU 118 +#define HI3670_PPLL3_GT_CPU 119 +#define HI3670_CLK_GATE_PPLL2_MEDIA 120 +#define HI3670_CLK_GATE_PPLL3_MEDIA 121 +#define HI3670_CLK_GATE_PPLL4_MEDIA 122 +#define HI3670_CLK_GATE_PPLL6_MEDIA 123 +#define HI3670_CLK_GATE_PPLL7_MEDIA 124 +#define HI3670_PCLK_GPIO0 125 +#define HI3670_PCLK_GPIO1 126 +#define HI3670_PCLK_GPIO2 127 +#define HI3670_PCLK_GPIO3 128 +#define HI3670_PCLK_GPIO4 129 +#define HI3670_PCLK_GPIO5 130 +#define HI3670_PCLK_GPIO6 131 +#define HI3670_PCLK_GPIO7 132 +#define HI3670_PCLK_GPIO8 133 +#define HI3670_PCLK_GPIO9 134 +#define HI3670_PCLK_GPIO10 135 +#define HI3670_PCLK_GPIO11 136 +#define HI3670_PCLK_GPIO12 137 +#define HI3670_PCLK_GPIO13 138 +#define HI3670_PCLK_GPIO14 139 +#define HI3670_PCLK_GPIO15 140 +#define HI3670_PCLK_GPIO16 141 +#define HI3670_PCLK_GPIO17 142 +#define HI3670_PCLK_GPIO20 143 +#define HI3670_PCLK_GPIO21 144 +#define HI3670_PCLK_GATE_DSI0 145 +#define HI3670_PCLK_GATE_DSI1 146 +#define HI3670_HCLK_GATE_USB3OTG 147 +#define HI3670_ACLK_GATE_USB3DVFS 148 +#define HI3670_HCLK_GATE_SDIO 149 +#define HI3670_PCLK_GATE_PCIE_SYS 150 +#define HI3670_PCLK_GATE_PCIE_PHY 151 +#define HI3670_PCLK_GATE_MMC1_PCIE 152 +#define HI3670_PCLK_GATE_MMC0_IOC 153 +#define HI3670_PCLK_GATE_MMC1_IOC 154 +#define HI3670_CLK_GATE_DMAC 155 +#define HI3670_CLK_GATE_VCODECBUS2DDR 156 +#define HI3670_CLK_CCI400_BYPASS 157 +#define HI3670_CLK_GATE_CCI400 158 +#define HI3670_CLK_GATE_SD 159 +#define HI3670_HCLK_GATE_SD 160 +#define HI3670_CLK_GATE_SDIO 161 +#define HI3670_CLK_GATE_A57HPM 162 +#define HI3670_CLK_GATE_A53HPM 163 +#define HI3670_CLK_GATE_PA_A53 164 +#define HI3670_CLK_GATE_PA_A57 165 +#define HI3670_CLK_GATE_PA_G3D 166 +#define HI3670_CLK_GATE_GPUHPM 167 +#define HI3670_CLK_GATE_PERIHPM 168 +#define HI3670_CLK_GATE_AOHPM 169 +#define HI3670_CLK_GATE_UART1 170 +#define HI3670_CLK_GATE_UART4 171 +#define HI3670_PCLK_GATE_UART1 172 +#define HI3670_PCLK_GATE_UART4 173 +#define HI3670_CLK_GATE_UART2 174 +#define HI3670_CLK_GATE_UART5 175 +#define HI3670_PCLK_GATE_UART2 176 +#define HI3670_PCLK_GATE_UART5 177 +#define HI3670_CLK_GATE_UART0 178 +#define HI3670_CLK_GATE_I2C3 179 +#define HI3670_CLK_GATE_I2C4 180 +#define HI3670_CLK_GATE_I2C7 181 +#define HI3670_PCLK_GATE_I2C3 182 +#define HI3670_PCLK_GATE_I2C4 183 +#define HI3670_PCLK_GATE_I2C7 184 +#define HI3670_CLK_GATE_SPI1 185 +#define HI3670_CLK_GATE_SPI4 186 +#define HI3670_PCLK_GATE_SPI1 187 +#define HI3670_PCLK_GATE_SPI4 188 +#define HI3670_CLK_GATE_USB3OTG_REF 189 +#define HI3670_CLK_GATE_USB2PHY_REF 190 +#define HI3670_CLK_GATE_PCIEAUX 191 +#define HI3670_ACLK_GATE_PCIE 192 +#define HI3670_CLK_GATE_MMC1_PCIEAXI 193 +#define HI3670_CLK_GATE_PCIEPHY_REF 194 +#define HI3670_CLK_GATE_PCIE_DEBOUNCE 195 +#define HI3670_CLK_GATE_PCIEIO 196 +#define HI3670_CLK_GATE_PCIE_HP 197 +#define HI3670_CLK_GATE_AO_ASP 198 +#define HI3670_PCLK_GATE_PCTRL 199 +#define HI3670_CLK_CSI_TRANS_GT 200 +#define HI3670_CLK_DSI_TRANS_GT 201 +#define HI3670_CLK_GATE_PWM 202 +#define HI3670_ABB_AUDIO_EN0 203 +#define HI3670_ABB_AUDIO_EN1 204 +#define HI3670_ABB_AUDIO_GT_EN0 205 +#define HI3670_ABB_AUDIO_GT_EN1 206 +#define HI3670_CLK_GATE_DP_AUDIO_PLL_AO 207 +#define HI3670_PERI_VOLT_HOLD 208 +#define HI3670_PERI_VOLT_MIDDLE 209 +#define HI3670_CLK_GATE_ISP_SNCLK0 210 +#define HI3670_CLK_GATE_ISP_SNCLK1 211 +#define HI3670_CLK_GATE_ISP_SNCLK2 212 +#define HI3670_CLK_GATE_RXDPHY0_CFG 213 +#define HI3670_CLK_GATE_RXDPHY1_CFG 214 +#define HI3670_CLK_GATE_RXDPHY2_CFG 215 +#define HI3670_CLK_GATE_TXDPHY0_CFG 216 +#define HI3670_CLK_GATE_TXDPHY0_REF 217 +#define HI3670_CLK_GATE_TXDPHY1_CFG 218 +#define HI3670_CLK_GATE_TXDPHY1_REF 219 +#define HI3670_CLK_GATE_MEDIA_TCXO 220 + +/* clk in sctrl */ +#define HI3670_CLK_ANDGT_IOPERI 0 +#define HI3670_CLKANDGT_ASP_SUBSYS_PERI 1 +#define HI3670_CLK_ANGT_ASP_SUBSYS 2 +#define HI3670_CLK_MUX_UFS_SUBSYS 3 +#define HI3670_CLK_MUX_CLKOUT0 4 +#define HI3670_CLK_MUX_CLKOUT1 5 +#define HI3670_CLK_MUX_ASP_SUBSYS_PERI 6 +#define HI3670_CLK_MUX_ASP_PLL 7 +#define HI3670_CLK_DIV_AOBUS 8 +#define HI3670_CLK_DIV_UFS_SUBSYS 9 +#define HI3670_CLK_DIV_IOPERI 10 +#define HI3670_CLK_DIV_CLKOUT0_TCXO 11 +#define HI3670_CLK_DIV_CLKOUT1_TCXO 12 +#define HI3670_CLK_ASP_SUBSYS_PERI_DIV 13 +#define HI3670_CLK_DIV_ASP_SUBSYS 14 +#define HI3670_PPLL0_EN_ACPU 15 +#define HI3670_PPLL0_GT_CPU 16 +#define HI3670_CLK_GATE_PPLL0_MEDIA 17 +#define HI3670_PCLK_GPIO18 18 +#define HI3670_PCLK_GPIO19 19 +#define HI3670_CLK_GATE_SPI 20 +#define HI3670_PCLK_GATE_SPI 21 +#define HI3670_CLK_GATE_UFS_SUBSYS 22 +#define HI3670_CLK_GATE_UFSIO_REF 23 +#define HI3670_PCLK_AO_GPIO0 24 +#define HI3670_PCLK_AO_GPIO1 25 +#define HI3670_PCLK_AO_GPIO2 26 +#define HI3670_PCLK_AO_GPIO3 27 +#define HI3670_PCLK_AO_GPIO4 28 +#define HI3670_PCLK_AO_GPIO5 29 +#define HI3670_PCLK_AO_GPIO6 30 +#define HI3670_CLK_GATE_OUT0 31 +#define HI3670_CLK_GATE_OUT1 32 +#define HI3670_PCLK_GATE_SYSCNT 33 +#define HI3670_CLK_GATE_SYSCNT 34 +#define HI3670_CLK_GATE_ASP_SUBSYS_PERI 35 +#define HI3670_CLK_GATE_ASP_SUBSYS 36 +#define HI3670_CLK_GATE_ASP_TCXO 37 +#define HI3670_CLK_GATE_DP_AUDIO_PLL 38 + +/* clk in pmuctrl */ +#define HI3670_GATE_ABB_192 0 + +/* clk in pctrl */ +#define HI3670_GATE_UFS_TCXO_EN 0 +#define HI3670_GATE_USB_TCXO_EN 1 + +/* clk in iomcu */ +#define HI3670_CLK_GATE_I2C0 0 +#define HI3670_CLK_GATE_I2C1 1 +#define HI3670_CLK_GATE_I2C2 2 +#define HI3670_CLK_GATE_SPI0 3 +#define HI3670_CLK_GATE_SPI2 4 +#define HI3670_CLK_GATE_UART3 5 +#define HI3670_CLK_I2C0_GATE_IOMCU 6 +#define HI3670_CLK_I2C1_GATE_IOMCU 7 +#define HI3670_CLK_I2C2_GATE_IOMCU 8 +#define HI3670_CLK_SPI0_GATE_IOMCU 9 +#define HI3670_CLK_SPI2_GATE_IOMCU 10 +#define HI3670_CLK_UART3_GATE_IOMCU 11 +#define HI3670_CLK_GATE_PERI0_IOMCU 12 + +/* clk in media1 */ +#define HI3670_CLK_GATE_VIVOBUS_ANDGT 0 +#define HI3670_CLK_ANDGT_EDC0 1 +#define HI3670_CLK_ANDGT_LDI0 2 +#define HI3670_CLK_ANDGT_LDI1 3 +#define HI3670_CLK_MMBUF_PLL_ANDGT 4 +#define HI3670_PCLK_MMBUF_ANDGT 5 +#define HI3670_CLK_MUX_VIVOBUS 6 +#define HI3670_CLK_MUX_EDC0 7 +#define HI3670_CLK_MUX_LDI0 8 +#define HI3670_CLK_MUX_LDI1 9 +#define HI3670_CLK_SW_MMBUF 10 +#define HI3670_CLK_DIV_VIVOBUS 11 +#define HI3670_CLK_DIV_EDC0 12 +#define HI3670_CLK_DIV_LDI0 13 +#define HI3670_CLK_DIV_LDI1 14 +#define HI3670_ACLK_DIV_MMBUF 15 +#define HI3670_PCLK_DIV_MMBUF 16 +#define HI3670_ACLK_GATE_NOC_DSS 17 +#define HI3670_PCLK_GATE_NOC_DSS_CFG 18 +#define HI3670_PCLK_GATE_MMBUF_CFG 19 +#define HI3670_PCLK_GATE_DISP_NOC_SUBSYS 20 +#define HI3670_ACLK_GATE_DISP_NOC_SUBSYS 21 +#define HI3670_PCLK_GATE_DSS 22 +#define HI3670_ACLK_GATE_DSS 23 +#define HI3670_CLK_GATE_VIVOBUSFREQ 24 +#define HI3670_CLK_GATE_EDC0 25 +#define HI3670_CLK_GATE_LDI0 26 +#define HI3670_CLK_GATE_LDI1FREQ 27 +#define HI3670_CLK_GATE_BRG 28 +#define HI3670_ACLK_GATE_ASC 29 +#define HI3670_CLK_GATE_DSS_AXI_MM 30 +#define HI3670_CLK_GATE_MMBUF 31 +#define HI3670_PCLK_GATE_MMBUF 32 +#define HI3670_CLK_GATE_ATDIV_VIVO 33 + +/* clk in media2 */ +#define HI3670_CLK_GATE_VDECFREQ 0 +#define HI3670_CLK_GATE_VENCFREQ 1 +#define HI3670_CLK_GATE_ICSFREQ 2 + +#endif /* __DT_BINDINGS_CLOCK_HI3670_H */ -- cgit v1.2.3 From f2a76a2955c0eb7514cdb5885e3d60a973301ae0 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 25 Sep 2018 18:35:58 +0100 Subject: clk: qcom: Add Global Clock controller (GCC) driver for SDM660 Add support for the global clock controller found on SDM660 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Based on CAF implementation. Signed-off-by: Taniya Das [craig: rename parents to fit upstream, and other cleanups] Signed-off-by: Craig Tatlor Acked-by: Rob Herring [sboyd@kernel.org: Rename gcc_660 to gcc_sdm660 and fix numbering of defines to avoid duplicates] Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc.txt | 2 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sdm660.c | 2479 ++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-sdm660.h | 156 ++ 5 files changed, 2647 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sdm660.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm660.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 664ea1fd6c76..45b827997f18 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -19,6 +19,8 @@ Required properties : "qcom,gcc-msm8996" "qcom,gcc-msm8998" "qcom,gcc-mdm9615" + "qcom,gcc-sdm630" + "qcom,gcc-sdm660" "qcom,gcc-sdm845" - reg : shall contain base register location and length diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 064768699fe7..0c1d42e519e3 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,15 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_GCC_660 + tristate "SDM660 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SDM660 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2C, USB, UFS, SDDC, PCIe, etc. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 21a45035930d..db49b018ed43 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o +obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c new file mode 100644 index 000000000000..b5f1e8f37c3d --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -0,0 +1,2479 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2018, Craig Tatlor. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_XO, + P_SLEEP_CLK, + P_GPLL0, + P_GPLL1, + P_GPLL4, + P_GPLL0_EARLY_DIV, + P_GPLL1_EARLY_DIV, +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const char * const gcc_parent_names_xo_gpll0[] = { + "xo", + "gpll0", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div[] = { + "xo", + "gpll0", + "sleep_clk", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_sleep_clk[] = { + { P_XO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const char * const gcc_parent_names_xo_sleep_clk[] = { + "xo", + "sleep_clk", +}; + +static const struct parent_map gcc_parent_map_xo_gpll4[] = { + { P_XO, 0 }, + { P_GPLL4, 5 }, +}; + +static const char * const gcc_parent_names_xo_gpll4[] = { + "xo", + "gpll4", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 3 }, + { P_GPLL1, 4 }, + { P_GPLL4, 5 }, + { P_GPLL1_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = { + "xo", + "gpll0", + "gpll0_early_div", + "gpll1", + "gpll4", + "gpll1_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 5 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll4", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 2 }, + { P_GPLL4, 5 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4[] = { + "xo", + "gpll0", + "gpll0_early_div", + "gpll4", +}; + +static struct clk_fixed_factor xo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "xo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll0_early = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll0_early_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early_div", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x00000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll1_early = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll1_early_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll1_early_div", + .parent_names = (const char *[]){ "gpll1_early" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_names = (const char *[]){ "gpll1_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll4_early = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) + { + .name = "gpll4", + .parent_names = (const char *[]) { "gpll4_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x19020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(15000000, P_GPLL0, 10, 1, 4), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x1900c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x1b020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x1b00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x1d020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x1d00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x1f020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x1f00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart1_apps_clk_src[] = { + F(3686400, P_GPLL0, 1, 96, 15625), + F(7372800, P_GPLL0, 1, 192, 15625), + F(14745600, P_GPLL0, 1, 384, 15625), + F(16000000, P_GPLL0, 5, 2, 15), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 5, 1, 5), + F(32000000, P_GPLL0, 1, 4, 75), + F(40000000, P_GPLL0, 15, 0, 0), + F(46400000, P_GPLL0, 1, 29, 375), + F(48000000, P_GPLL0, 12.5, 0, 0), + F(51200000, P_GPLL0, 1, 32, 375), + F(56000000, P_GPLL0, 1, 7, 75), + F(58982400, P_GPLL0, 1, 1536, 15625), + F(60000000, P_GPLL0, 10, 0, 0), + F(63157895, P_GPLL0, 9.5, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x1a00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x1c00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x26020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x28020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x2800c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x2a020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x2a00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x2c020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x2c00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart1_apps_clk_src = { + .cmd_rcgr = 0x2700c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart2_apps_clk_src = { + .cmd_rcgr = 0x2900c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp1_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_gpll0_clk_src[] = { + F(300000000, P_GPLL0, 2, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_gpll0_clk_src = { + .cmd_rcgr = 0x4805c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_hmss_gpll0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_gpll0_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_gpll4_clk_src[] = { + F(384000000, P_GPLL4, 4, 0, 0), + F(768000000, P_GPLL4, 2, 0, 0), + F(1536000000, P_GPLL4, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_gpll4_clk_src = { + .cmd_rcgr = 0x48074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll4, + .freq_tbl = ftbl_hmss_gpll4_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_gpll4_clk_src", + .parent_names = gcc_parent_names_xo_gpll4, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_rbcpr_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_rbcpr_clk_src = { + .cmd_rcgr = 0x48044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_hmss_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_rbcpr_clk_src", + .parent_names = gcc_parent_names_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_qspi_ser_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(80200000, P_GPLL1_EARLY_DIV, 5, 0, 0), + F(160400000, P_GPLL1, 5, 0, 0), + F(267333333, P_GPLL1, 3, 0, 0), + { } +}; + +static struct clk_rcg2 qspi_ser_clk_src = { + .cmd_rcgr = 0x4d00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div, + .freq_tbl = ftbl_qspi_ser_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qspi_ser_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3), + F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2), + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(192000000, P_GPLL4, 8, 0, 0), + F(384000000, P_GPLL4, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x1602c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div, + .freq_tbl = ftbl_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x16010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3), + F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2), + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(192000000, P_GPLL4, 8, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x14010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_axi_clk_src[] = { + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_axi_clk_src = { + .cmd_rcgr = 0x75018, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_axi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_ice_core_clk_src[] = { + F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_ice_core_clk_src = { + .cmd_rcgr = 0x76010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_ice_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 ufs_phy_aux_clk_src = { + .cmd_rcgr = 0x76044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_sleep_clk, + .freq_tbl = ftbl_hmss_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_phy_aux_clk_src", + .parent_names = gcc_parent_names_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_EARLY_DIV, 8, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_unipro_core_clk_src = { + .cmd_rcgr = 0x76028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_unipro_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb20_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 usb20_master_clk_src = { + .cmd_rcgr = 0x2f010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb20_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_master_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb20_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x2f024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb20_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_mock_utmi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(66666667, P_GPLL0_EARLY_DIV, 4.5, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), + F(133333333, P_GPLL0, 4.5, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0xf014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb30_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0_EARLY_DIV, 7.5, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0xf028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb30_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb3_phy_aux_clk_src[] = { + F(1200000, P_XO, 16, 0, 0), + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 usb3_phy_aux_clk_src = { + .cmd_rcgr = 0x5000c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_sleep_clk, + .freq_tbl = ftbl_usb3_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb3_phy_aux_clk_src", + .parent_names = gcc_parent_names_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre2_ufs_axi_clk = { + .halt_reg = 0x75034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x75034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_ufs_axi_clk", + .parent_names = (const char *[]){ + "ufs_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre2_usb3_axi_clk = { + .halt_reg = 0xf03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_usb3_axi_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x7106c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7106c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_hmss_axi_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_hmss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_mss_q6_axi_clk = { + .halt_reg = 0x4401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_mss_q6_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x19008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x19008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x19004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x19004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x1b008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x1b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x1d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x1d004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x1f008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x1f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x1a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x1c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0x25004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { + .halt_reg = 0x26004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { + .halt_reg = 0x28008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { + .halt_reg = 0x28004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { + .halt_reg = 0x2a008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2a008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { + .halt_reg = 0x2a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { + .halt_reg = 0x2c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { + .halt_reg = 0x2c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart1_apps_clk = { + .halt_reg = 0x27004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x27004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart2_apps_clk = { + .halt_reg = 0x29004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x29004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_axi_clk = { + .halt_reg = 0x5058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb2_axi_clk", + .parent_names = (const char *[]){ + "usb20_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_axi_clk = { + .halt_reg = 0x5018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_axi_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_ahb_clk = { + .halt_reg = 0x84004, + .clkr = { + .enable_reg = 0x84004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_bimc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_cfg_ahb_clk = { + .halt_reg = 0x71004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x71004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk", + .parent_names = (const char *[]){ + "gpll0_early_div", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_hmss_dvm_bus_clk = { + .halt_reg = 0x4808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4808c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hmss_dvm_bus_clk", + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch gcc_hmss_rbcpr_clk = { + .halt_reg = 0x48008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hmss_rbcpr_clk", + .parent_names = (const char *[]){ + "hmss_rbcpr_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_gpll0_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_clk", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_gpll0_div_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_div_clk", + .parent_names = (const char *[]){ + "gpll0_early_div", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { + .halt_reg = 0x9004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_noc_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_sys_noc_axi_clk = { + .halt_reg = 0x9000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_sys_noc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x8a040, + .clkr = { + .enable_reg = 0x8a040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a03c, + .clkr = { + .enable_reg = 0x8a03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_names = (const char *[]){ + "pdm2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ser_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ser_clk", + .parent_names = (const char *[]){ + "qspi_ser_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx0_usb2_clkref_clk = { + .halt_reg = 0x88018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x88018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx0_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx1_usb2_clkref_clk = { + .halt_reg = 0x88014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x88014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx1_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x16008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x1600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_names = (const char *[]){ + "sdcc1_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_names = (const char *[]){ + "sdcc2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ahb_clk = { + .halt_reg = 0x7500c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7500c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_axi_clk = { + .halt_reg = 0x75008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x75008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_axi_clk", + .parent_names = (const char *[]){ + "ufs_axi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_clkref_clk = { + .halt_reg = 0x88008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x88008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ice_core_clk = { + .halt_reg = 0x7600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ice_core_clk", + .parent_names = (const char *[]){ + "ufs_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_aux_clk = { + .halt_reg = 0x76040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x76040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_aux_clk", + .parent_names = (const char *[]){ + "ufs_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_0_clk = { + .halt_reg = 0x75014, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x75014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_1_clk = { + .halt_reg = 0x7605c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7605c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_tx_symbol_0_clk = { + .halt_reg = 0x75010, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_unipro_core_clk = { + .halt_reg = 0x76008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x76008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_unipro_core_clk", + .parent_names = (const char *[]){ + "ufs_unipro_core_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0x2f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_master_clk", + .parent_names = (const char *[]){ + "usb20_master_clk_src" + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0x2f00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb20_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0x2f008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0xf008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_master_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mock_utmi_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sleep_clk = { + .halt_reg = 0xf00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_clkref_clk = { + .halt_reg = 0x8800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_aux_clk = { + .halt_reg = 0x50000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_aux_clk", + .parent_names = (const char *[]){ + "usb3_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_pipe_clk = { + .halt_reg = 0x50004, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x50004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc ufs_gdsc = { + .gdscr = 0x75004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "ufs_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc usb_30_gdsc = { + .gdscr = 0xf004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "usb_30_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc pcie_0_gdsc = { + .gdscr = 0x6b004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct clk_hw *gcc_sdm660_hws[] = { + &xo.hw, + &gpll0_early_div.hw, + &gpll1_early_div.hw, +}; + +static struct clk_regmap *gcc_sdm660_clocks[] = { + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, + [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_HMSS_AXI_CLK] = &gcc_bimc_hmss_axi_clk.clkr, + [GCC_BIMC_MSS_Q6_AXI_CLK] = &gcc_bimc_mss_q6_axi_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CFG_NOC_USB2_AXI_CLK] = &gcc_cfg_noc_usb2_axi_clk.clkr, + [GCC_CFG_NOC_USB3_AXI_CLK] = &gcc_cfg_noc_usb3_axi_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr, + [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, + [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr, + [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr, + [GCC_HMSS_DVM_BUS_CLK] = &gcc_hmss_dvm_bus_clk.clkr, + [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr, + [GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr, + [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, + [GCC_MMSS_NOC_CFG_AHB_CLK] = &gcc_mmss_noc_cfg_ahb_clk.clkr, + [GCC_MMSS_SYS_NOC_AXI_CLK] = &gcc_mmss_sys_noc_axi_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, + [GCC_QSPI_SER_CLK] = &gcc_qspi_ser_clk.clkr, + [GCC_RX0_USB2_CLKREF_CLK] = &gcc_rx0_usb2_clkref_clk.clkr, + [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, + [GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr, + [GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr, + [GCC_UFS_ICE_CORE_CLK] = &gcc_ufs_ice_core_clk.clkr, + [GCC_UFS_PHY_AUX_CLK] = &gcc_ufs_phy_aux_clk.clkr, + [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, + [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, + [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, + [GCC_UFS_UNIPRO_CORE_CLK] = &gcc_ufs_unipro_core_clk.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr, + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL1] = &gpll1.clkr, + [GPLL1_EARLY] = &gpll1_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr, + [HMSS_GPLL4_CLK_SRC] = &hmss_gpll4_clk_src.clkr, + [HMSS_RBCPR_CLK_SRC] = &hmss_rbcpr_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [QSPI_SER_CLK_SRC] = &qspi_ser_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr, + [UFS_ICE_CORE_CLK_SRC] = &ufs_ice_core_clk_src.clkr, + [UFS_PHY_AUX_CLK_SRC] = &ufs_phy_aux_clk_src.clkr, + [UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr, + [USB20_MASTER_CLK_SRC] = &usb20_master_clk_src.clkr, + [USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr, + [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, +}; + +static struct gdsc *gcc_sdm660_gdscs[] = { + [UFS_GDSC] = &ufs_gdsc, + [USB_30_GDSC] = &usb_30_gdsc, + [PCIE_0_GDSC] = &pcie_0_gdsc, +}; + +static const struct qcom_reset_map gcc_sdm660_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_UFS_BCR] = { 0x75000 }, + [GCC_USB3_DP_PHY_BCR] = { 0x50028 }, + [GCC_USB3_PHY_BCR] = { 0x50020 }, + [GCC_USB3PHY_PHY_BCR] = { 0x50024 }, + [GCC_USB_20_BCR] = { 0x2f000 }, + [GCC_USB_30_BCR] = { 0xf000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static const struct regmap_config gcc_sdm660_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x94000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sdm660_desc = { + .config = &gcc_sdm660_regmap_config, + .clks = gcc_sdm660_clocks, + .num_clks = ARRAY_SIZE(gcc_sdm660_clocks), + .resets = gcc_sdm660_resets, + .num_resets = ARRAY_SIZE(gcc_sdm660_resets), + .gdscs = gcc_sdm660_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sdm660_gdscs), +}; + +static const struct of_device_id gcc_sdm660_match_table[] = { + { .compatible = "qcom,gcc-sdm630" }, + { .compatible = "qcom,gcc-sdm660" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sdm660_match_table); + +static int gcc_sdm660_probe(struct platform_device *pdev) +{ + int i, ret; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_sdm660_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be + * turned off by hardware during certain apps low power modes. + */ + ret = regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); + if (ret) + return ret; + + /* Register the hws */ + for (i = 0; i < ARRAY_SIZE(gcc_sdm660_hws); i++) { + ret = devm_clk_hw_register(&pdev->dev, gcc_sdm660_hws[i]); + if (ret) + return ret; + } + + return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap); +} + +static struct platform_driver gcc_sdm660_driver = { + .probe = gcc_sdm660_probe, + .driver = { + .name = "gcc-sdm660", + .of_match_table = gcc_sdm660_match_table, + }, +}; + +static int __init gcc_sdm660_init(void) +{ + return platform_driver_register(&gcc_sdm660_driver); +} +core_initcall_sync(gcc_sdm660_init); + +static void __exit gcc_sdm660_exit(void) +{ + platform_driver_unregister(&gcc_sdm660_driver); +} +module_exit(gcc_sdm660_exit); + +MODULE_DESCRIPTION("QCOM GCC sdm660 Driver"); diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h new file mode 100644 index 000000000000..468302282913 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2018, Craig Tatlor. + */ + +#ifndef _DT_BINDINGS_CLK_MSM_GCC_660_H +#define _DT_BINDINGS_CLK_MSM_GCC_660_H + +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 0 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 1 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 2 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 3 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 4 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 5 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 6 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 7 +#define BLSP1_UART1_APPS_CLK_SRC 8 +#define BLSP1_UART2_APPS_CLK_SRC 9 +#define BLSP2_QUP1_I2C_APPS_CLK_SRC 10 +#define BLSP2_QUP1_SPI_APPS_CLK_SRC 11 +#define BLSP2_QUP2_I2C_APPS_CLK_SRC 12 +#define BLSP2_QUP2_SPI_APPS_CLK_SRC 13 +#define BLSP2_QUP3_I2C_APPS_CLK_SRC 14 +#define BLSP2_QUP3_SPI_APPS_CLK_SRC 15 +#define BLSP2_QUP4_I2C_APPS_CLK_SRC 16 +#define BLSP2_QUP4_SPI_APPS_CLK_SRC 17 +#define BLSP2_UART1_APPS_CLK_SRC 18 +#define BLSP2_UART2_APPS_CLK_SRC 19 +#define GCC_AGGRE2_UFS_AXI_CLK 20 +#define GCC_AGGRE2_USB3_AXI_CLK 21 +#define GCC_BIMC_GFX_CLK 22 +#define GCC_BIMC_HMSS_AXI_CLK 23 +#define GCC_BIMC_MSS_Q6_AXI_CLK 24 +#define GCC_BLSP1_AHB_CLK 25 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 26 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 27 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 28 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 29 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 30 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 31 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 32 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 33 +#define GCC_BLSP1_UART1_APPS_CLK 34 +#define GCC_BLSP1_UART2_APPS_CLK 35 +#define GCC_BLSP2_AHB_CLK 36 +#define GCC_BLSP2_QUP1_I2C_APPS_CLK 37 +#define GCC_BLSP2_QUP1_SPI_APPS_CLK 38 +#define GCC_BLSP2_QUP2_I2C_APPS_CLK 39 +#define GCC_BLSP2_QUP2_SPI_APPS_CLK 40 +#define GCC_BLSP2_QUP3_I2C_APPS_CLK 41 +#define GCC_BLSP2_QUP3_SPI_APPS_CLK 42 +#define GCC_BLSP2_QUP4_I2C_APPS_CLK 43 +#define GCC_BLSP2_QUP4_SPI_APPS_CLK 44 +#define GCC_BLSP2_UART1_APPS_CLK 45 +#define GCC_BLSP2_UART2_APPS_CLK 46 +#define GCC_BOOT_ROM_AHB_CLK 47 +#define GCC_CFG_NOC_USB2_AXI_CLK 48 +#define GCC_CFG_NOC_USB3_AXI_CLK 49 +#define GCC_DCC_AHB_CLK 50 +#define GCC_GP1_CLK 51 +#define GCC_GP2_CLK 52 +#define GCC_GP3_CLK 53 +#define GCC_GPU_BIMC_GFX_CLK 54 +#define GCC_GPU_CFG_AHB_CLK 55 +#define GCC_GPU_GPLL0_CLK 56 +#define GCC_GPU_GPLL0_DIV_CLK 57 +#define GCC_HMSS_DVM_BUS_CLK 58 +#define GCC_HMSS_RBCPR_CLK 59 +#define GCC_MMSS_GPLL0_CLK 60 +#define GCC_MMSS_GPLL0_DIV_CLK 61 +#define GCC_MMSS_NOC_CFG_AHB_CLK 62 +#define GCC_MMSS_SYS_NOC_AXI_CLK 63 +#define GCC_MSS_CFG_AHB_CLK 64 +#define GCC_MSS_GPLL0_DIV_CLK 65 +#define GCC_MSS_MNOC_BIMC_AXI_CLK 66 +#define GCC_MSS_Q6_BIMC_AXI_CLK 67 +#define GCC_MSS_SNOC_AXI_CLK 68 +#define GCC_PDM2_CLK 69 +#define GCC_PDM_AHB_CLK 70 +#define GCC_PRNG_AHB_CLK 71 +#define GCC_QSPI_AHB_CLK 72 +#define GCC_QSPI_SER_CLK 73 +#define GCC_SDCC1_AHB_CLK 74 +#define GCC_SDCC1_APPS_CLK 75 +#define GCC_SDCC1_ICE_CORE_CLK 76 +#define GCC_SDCC2_AHB_CLK 77 +#define GCC_SDCC2_APPS_CLK 78 +#define GCC_UFS_AHB_CLK 79 +#define GCC_UFS_AXI_CLK 80 +#define GCC_UFS_CLKREF_CLK 81 +#define GCC_UFS_ICE_CORE_CLK 82 +#define GCC_UFS_PHY_AUX_CLK 83 +#define GCC_UFS_RX_SYMBOL_0_CLK 84 +#define GCC_UFS_RX_SYMBOL_1_CLK 85 +#define GCC_UFS_TX_SYMBOL_0_CLK 86 +#define GCC_UFS_UNIPRO_CORE_CLK 87 +#define GCC_USB20_MASTER_CLK 88 +#define GCC_USB20_MOCK_UTMI_CLK 89 +#define GCC_USB20_SLEEP_CLK 90 +#define GCC_USB30_MASTER_CLK 91 +#define GCC_USB30_MOCK_UTMI_CLK 92 +#define GCC_USB30_SLEEP_CLK 93 +#define GCC_USB3_CLKREF_CLK 94 +#define GCC_USB3_PHY_AUX_CLK 95 +#define GCC_USB3_PHY_PIPE_CLK 96 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 97 +#define GP1_CLK_SRC 98 +#define GP2_CLK_SRC 99 +#define GP3_CLK_SRC 100 +#define GPLL0 101 +#define GPLL0_EARLY 102 +#define GPLL1 103 +#define GPLL1_EARLY 104 +#define GPLL4 105 +#define GPLL4_EARLY 106 +#define HMSS_GPLL0_CLK_SRC 107 +#define HMSS_GPLL4_CLK_SRC 108 +#define HMSS_RBCPR_CLK_SRC 109 +#define PDM2_CLK_SRC 110 +#define QSPI_SER_CLK_SRC 111 +#define SDCC1_APPS_CLK_SRC 112 +#define SDCC1_ICE_CORE_CLK_SRC 113 +#define SDCC2_APPS_CLK_SRC 114 +#define UFS_AXI_CLK_SRC 115 +#define UFS_ICE_CORE_CLK_SRC 116 +#define UFS_PHY_AUX_CLK_SRC 117 +#define UFS_UNIPRO_CORE_CLK_SRC 118 +#define USB20_MASTER_CLK_SRC 119 +#define USB20_MOCK_UTMI_CLK_SRC 120 +#define USB30_MASTER_CLK_SRC 121 +#define USB30_MOCK_UTMI_CLK_SRC 122 +#define USB3_PHY_AUX_CLK_SRC 123 +#define GPLL0_OUT_MSSCC 124 +#define GCC_UFS_AXI_HW_CTL_CLK 125 +#define GCC_UFS_ICE_CORE_HW_CTL_CLK 126 +#define GCC_UFS_PHY_AUX_HW_CTL_CLK 127 +#define GCC_UFS_UNIPRO_CORE_HW_CTL_CLK 128 +#define GCC_RX0_USB2_CLKREF_CLK 129 +#define GCC_RX1_USB2_CLKREF_CLK 130 + +#define PCIE_0_GDSC 0 +#define UFS_GDSC 1 +#define USB_30_GDSC 2 + +#define GCC_QUSB2PHY_PRIM_BCR 0 +#define GCC_QUSB2PHY_SEC_BCR 1 +#define GCC_UFS_BCR 2 +#define GCC_USB3_DP_PHY_BCR 3 +#define GCC_USB3_PHY_BCR 4 +#define GCC_USB3PHY_PHY_BCR 5 +#define GCC_USB_20_BCR 6 +#define GCC_USB_30_BCR 7 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 8 + +#endif -- cgit v1.2.3 From 652f1813c113a3f5169cd1325201fdf9b2d22ded Mon Sep 17 00:00:00 2001 From: Shefali Jain Date: Wed, 10 Oct 2018 20:21:38 +0530 Subject: clk: qcom: gcc: Add global clock controller driver for QCS404 Add the clocks supported in global clock controller which clock the peripherals like BLSPs, SDCC, USB, MDSS etc. Register all the clocks to the clock framework for the clients to be able to request for them. Signed-off-by: Shefali Jain Signed-off-by: Taniya Das Co-developed-by: Taniya Das Signed-off-by: Anu Ramanathan [bamse, vkoul: rebase and tidyup for upstream] Signed-off-by: Bjorn Andersson Signed-off-by: Vinod Koul Acked-by: Rob Herring [sboyd@kernel.org: Lowercase hex] Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc.txt | 1 + drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-qcs404.c | 2744 ++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-qcs404.h | 165 ++ 5 files changed, 2919 insertions(+) create mode 100644 drivers/clk/qcom/gcc-qcs404.c create mode 100644 include/dt-bindings/clock/qcom,gcc-qcs404.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 664ea1fd6c76..69fa8603b5ab 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -19,6 +19,7 @@ Required properties : "qcom,gcc-msm8996" "qcom,gcc-msm8998" "qcom,gcc-mdm9615" + "qcom,gcc-qcs404" "qcom,gcc-sdm845" - reg : shall contain base register location and length diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 064768699fe7..13dbfa3d9698 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config QCS_GCC_404 + tristate "QCS404 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on QCS404 devices. + Say Y if you want to use multimedia devices or peripheral + devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 21a45035930d..37197b90ddf5 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o +obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c new file mode 100644 index 000000000000..e4ca6a45f313 --- /dev/null +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -0,0 +1,2744 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "reset.h" + +enum { + P_CORE_BI_PLL_TEST_SE, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_GPLL0_OUT_AUX, + P_GPLL0_OUT_MAIN, + P_GPLL1_OUT_MAIN, + P_GPLL3_OUT_MAIN, + P_GPLL4_OUT_AUX, + P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_AUX, + P_HDMI_PHY_PLL_CLK, + P_PCIE_0_PIPE_CLK, + P_SLEEP_CLK, + P_XO, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_0[] = { + "cxo", + "gpll0_out_main", + "core_bi_pll_test_se", +}; + +static const char * const gcc_parent_names_ao_0[] = { + "cxo", + "gpll0_ao_out_main", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_XO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_1[] = { + "cxo", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_AUX, 2 }, + { P_SLEEP_CLK, 6 }, +}; + +static const char * const gcc_parent_names_2[] = { + "cxo", + "gpll0_out_main", + "gpll6_out_aux", + "sleep_clk", +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_3[] = { + "cxo", + "gpll0_out_main", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_XO, 0 }, + { P_GPLL1_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_4[] = { + "cxo", + "gpll1_out_main", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_5[] = { + "cxo", + "dsi0pll_byteclk_src", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_GPLL0_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_6[] = { + "cxo", + "dsi0_phy_pll_out_byteclk", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL3_OUT_MAIN, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_GPLL4_OUT_AUX, 4 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_7[] = { + "cxo", + "gpll0_out_main", + "gpll3_out_main", + "gpll6_out_aux", + "gpll4_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_XO, 0 }, + { P_HDMI_PHY_PLL_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_8[] = { + "cxo", + "hdmi_phy_pll_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_9[] = { + "cxo", + "gpll0_out_main", + "dsi0_phy_pll_out_dsiclk", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_XO, 0 }, + { P_SLEEP_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_10[] = { + "cxo", + "sleep_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_XO, 0 }, + { P_PCIE_0_PIPE_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_11[] = { + "cxo", + "pcie_0_pipe_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_12[] = { + "cxo", + "dsi0pll_pclk_src", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_13[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_MAIN, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_13[] = { + "cxo", + "gpll0_out_main", + "gpll4_out_main", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_14[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_14[] = { + "cxo", + "gpll0_out_main", + "gpll4_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_15[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_15[] = { + "cxo", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static struct clk_fixed_factor cxo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "cxo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll0_sleep_clk_src = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45008, + .enable_mask = BIT(23), + .enable_is_inverted = true, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_sleep_clk_src", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll0_out_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .flags = SUPPORTS_FSM_MODE, + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_main", + .parent_names = (const char *[]) + { "gpll0_sleep_clk_src" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll0_ao_out_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .flags = SUPPORTS_FSM_MODE, + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_ao_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll1_out_main = { + .offset = 0x20000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* 930MHz configuration */ +static const struct alpha_pll_config gpll3_config = { + .l = 48, + .alpha = 0x0, + .alpha_en_mask = BIT(24), + .post_div_mask = 0xf << 8, + .post_div_val = 0x1 << 8, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, + .config_ctl_val = 0x4001055b, +}; + +static const struct pll_vco gpll3_vco[] = { + { 700000000, 1400000000, 0 }, +}; + +static struct clk_alpha_pll gpll3_out_main = { + .offset = 0x22000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .vco_table = gpll3_vco, + .num_vco = ARRAY_SIZE(gpll3_vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpll3_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4_out_main = { + .offset = 0x24000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_pll gpll6 = { + .l_reg = 0x37004, + .m_reg = 0x37008, + .n_reg = 0x3700C, + .config_reg = 0x37014, + .mode_reg = 0x37000, + .status_reg = 0x3701C, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll6_out_aux = { + .enable_reg = 0x45000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll6_out_aux", + .parent_names = (const char *[]){ "gpll6" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_apss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_names = gcc_parent_names_ao_0, + .num_parents = 3, + .flags = CLK_IS_CRITICAL, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup0_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup0_i2c_apps_clk_src = { + .cmd_rcgr = 0x602c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup0_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup0_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup0_spi_apps_clk_src = { + .cmd_rcgr = 0x6034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup0_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x200c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(10480000, P_GPLL0_OUT_MAIN, 1, 3, 229), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(20961000, P_GPLL0_OUT_MAIN, 1, 6, 229), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x3000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup2_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(15000000, P_GPLL0_OUT_MAIN, 1, 3, 160), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(30000000, P_GPLL0_OUT_MAIN, 1, 3, 80), + { } +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x3014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup2_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x4024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x5000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x5024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart0_apps_clk_src[] = { + F(3686400, P_GPLL0_OUT_MAIN, 1, 72, 15625), + F(7372800, P_GPLL0_OUT_MAIN, 1, 144, 15625), + F(14745600, P_GPLL0_OUT_MAIN, 1, 288, 15625), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0_OUT_MAIN, 1, 3, 100), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25), + F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20), + F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500), + F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50), + F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125), + F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100), + F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625), + F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40), + F(64000000, P_GPLL0_OUT_MAIN, 1, 2, 25), + { } +}; + +static struct clk_rcg2 blsp1_uart0_apps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart0_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x2044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x3034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart3_apps_clk_src = { + .cmd_rcgr = 0x4014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart3_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup0_i2c_apps_clk_src = { + .cmd_rcgr = 0xc00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup0_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup0_spi_apps_clk_src = { + .cmd_rcgr = 0xc024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup0_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart0_apps_clk_src = { + .cmd_rcgr = 0xc044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart0_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x4d044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = gcc_parent_names_5, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_emac_clk_src[] = { + F(5000000, P_GPLL1_OUT_MAIN, 2, 1, 50), + F(50000000, P_GPLL1_OUT_MAIN, 10, 0, 0), + F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 emac_clk_src = { + .cmd_rcgr = 0x4e01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_emac_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "emac_clk_src", + .parent_names = gcc_parent_names_4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_emac_ptp_clk_src[] = { + F(50000000, P_GPLL1_OUT_MAIN, 10, 0, 0), + F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 emac_ptp_clk_src = { + .cmd_rcgr = 0x4e014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_emac_ptp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "emac_ptp_clk_src", + .parent_names = gcc_parent_names_4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_esc0_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x4d05c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = gcc_parent_names_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(228571429, P_GPLL0_OUT_MAIN, 3.5, 0, 0), + F(240000000, P_GPLL6_OUT_AUX, 4.5, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(270000000, P_GPLL6_OUT_AUX, 4, 0, 0), + F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(484800000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(523200000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(550000000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(598000000, P_GPLL3_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x59000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gfx3d_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = gcc_parent_names_7, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp1_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x8004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x9004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0xa004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hdmi_app_clk_src = { + .cmd_rcgr = 0x4d0e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_app_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hdmi_pclk_clk_src = { + .cmd_rcgr = 0x4d0dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_pclk_clk_src", + .parent_names = gcc_parent_names_8, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(145454545, P_GPLL0_OUT_MAIN, 5.5, 0, 0), + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x4d014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = gcc_parent_names_9, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_0_aux_clk_src[] = { + F(1200000, P_XO, 16, 0, 0), + { } +}; + +static struct clk_rcg2 pcie_0_aux_clk_src = { + .cmd_rcgr = 0x3e024, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie_0_aux_clk_src", + .parent_names = gcc_parent_names_10, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_0_pipe_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(125000000, P_PCIE_0_PIPE_CLK, 2, 0, 0), + F(250000000, P_PCIE_0_PIPE_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 pcie_0_pipe_clk_src = { + .cmd_rcgr = 0x3e01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_pcie_0_pipe_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie_0_pipe_clk_src", + .parent_names = gcc_parent_names_11, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x4d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = gcc_parent_names_12, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x44010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(192000000, P_GPLL4_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(384000000, P_GPLL4_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_13, + .freq_tbl = ftbl_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_parent_names_13, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = { + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x5d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_names = gcc_parent_names_3, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x43004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_14, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_parent_names_14, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x41048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_mock_utmi_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0x39028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_usb30_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x3901c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb3_phy_aux_clk_src = { + .cmd_rcgr = 0x3903c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb3_phy_aux_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_hs_system_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x41010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_usb_hs_system_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_names = gcc_parent_names_3, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x4d02c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_15, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = gcc_parent_names_15, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x4601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_names = (const char *[]){ + "apss_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_tcu_clk = { + .halt_reg = 0x5b004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x59034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + .parent_names = (const char *[]){ + "gcc_apss_tcu_clk", + }, + + }, + }, +}; + +static struct clk_branch gcc_bimc_gpu_clk = { + .halt_reg = 0x59030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gpu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_mdss_clk = { + .halt_reg = 0x31038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_mdss_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x1008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_clk = { + .halt_reg = 0x77004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x77004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_xo_clk = { + .halt_reg = 0x77008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x77008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup0_i2c_apps_clk = { + .halt_reg = 0x6028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup0_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup0_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup0_spi_apps_clk = { + .halt_reg = 0x6024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup0_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup0_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x2008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x3010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x4020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x5020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart0_apps_clk = { + .halt_reg = 0x6004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart0_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart0_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x302c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart3_apps_clk = { + .halt_reg = 0x400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart3_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart3_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0xb008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup0_i2c_apps_clk = { + .halt_reg = 0xc008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup0_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup0_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup0_spi_apps_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup0_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup0_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart0_apps_clk = { + .halt_reg = 0xc03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart0_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart0_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_axi_clk = { + .halt_reg = 0x4e010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_ptp_clk = { + .halt_reg = 0x4e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_ptp_clk", + .parent_names = (const char *[]){ + "emac_ptp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_rgmii_clk = { + .halt_reg = 0x4e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_rgmii_clk", + .parent_names = (const char *[]){ + "emac_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_slave_ahb_clk = { + .halt_reg = 0x4e00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_slave_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_geni_ir_s_clk = { + .halt_reg = 0xf008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_geni_ir_s_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_geni_ir_h_clk = { + .halt_reg = 0xf004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_geni_ir_h_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tcu_clk = { + .halt_reg = 0x12020, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500C, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tbu_clk = { + .halt_reg = 0x12010, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500C, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x8000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x9000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0xa000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gtcu_ahb_clk = { + .halt_reg = 0x12044, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gtcu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdp_tbu_clk = { + .halt_reg = 0x1201c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdp_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_ahb_clk = { + .halt_reg = 0x4d07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_axi_clk = { + .halt_reg = 0x4d080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_byte0_clk = { + .halt_reg = 0x4d094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_byte0_clk", + .parent_names = (const char *[]){ + "byte0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_esc0_clk = { + .halt_reg = 0x4d098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_esc0_clk", + .parent_names = (const char *[]){ + "esc0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_hdmi_app_clk = { + .halt_reg = 0x4d0d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0d8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_hdmi_app_clk", + .parent_names = (const char *[]){ + "hdmi_app_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_hdmi_pclk_clk = { + .halt_reg = 0x4d0d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_hdmi_pclk_clk", + .parent_names = (const char *[]){ + "hdmi_pclk_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_mdp_clk = { + .halt_reg = 0x4d088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_mdp_clk", + .parent_names = (const char *[]){ + "mdp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_pclk0_clk = { + .halt_reg = 0x4d084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_pclk0_clk", + .parent_names = (const char *[]){ + "pclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_vsync_clk = { + .halt_reg = 0x4d090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_vsync_clk", + .parent_names = (const char *[]){ + "vsync_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_ahb_clk = { + .halt_reg = 0x59028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_gfx3d_clk = { + .halt_reg = 0x59020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_gfx3d_clk", + .parent_names = (const char *[]){ + "gfx3d_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x3e014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk", + .parent_names = (const char *[]){ + "pcie_0_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x3e008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x3e018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x3e00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(28), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_pipe_clk", + .parent_names = (const char *[]){ + "pcie_0_pipe_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x3e010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcnoc_usb2_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcnoc_usb2_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcnoc_usb3_clk = { + .halt_reg = 0x2700c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2700c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcnoc_usb3_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x4400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_names = (const char *[]){ + "pdm2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x44004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* PWM clks do not have XO as parent as src clk is a balance root */ +static struct clk_branch gcc_pwm0_xo512_clk = { + .halt_reg = 0x44018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm0_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm1_xo512_clk = { + .halt_reg = 0x49004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm1_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm2_xo512_clk = { + .halt_reg = 0x4a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm2_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qdss_dap_clk = { + .halt_reg = 0x29084, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qdss_dap_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x4201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x42018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x5d014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5d014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_names = (const char *[]){ + "sdcc1_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x4301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x43018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x43018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_names = (const char *[]){ + "sdcc2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_cfg_clk = { + .halt_reg = 0x12038, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x3600C, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_cfg_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_usb3_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_inactivity_timers_clk = { + .halt_reg = 0x4100C, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4100C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_inactivity_timers_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0x41044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb20_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2a_phy_sleep_clk = { + .halt_reg = 0x4102c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4102c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2a_phy_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0x3900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3900c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_master_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mock_utmi_clk = { + .halt_reg = 0x39014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sleep_clk = { + .halt_reg = 0x39010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_aux_clk = { + .halt_reg = 0x39044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_aux_clk", + .parent_names = (const char *[]){ + "usb3_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_pipe_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x39018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = { + .halt_reg = 0x41030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_phy_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_system_clk = { + .halt_reg = 0x41004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_system_clk", + .parent_names = (const char *[]){ + "usb_hs_system_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *gcc_qcs404_hws[] = { + &cxo.hw, +}; + +static struct clk_regmap *gcc_qcs404_clocks[] = { + [GCC_APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [GCC_BLSP1_QUP0_I2C_APPS_CLK_SRC] = &blsp1_qup0_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP0_SPI_APPS_CLK_SRC] = &blsp1_qup0_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [GCC_BLSP1_UART0_APPS_CLK_SRC] = &blsp1_uart0_apps_clk_src.clkr, + [GCC_BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [GCC_BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [GCC_BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [GCC_BLSP2_QUP0_I2C_APPS_CLK_SRC] = &blsp2_qup0_i2c_apps_clk_src.clkr, + [GCC_BLSP2_QUP0_SPI_APPS_CLK_SRC] = &blsp2_qup0_spi_apps_clk_src.clkr, + [GCC_BLSP2_UART0_APPS_CLK_SRC] = &blsp2_uart0_apps_clk_src.clkr, + [GCC_BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [GCC_EMAC_CLK_SRC] = &emac_clk_src.clkr, + [GCC_EMAC_PTP_CLK_SRC] = &emac_ptp_clk_src.clkr, + [GCC_ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_MDSS_CLK] = &gcc_bimc_mdss_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP0_I2C_APPS_CLK] = &gcc_blsp1_qup0_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP0_SPI_APPS_CLK] = &gcc_blsp1_qup0_spi_apps_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART0_APPS_CLK] = &gcc_blsp1_uart0_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP0_I2C_APPS_CLK] = &gcc_blsp2_qup0_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP0_SPI_APPS_CLK] = &gcc_blsp2_qup0_spi_apps_clk.clkr, + [GCC_BLSP2_UART0_APPS_CLK] = &gcc_blsp2_uart0_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_ETH_AXI_CLK] = &gcc_eth_axi_clk.clkr, + [GCC_ETH_PTP_CLK] = &gcc_eth_ptp_clk.clkr, + [GCC_ETH_RGMII_CLK] = &gcc_eth_rgmii_clk.clkr, + [GCC_ETH_SLAVE_AHB_CLK] = &gcc_eth_slave_ahb_clk.clkr, + [GCC_GENI_IR_S_CLK] = &gcc_geni_ir_s_clk.clkr, + [GCC_GENI_IR_H_CLK] = &gcc_geni_ir_h_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr, + [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr, + [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [GCC_MDSS_HDMI_APP_CLK] = &gcc_mdss_hdmi_app_clk.clkr, + [GCC_MDSS_HDMI_PCLK_CLK] = &gcc_mdss_hdmi_pclk_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCNOC_USB2_CLK] = &gcc_pcnoc_usb2_clk.clkr, + [GCC_PCNOC_USB3_CLK] = &gcc_pcnoc_usb3_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_PWM0_XO512_CLK] = &gcc_pwm0_xo512_clk.clkr, + [GCC_PWM1_XO512_CLK] = &gcc_pwm1_xo512_clk.clkr, + [GCC_PWM2_XO512_CLK] = &gcc_pwm2_xo512_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SYS_NOC_USB3_CLK] = &gcc_sys_noc_usb3_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [GCC_GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GCC_GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GCC_GP3_CLK_SRC] = &gp3_clk_src.clkr, + [GCC_GPLL0_OUT_MAIN] = &gpll0_out_main.clkr, + [GCC_GPLL0_AO_OUT_MAIN] = &gpll0_ao_out_main.clkr, + [GCC_GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr, + [GCC_GPLL1_OUT_MAIN] = &gpll1_out_main.clkr, + [GCC_GPLL3_OUT_MAIN] = &gpll3_out_main.clkr, + [GCC_GPLL4_OUT_MAIN] = &gpll4_out_main.clkr, + [GCC_GPLL6] = &gpll6.clkr, + [GCC_GPLL6_OUT_AUX] = &gpll6_out_aux, + [GCC_HDMI_APP_CLK_SRC] = &hdmi_app_clk_src.clkr, + [GCC_HDMI_PCLK_CLK_SRC] = &hdmi_pclk_clk_src.clkr, + [GCC_MDP_CLK_SRC] = &mdp_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK_SRC] = &pcie_0_pipe_clk_src.clkr, + [GCC_PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [GCC_PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr, + [GCC_USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [GCC_USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [GCC_USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, + [GCC_USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [GCC_VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [GCC_USB_HS_INACTIVITY_TIMERS_CLK] = + &gcc_usb_hs_inactivity_timers_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr, + [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr, + [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, + [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr, +}; + +static const struct qcom_reset_map gcc_qcs404_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_EMAC_BCR] = { 0x4e000 }, +}; + +static const struct regmap_config gcc_qcs404_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x7f000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_qcs404_desc = { + .config = &gcc_qcs404_regmap_config, + .clks = gcc_qcs404_clocks, + .num_clks = ARRAY_SIZE(gcc_qcs404_clocks), + .resets = gcc_qcs404_resets, + .num_resets = ARRAY_SIZE(gcc_qcs404_resets), +}; + +static const struct of_device_id gcc_qcs404_match_table[] = { + { .compatible = "qcom,gcc-qcs404" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_qcs404_match_table); + +static int gcc_qcs404_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret, i; + + regmap = qcom_cc_map(pdev, &gcc_qcs404_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config); + + for (i = 0; i < ARRAY_SIZE(gcc_qcs404_hws); i++) { + ret = devm_clk_hw_register(&pdev->dev, gcc_qcs404_hws[i]); + if (ret) + return ret; + } + + return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap); +} + +static struct platform_driver gcc_qcs404_driver = { + .probe = gcc_qcs404_probe, + .driver = { + .name = "gcc-qcs404", + .of_match_table = gcc_qcs404_match_table, + }, +}; + +static int __init gcc_qcs404_init(void) +{ + return platform_driver_register(&gcc_qcs404_driver); +} +subsys_initcall(gcc_qcs404_init); + +static void __exit gcc_qcs404_exit(void) +{ + platform_driver_unregister(&gcc_qcs404_driver); +} +module_exit(gcc_qcs404_exit); + +MODULE_DESCRIPTION("Qualcomm GCC QCS404 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/clock/qcom,gcc-qcs404.h b/include/dt-bindings/clock/qcom,gcc-qcs404.h new file mode 100644 index 000000000000..6ceb55ed72c6 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-qcs404.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_QCS404_H +#define _DT_BINDINGS_CLK_QCOM_GCC_QCS404_H + +#define GCC_APSS_AHB_CLK_SRC 0 +#define GCC_BLSP1_QUP0_I2C_APPS_CLK_SRC 1 +#define GCC_BLSP1_QUP0_SPI_APPS_CLK_SRC 2 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC 3 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC 4 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC 5 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC 6 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC 7 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC 8 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC 9 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC 10 +#define GCC_BLSP1_UART0_APPS_CLK_SRC 11 +#define GCC_BLSP1_UART1_APPS_CLK_SRC 12 +#define GCC_BLSP1_UART2_APPS_CLK_SRC 13 +#define GCC_BLSP1_UART3_APPS_CLK_SRC 14 +#define GCC_BLSP2_QUP0_I2C_APPS_CLK_SRC 15 +#define GCC_BLSP2_QUP0_SPI_APPS_CLK_SRC 16 +#define GCC_BLSP2_UART0_APPS_CLK_SRC 17 +#define GCC_BYTE0_CLK_SRC 18 +#define GCC_EMAC_CLK_SRC 19 +#define GCC_EMAC_PTP_CLK_SRC 20 +#define GCC_ESC0_CLK_SRC 21 +#define GCC_APSS_AHB_CLK 22 +#define GCC_APSS_AXI_CLK 23 +#define GCC_BIMC_APSS_AXI_CLK 24 +#define GCC_BIMC_GFX_CLK 25 +#define GCC_BIMC_MDSS_CLK 26 +#define GCC_BLSP1_AHB_CLK 27 +#define GCC_BLSP1_QUP0_I2C_APPS_CLK 28 +#define GCC_BLSP1_QUP0_SPI_APPS_CLK 29 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 30 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 31 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 32 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 33 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 34 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 35 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 36 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 37 +#define GCC_BLSP1_UART0_APPS_CLK 38 +#define GCC_BLSP1_UART1_APPS_CLK 39 +#define GCC_BLSP1_UART2_APPS_CLK 40 +#define GCC_BLSP1_UART3_APPS_CLK 41 +#define GCC_BLSP2_AHB_CLK 42 +#define GCC_BLSP2_QUP0_I2C_APPS_CLK 43 +#define GCC_BLSP2_QUP0_SPI_APPS_CLK 44 +#define GCC_BLSP2_UART0_APPS_CLK 45 +#define GCC_BOOT_ROM_AHB_CLK 46 +#define GCC_DCC_CLK 47 +#define GCC_GENI_IR_H_CLK 48 +#define GCC_ETH_AXI_CLK 49 +#define GCC_ETH_PTP_CLK 50 +#define GCC_ETH_RGMII_CLK 51 +#define GCC_ETH_SLAVE_AHB_CLK 52 +#define GCC_GENI_IR_S_CLK 53 +#define GCC_GP1_CLK 54 +#define GCC_GP2_CLK 55 +#define GCC_GP3_CLK 56 +#define GCC_MDSS_AHB_CLK 57 +#define GCC_MDSS_AXI_CLK 58 +#define GCC_MDSS_BYTE0_CLK 59 +#define GCC_MDSS_ESC0_CLK 60 +#define GCC_MDSS_HDMI_APP_CLK 61 +#define GCC_MDSS_HDMI_PCLK_CLK 62 +#define GCC_MDSS_MDP_CLK 63 +#define GCC_MDSS_PCLK0_CLK 64 +#define GCC_MDSS_VSYNC_CLK 65 +#define GCC_OXILI_AHB_CLK 66 +#define GCC_OXILI_GFX3D_CLK 67 +#define GCC_PCIE_0_AUX_CLK 68 +#define GCC_PCIE_0_CFG_AHB_CLK 69 +#define GCC_PCIE_0_MSTR_AXI_CLK 70 +#define GCC_PCIE_0_PIPE_CLK 71 +#define GCC_PCIE_0_SLV_AXI_CLK 72 +#define GCC_PCNOC_USB2_CLK 73 +#define GCC_PCNOC_USB3_CLK 74 +#define GCC_PDM2_CLK 75 +#define GCC_PDM_AHB_CLK 76 +#define GCC_VSYNC_CLK_SRC 77 +#define GCC_PRNG_AHB_CLK 78 +#define GCC_PWM0_XO512_CLK 79 +#define GCC_PWM1_XO512_CLK 80 +#define GCC_PWM2_XO512_CLK 81 +#define GCC_SDCC1_AHB_CLK 82 +#define GCC_SDCC1_APPS_CLK 83 +#define GCC_SDCC1_ICE_CORE_CLK 84 +#define GCC_SDCC2_AHB_CLK 85 +#define GCC_SDCC2_APPS_CLK 86 +#define GCC_SYS_NOC_USB3_CLK 87 +#define GCC_USB20_MOCK_UTMI_CLK 88 +#define GCC_USB2A_PHY_SLEEP_CLK 89 +#define GCC_USB30_MASTER_CLK 90 +#define GCC_USB30_MOCK_UTMI_CLK 91 +#define GCC_USB30_SLEEP_CLK 92 +#define GCC_USB3_PHY_AUX_CLK 93 +#define GCC_USB3_PHY_PIPE_CLK 94 +#define GCC_USB_HS_PHY_CFG_AHB_CLK 95 +#define GCC_USB_HS_SYSTEM_CLK 96 +#define GCC_GFX3D_CLK_SRC 97 +#define GCC_GP1_CLK_SRC 98 +#define GCC_GP2_CLK_SRC 99 +#define GCC_GP3_CLK_SRC 100 +#define GCC_GPLL0_OUT_MAIN 101 +#define GCC_GPLL1_OUT_MAIN 102 +#define GCC_GPLL3_OUT_MAIN 103 +#define GCC_GPLL4_OUT_MAIN 104 +#define GCC_HDMI_APP_CLK_SRC 105 +#define GCC_HDMI_PCLK_CLK_SRC 106 +#define GCC_MDP_CLK_SRC 107 +#define GCC_PCIE_0_AUX_CLK_SRC 108 +#define GCC_PCIE_0_PIPE_CLK_SRC 109 +#define GCC_PCLK0_CLK_SRC 110 +#define GCC_PDM2_CLK_SRC 111 +#define GCC_SDCC1_APPS_CLK_SRC 112 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 113 +#define GCC_SDCC2_APPS_CLK_SRC 114 +#define GCC_USB20_MOCK_UTMI_CLK_SRC 115 +#define GCC_USB30_MASTER_CLK_SRC 116 +#define GCC_USB30_MOCK_UTMI_CLK_SRC 117 +#define GCC_USB3_PHY_AUX_CLK_SRC 118 +#define GCC_USB_HS_SYSTEM_CLK_SRC 119 +#define GCC_GPLL0_AO_CLK_SRC 120 +#define GCC_USB_HS_INACTIVITY_TIMERS_CLK 122 +#define GCC_GPLL0_AO_OUT_MAIN 123 +#define GCC_GPLL0_SLEEP_CLK_SRC 124 +#define GCC_GPLL6 125 +#define GCC_GPLL6_OUT_AUX 126 +#define GCC_MDSS_MDP_VOTE_CLK 127 +#define GCC_MDSS_ROTATOR_VOTE_CLK 128 +#define GCC_BIMC_GPU_CLK 129 +#define GCC_GTCU_AHB_CLK 130 +#define GCC_GFX_TCU_CLK 131 +#define GCC_GFX_TBU_CLK 132 +#define GCC_SMMU_CFG_CLK 133 +#define GCC_APSS_TCU_CLK 134 +#define GCC_CRYPTO_AHB_CLK 135 +#define GCC_CRYPTO_AXI_CLK 136 +#define GCC_CRYPTO_CLK 137 +#define GCC_MDP_TBU_CLK 138 +#define GCC_QDSS_DAP_CLK 139 +#define GCC_DCC_XO_CLK 140 + +#define GCC_GENI_IR_BCR 0 +#define GCC_USB_HS_BCR 1 +#define GCC_USB2_HS_PHY_ONLY_BCR 2 +#define GCC_QUSB2_PHY_BCR 3 +#define GCC_USB_HS_PHY_CFG_AHB_BCR 4 +#define GCC_USB2A_PHY_BCR 5 +#define GCC_USB3_PHY_BCR 6 +#define GCC_USB_30_BCR 7 +#define GCC_USB3PHY_PHY_BCR 8 +#define GCC_PCIE_0_BCR 9 +#define GCC_PCIE_0_PHY_BCR 10 +#define GCC_PCIE_0_LINK_DOWN_BCR 11 +#define GCC_PCIEPHY_0_PHY_BCR 12 +#define GCC_EMAC_BCR 13 + +#endif -- cgit v1.2.3 From 067b6dedeb34ffda811ebbadf8bbad9311f28dc4 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Thu, 23 Aug 2018 15:17:42 +0200 Subject: dt-bindings: clock: ingenic: Explicitly list compatible strings This is better than letting the other developers wondering what are the supported strings. Signed-off-by: Paul Cercueil Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/ingenic,cgu.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,cgu.txt index f8d4134ae409..ba5a442026b7 100644 --- a/Documentation/devicetree/bindings/clock/ingenic,cgu.txt +++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.txt @@ -6,8 +6,11 @@ to provide many different clock signals derived from only 2 external source clocks. Required properties: -- compatible : Should be "ingenic,-cgu". - For example "ingenic,jz4740-cgu" or "ingenic,jz4780-cgu". +- compatible : Should be one of: + * ingenic,jz4740-cgu + * ingenic,jz4725b-cgu + * ingenic,jz4770-cgu + * ingenic,jz4780-cgu - reg : The address & length of the CGU registers. - clocks : List of phandle & clock specifiers for clocks external to the CGU. Two such external clocks should be specified - first the external crystal -- cgit v1.2.3 From d425ad81eacda2df98f063c4ca93b0f5a4690206 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 16 Oct 2018 16:21:46 +0200 Subject: dt-bindings: clk: at91: Document new PMC binding Document the new PMC binding with only one PMC node for all the PMC clocks instead of one node per clock as this proved to be problematic. Reviewed-by: Rob Herring Signed-off-by: Alexandre Belloni Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/at91-clock.txt | 516 +-------------------- 1 file changed, 21 insertions(+), 495 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 8f8f95056f3d..e9f70fcdfe80 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt @@ -4,6 +4,8 @@ This binding uses the common clock binding[1]. [1] Documentation/devicetree/bindings/clock/clock-bindings.txt +Slow Clock controller: + Required properties: - compatible : shall be one of the following: "atmel,at91sam9x5-sckc" or @@ -16,84 +18,6 @@ Required properties: "atmel,at91sam9x5-clk-slow-rc-osc": at91 internal slow RC oscillator - - "atmel,-pmc": - at91 PMC (Power Management Controller) - All at91 specific clocks (clocks defined below) must be child - node of the PMC node. - can be: at91rm9200, at91sam9260, at91sam9261, - at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9x5, - sama5d2, sama5d3 or sama5d4. - - "atmel,at91sam9x5-clk-slow" (under sckc node) - or - "atmel,at91sam9260-clk-slow" (under pmc node): - at91 slow clk - - "atmel,at91rm9200-clk-main-osc" - "atmel,at91sam9x5-clk-main-rc-osc" - at91 main clk sources - - "atmel,at91sam9x5-clk-main" - "atmel,at91rm9200-clk-main": - at91 main clock - - "atmel,at91rm9200-clk-master" or - "atmel,at91sam9x5-clk-master": - at91 master clock - - "atmel,at91sam9x5-clk-peripheral" or - "atmel,at91rm9200-clk-peripheral": - at91 peripheral clocks - - "atmel,at91rm9200-clk-pll" or - "atmel,at91sam9g45-clk-pll" or - "atmel,at91sam9g20-clk-pllb" or - "atmel,sama5d3-clk-pll": - at91 pll clocks - - "atmel,at91sam9x5-clk-plldiv": - at91 plla divisor - - "atmel,at91rm9200-clk-programmable" or - "atmel,at91sam9g45-clk-programmable" or - "atmel,at91sam9x5-clk-programmable": - at91 programmable clocks - - "atmel,at91sam9x5-clk-smd": - at91 SMD (Soft Modem) clock - - "atmel,at91rm9200-clk-system": - at91 system clocks - - "atmel,at91rm9200-clk-usb" or - "atmel,at91sam9x5-clk-usb" or - "atmel,at91sam9n12-clk-usb": - at91 usb clock - - "atmel,at91sam9x5-clk-utmi": - at91 utmi clock - - "atmel,sama5d4-clk-h32mx": - at91 h32mx clock - - "atmel,sama5d2-clk-generated": - at91 generated clock - - "atmel,sama5d2-clk-audio-pll-frac": - at91 audio fractional pll - - "atmel,sama5d2-clk-audio-pll-pad": - at91 audio pll CLK_AUDIO output pin - - "atmel,sama5d2-clk-audio-pll-pmc" - at91 audio pll output on AUDIOPLLCLK that feeds the PMC - and can be used by peripheral clock or generic clock - - "atmel,sama5d2-clk-i2s-mux" (under pmc node): - at91 I2S clock source selection - -Required properties for SCKC node: - reg : defines the IO memory reserved for the SCKC. - #size-cells : shall be 0 (reg is used to encode clk id). - #address-cells : shall be 1 (reg is used to encode clk id). @@ -109,428 +33,30 @@ For example: /* put at91 slow clocks here */ }; +Power Management Controller (PMC): -Required properties for internal slow RC oscillator: -- #clock-cells : from common clock binding; shall be set to 0. -- clock-frequency : define the internal RC oscillator frequency. - -Optional properties: -- clock-accuracy : define the internal RC oscillator accuracy. - -For example: - slow_rc_osc: slow_rc_osc { - compatible = "atmel,at91sam9x5-clk-slow-rc-osc"; - clock-frequency = <32768>; - clock-accuracy = <50000000>; - }; - -Required properties for slow oscillator: -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall encode the main osc source clk sources (see atmel datasheet). +Required properties: +- compatible : shall be "atmel,-pmc", "syscon": + can be: at91rm9200, at91sam9260, at91sam9261, + at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15, + at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5, + sama5d2, sama5d3 or sama5d4. +- #clock-cells : from common clock binding; shall be set to 2. The first entry + is the type of the clock (core, system, peripheral or generated) and the + second entry its index as provided by the datasheet +- clocks : Must contain an entry for each entry in clock-names. +- clock-names: Must include the following entries: "slow_clk", "main_xtal" Optional properties: - atmel,osc-bypass : boolean property. Set this when a clock signal is directly provided on XIN. For example: - slow_osc: slow_osc { - compatible = "atmel,at91rm9200-clk-slow-osc"; - #clock-cells = <0>; - clocks = <&slow_xtal>; - }; - -Required properties for slow clock: -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall encode the slow clk sources (see atmel datasheet). - -For example: - clk32k: slck { - compatible = "atmel,at91sam9x5-clk-slow"; - #clock-cells = <0>; - clocks = <&slow_rc_osc &slow_osc>; - }; - -Required properties for PMC node: -- reg : defines the IO memory reserved for the PMC. -- #size-cells : shall be 0 (reg is used to encode clk id). -- #address-cells : shall be 1 (reg is used to encode clk id). -- interrupts : shall be set to PMC interrupt line. -- interrupt-controller : tell that the PMC is an interrupt controller. -- #interrupt-cells : must be set to 1. The first cell encodes the interrupt id, - and reflect the bit position in the PMC_ER/DR/SR registers. - You can use the dt macros defined in dt-bindings/clock/at91.h. - 0 (AT91_PMC_MOSCS) -> main oscillator ready - 1 (AT91_PMC_LOCKA) -> PLL A ready - 2 (AT91_PMC_LOCKB) -> PLL B ready - 3 (AT91_PMC_MCKRDY) -> master clock ready - 6 (AT91_PMC_LOCKU) -> UTMI PLL clock ready - 8 .. 15 (AT91_PMC_PCKRDY(id)) -> programmable clock ready - 16 (AT91_PMC_MOSCSELS) -> main oscillator selected - 17 (AT91_PMC_MOSCRCS) -> RC main oscillator stabilized - 18 (AT91_PMC_CFDEV) -> clock failure detected - -For example: - pmc: pmc@fffffc00 { - compatible = "atmel,sama5d3-pmc"; - interrupts = <1 4 7>; - interrupt-controller; - #interrupt-cells = <2>; - #size-cells = <0>; - #address-cells = <1>; - - /* put at91 clocks here */ - }; - -Required properties for main clock internal RC oscillator: -- interrupts : shall be set to "<0>". -- clock-frequency : define the internal RC oscillator frequency. - -Optional properties: -- clock-accuracy : define the internal RC oscillator accuracy. - -For example: - main_rc_osc: main_rc_osc { - compatible = "atmel,at91sam9x5-clk-main-rc-osc"; - interrupt-parent = <&pmc>; - interrupts = <0>; - clock-frequency = <12000000>; - clock-accuracy = <50000000>; - }; - -Required properties for main clock oscillator: -- interrupts : shall be set to "<0>". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall encode the main osc source clk sources (see atmel datasheet). - -Optional properties: -- atmel,osc-bypass : boolean property. Specified if a clock signal is provided - on XIN. - - clock signal is directly provided on XIN pin. - -For example: - main_osc: main_osc { - compatible = "atmel,at91rm9200-clk-main-osc"; - interrupt-parent = <&pmc>; - interrupts = <0>; - #clock-cells = <0>; - clocks = <&main_xtal>; - }; - -Required properties for main clock: -- interrupts : shall be set to "<0>". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall encode the main clk sources (see atmel datasheet). - -For example: - main: mainck { - compatible = "atmel,at91sam9x5-clk-main"; - interrupt-parent = <&pmc>; - interrupts = <0>; - #clock-cells = <0>; - clocks = <&main_rc_osc &main_osc>; - }; - -Required properties for master clock: -- interrupts : shall be set to "<3>". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the master clock sources (see atmel datasheet) phandles. - e.g. "<&ck32k>, <&main>, <&plla>, <&pllb>". -- atmel,clk-output-range : minimum and maximum clock frequency (two u32 - fields). - e.g. output = <0 133000000>; <=> 0 to 133MHz. -- atmel,clk-divisors : master clock divisors table (four u32 fields). - 0 <=> reserved value. - e.g. divisors = <1 2 4 6>; -- atmel,master-clk-have-div3-pres : some SoC use the reserved value 7 in the - PRES field as CLOCK_DIV3 (e.g sam9x5). - -For example: - mck: mck { - compatible = "atmel,at91rm9200-clk-master"; - interrupt-parent = <&pmc>; - interrupts = <3>; - #clock-cells = <0>; - atmel,clk-output-range = <0 133000000>; - atmel,clk-divisors = <1 2 4 0>; - }; - -Required properties for peripheral clocks: -- #size-cells : shall be 0 (reg is used to encode clk id). -- #address-cells : shall be 1 (reg is used to encode clk id). -- clocks : shall be the master clock phandle. - e.g. clocks = <&mck>; -- name: device tree node describing a specific peripheral clock. - * #clock-cells : from common clock binding; shall be set to 0. - * reg: peripheral id. See Atmel's datasheets to get a full - list of peripheral ids. - * atmel,clk-output-range : minimum and maximum clock frequency - (two u32 fields). Only valid on at91sam9x5-clk-peripheral - compatible IPs. - -For example: - periph: periphck { - compatible = "atmel,at91sam9x5-clk-peripheral"; - #size-cells = <0>; - #address-cells = <1>; - clocks = <&mck>; - - ssc0_clk { - #clock-cells = <0>; - reg = <2>; - atmel,clk-output-range = <0 133000000>; - }; - - usart0_clk { - #clock-cells = <0>; - reg = <3>; - atmel,clk-output-range = <0 66000000>; - }; - }; - - -Required properties for pll clocks: -- interrupts : shall be set to "<1>". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the main clock phandle. -- reg : pll id. - 0 -> PLL A - 1 -> PLL B -- atmel,clk-input-range : minimum and maximum source clock frequency (two u32 - fields). - e.g. input = <1 32000000>; <=> 1 to 32MHz. -- #atmel,pll-clk-output-range-cells : number of cells reserved for pll output - range description. Sould be set to 2, 3 - or 4. - * 1st and 2nd cells represent the frequency range (min-max). - * 3rd cell is optional and represents the OUT field value for the given - range. - * 4th cell is optional and represents the ICPLL field (PLLICPR - register) -- atmel,pll-clk-output-ranges : pll output frequency ranges + optional parameter - depending on #atmel,pll-output-range-cells - property value. - -For example: - plla: pllack { - compatible = "atmel,at91sam9g45-clk-pll"; - interrupt-parent = <&pmc>; - interrupts = <1>; - #clock-cells = <0>; - clocks = <&main>; - reg = <0>; - atmel,clk-input-range = <2000000 32000000>; - #atmel,pll-clk-output-range-cells = <4>; - atmel,pll-clk-output-ranges = <74500000 800000000 0 0 - 69500000 750000000 1 0 - 64500000 700000000 2 0 - 59500000 650000000 3 0 - 54500000 600000000 0 1 - 49500000 550000000 1 1 - 44500000 500000000 2 1 - 40000000 450000000 3 1>; - }; - -Required properties for plldiv clocks (plldiv = pll / 2): -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the plla clock phandle. - -The pll divisor is equal to 2 and cannot be changed. - -For example: - plladiv: plladivck { - compatible = "atmel,at91sam9x5-clk-plldiv"; - #clock-cells = <0>; - clocks = <&plla>; - }; - -Required properties for programmable clocks: -- #size-cells : shall be 0 (reg is used to encode clk id). -- #address-cells : shall be 1 (reg is used to encode clk id). -- clocks : shall be the programmable clock source phandles. - e.g. clocks = <&clk32k>, <&main>, <&plla>, <&pllb>; -- name: device tree node describing a specific prog clock. - * #clock-cells : from common clock binding; shall be set to 0. - * reg : programmable clock id (register offset from PCKx - register). - * interrupts : shall be set to "<(8 + id)>". - -For example: - prog: progck { - compatible = "atmel,at91sam9g45-clk-programmable"; - #size-cells = <0>; - #address-cells = <1>; - interrupt-parent = <&pmc>; - clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>; - - prog0 { - #clock-cells = <0>; - reg = <0>; - interrupts = <8>; - }; - - prog1 { - #clock-cells = <0>; - reg = <1>; - interrupts = <9>; - }; - }; - - -Required properties for smd clock: -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the smd clock source phandles. - e.g. clocks = <&plladiv>, <&utmi>; - -For example: - smd: smdck { - compatible = "atmel,at91sam9x5-clk-smd"; - #clock-cells = <0>; - clocks = <&plladiv>, <&utmi>; - }; - -Required properties for system clocks: -- #size-cells : shall be 0 (reg is used to encode clk id). -- #address-cells : shall be 1 (reg is used to encode clk id). -- name: device tree node describing a specific system clock. - * #clock-cells : from common clock binding; shall be set to 0. - * reg: system clock id (bit position in SCER/SCDR/SCSR registers). - See Atmel's datasheet to get a full list of system clock ids. - -For example: - system: systemck { - compatible = "atmel,at91rm9200-clk-system"; - #address-cells = <1>; - #size-cells = <0>; - - ddrck { - #clock-cells = <0>; - reg = <2>; - clocks = <&mck>; - }; - - uhpck { - #clock-cells = <0>; - reg = <6>; - clocks = <&usb>; - }; - - udpck { - #clock-cells = <0>; - reg = <7>; - clocks = <&usb>; - }; - }; - - -Required properties for usb clock: -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the smd clock source phandles. - e.g. clocks = <&pllb>; -- atmel,clk-divisors (only available for "atmel,at91rm9200-clk-usb"): - usb clock divisor table. - e.g. divisors = <1 2 4 0>; - -For example: - usb: usbck { - compatible = "atmel,at91sam9x5-clk-usb"; - #clock-cells = <0>; - clocks = <&plladiv>, <&utmi>; - }; - - usb: usbck { - compatible = "atmel,at91rm9200-clk-usb"; - #clock-cells = <0>; - clocks = <&pllb>; - atmel,clk-divisors = <1 2 4 0>; - }; - - -Required properties for utmi clock: -- interrupts : shall be set to "". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the main clock source phandle. - -For example: - utmi: utmick { - compatible = "atmel,at91sam9x5-clk-utmi"; - interrupt-parent = <&pmc>; - interrupts = ; - #clock-cells = <0>; - clocks = <&main>; - }; - -Required properties for 32 bits bus Matrix clock (h32mx clock): -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : shall be the master clock source phandle. - -For example: - h32ck: h32mxck { - #clock-cells = <0>; - compatible = "atmel,sama5d4-clk-h32mx"; - clocks = <&mck>; - }; - -Required properties for generated clocks: -- #size-cells : shall be 0 (reg is used to encode clk id). -- #address-cells : shall be 1 (reg is used to encode clk id). -- clocks : shall be the generated clock source phandles. - e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; -- name: device tree node describing a specific generated clock. - * #clock-cells : from common clock binding; shall be set to 0. - * reg: peripheral id. See Atmel's datasheets to get a full - list of peripheral ids. - * atmel,clk-output-range : minimum and maximum clock frequency - (two u32 fields). - -For example: - gck { - compatible = "atmel,sama5d2-clk-generated"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; - - tcb0_gclk: tcb0_gclk { - #clock-cells = <0>; - reg = <35>; - atmel,clk-output-range = <0 83000000>; - }; - - pwm_gclk: pwm_gclk { - #clock-cells = <0>; - reg = <38>; - atmel,clk-output-range = <0 83000000>; - }; - }; - -Required properties for I2S mux clocks: -- #size-cells : shall be 0 (reg is used to encode I2S bus id). -- #address-cells : shall be 1 (reg is used to encode I2S bus id). -- name: device tree node describing a specific mux clock. - * #clock-cells : from common clock binding; shall be set to 0. - * clocks : shall be the mux clock parent phandles; shall be 2 phandles: - peripheral and generated clock; the first phandle shall belong to the - peripheral clock and the second one shall belong to the generated - clock; "clock-indices" property can be user to specify - the correct order. - * reg: I2S bus id of the corresponding mux clock. - e.g. reg = <0>; for i2s0, reg = <1>; for i2s1 - -For example: - i2s_clkmux { - compatible = "atmel,sama5d2-clk-i2s-mux"; - #address-cells = <1>; - #size-cells = <0>; - - i2s0muxck: i2s0_muxclk { - clocks = <&i2s0_clk>, <&i2s0_gclk>; - #clock-cells = <0>; - reg = <0>; - }; - - i2s1muxck: i2s1_muxclk { - clocks = <&i2s1_clk>, <&i2s1_gclk>; - #clock-cells = <0>; - reg = <1>; - }; + pmc: pmc@f0018000 { + compatible = "atmel,sama5d4-pmc", "syscon"; + reg = <0xf0018000 0x120>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + #clock-cells = <2>; + clocks = <&clk32k>, <&main_xtal>; + clock-names = "slow_clk", "main_xtal"; }; -- cgit v1.2.3 From 1f924faa8b1e4789ecc06ed0dd58ca3487c89012 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 14 Aug 2018 17:42:23 +0530 Subject: dt-bindings: clock: Document qcom,hfpll Adds bindings document for qcom,hfpll instantiated within the Krait processor subsystem as separate register region. Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd Signed-off-by: Sricharan R Tested-by: Craig Tatlor Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,hfpll.txt | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,hfpll.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,hfpll.txt b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt new file mode 100644 index 000000000000..ec02a024424c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt @@ -0,0 +1,60 @@ +High-Frequency PLL (HFPLL) + +PROPERTIES + +- compatible: + Usage: required + Value type: : + shall contain only one of the following. The generic + compatible "qcom,hfpll" should be also included. + + "qcom,hfpll-ipq8064", "qcom,hfpll" + "qcom,hfpll-apq8064", "qcom,hfpll" + "qcom,hfpll-msm8974", "qcom,hfpll" + "qcom,hfpll-msm8960", "qcom,hfpll" + +- reg: + Usage: required + Value type: + Definition: address and size of HPLL registers. An optional second + element specifies the address and size of the alias + register region. + +- clocks: + Usage: required + Value type: + Definition: reference to the xo clock. + +- clock-names: + Usage: required + Value type: + Definition: must be "xo". + +- clock-output-names: + Usage: required + Value type: + Definition: Name of the PLL. Typically hfpllX where X is a CPU number + starting at 0. Otherwise hfpll_Y where Y is more specific + such as "l2". + +Example: + +1) An HFPLL for the L2 cache. + + clock-controller@f9016000 { + compatible = "qcom,hfpll-ipq8064", "qcom,hfpll"; + reg = <0xf9016000 0x30>; + clocks = <&xo_board>; + clock-names = "xo"; + clock-output-names = "hfpll_l2"; + }; + +2) An HFPLL for CPU0. This HFPLL has the alias register region. + + clock-controller@f908a000 { + compatible = "qcom,hfpll-ipq8064", "qcom,hfpll"; + reg = <0xf908a000 0x30>, <0xf900a000 0x30>; + clocks = <&xo_board>; + clock-names = "xo"; + clock-output-names = "hfpll0"; + }; -- cgit v1.2.3 From 40e5ddf4f84869815129551f4a8cfc2c223ebeae Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 14 Aug 2018 17:42:28 +0530 Subject: dt-bindings: arm: Document qcom,kpss-gcc The ACC and GCC regions present in KPSSv1 contain registers to control clocks and power to each Krait CPU and L2. Documenting the bindings here. Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd Signed-off-by: Sricharan R Tested-by: Craig Tatlor Signed-off-by: Stephen Boyd --- .../devicetree/bindings/arm/msm/qcom,kpss-acc.txt | 19 ++++++++++ .../devicetree/bindings/arm/msm/qcom,kpss-gcc.txt | 44 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt index 1333db9acfee..7f696362a4a1 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt @@ -21,10 +21,29 @@ PROPERTIES the register region. An optional second element specifies the base address and size of the alias register region. +- clocks: + Usage: required + Value type: + Definition: reference to the pll parents. + +- clock-names: + Usage: required + Value type: + Definition: must be "pll8_vote", "pxo". + +- clock-output-names: + Usage: optional + Value type: + Definition: Name of the output clock. Typically acpuX_aux where X is a + CPU number starting at 0. + Example: clock-controller@2088000 { compatible = "qcom,kpss-acc-v2"; reg = <0x02088000 0x1000>, <0x02008000 0x1000>; + clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>; + clock-names = "pll8_vote", "pxo"; + clock-output-names = "acpu0_aux"; }; diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt new file mode 100644 index 000000000000..e628758950e1 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt @@ -0,0 +1,44 @@ +Krait Processor Sub-system (KPSS) Global Clock Controller (GCC) + +PROPERTIES + +- compatible: + Usage: required + Value type: + Definition: should be one of the following. The generic compatible + "qcom,kpss-gcc" should also be included. + "qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc" + "qcom,kpss-gcc-apq8064", "qcom,kpss-gcc" + "qcom,kpss-gcc-msm8974", "qcom,kpss-gcc" + "qcom,kpss-gcc-msm8960", "qcom,kpss-gcc" + +- reg: + Usage: required + Value type: + Definition: base address and size of the register region + +- clocks: + Usage: required + Value type: + Definition: reference to the pll parents. + +- clock-names: + Usage: required + Value type: + Definition: must be "pll8_vote", "pxo". + +- clock-output-names: + Usage: required + Value type: + Definition: Name of the output clock. Typically acpu_l2_aux indicating + an L2 cache auxiliary clock. + +Example: + + l2cc: clock-controller@2011000 { + compatible = "qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc"; + reg = <0x2011000 0x1000>; + clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>; + clock-names = "pll8_vote", "pxo"; + clock-output-names = "acpu_l2_aux"; + }; -- cgit v1.2.3 From bf4503ccf321811192cb07f9711556237c3cf668 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 14 Aug 2018 17:42:30 +0530 Subject: dt-bindings: clock: Document qcom,krait-cc The Krait clock controller controls the krait CPU and the L2 clocks consisting a primary mux and secondary mux. Add document for that. Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd Signed-off-by: Sricharan R Tested-by: Craig Tatlor Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,krait-cc.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,krait-cc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt new file mode 100644 index 000000000000..030ba60dab08 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt @@ -0,0 +1,34 @@ +Krait Clock Controller + +PROPERTIES + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,krait-cc-v1" + "qcom,krait-cc-v2" + +- #clock-cells: + Usage: required + Value type: + Definition: must be 1 + +- clocks: + Usage: required + Value type: + Definition: reference to the clock parents of hfpll, secondary muxes. + +- clock-names: + Usage: required + Value type: + Definition: must be "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb". + +Example: + + kraitcc: clock-controller { + compatible = "qcom,krait-cc-v1"; + clocks = <&hfpll0>, <&hfpll1>, <&acpu0_aux>, <&acpu1_aux>, ; + clock-names = "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb"; + #clock-cells = <1>; + }; -- cgit v1.2.3 From 992a8e60e3fea77c55589fc1c5af2304e78a5baa Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 23 Nov 2017 22:57:20 -0500 Subject: xarray: Add documentation This is documentation on how to use the XArray, not details about its internal implementation. Signed-off-by: Matthew Wilcox Acked-by: Josef Bacik --- Documentation/core-api/index.rst | 1 + Documentation/core-api/xarray.rst | 404 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 405 insertions(+) create mode 100644 Documentation/core-api/xarray.rst (limited to 'Documentation') diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index 26b735cefb93..df3105aa75f4 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -21,6 +21,7 @@ Core utilities local_ops workqueue genericirq + xarray flexible-arrays librs genalloc diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst new file mode 100644 index 000000000000..4b101b4f3aa1 --- /dev/null +++ b/Documentation/core-api/xarray.rst @@ -0,0 +1,404 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +====== +XArray +====== + +:Author: Matthew Wilcox + +Overview +======== + +The XArray is an abstract data type which behaves like a very large array +of pointers. It meets many of the same needs as a hash or a conventional +resizable array. Unlike a hash, it allows you to sensibly go to the +next or previous entry in a cache-efficient manner. In contrast to a +resizable array, there is no need to copy data or change MMU mappings in +order to grow the array. It is more memory-efficient, parallelisable +and cache friendly than a doubly-linked list. It takes advantage of +RCU to perform lookups without locking. + +The XArray implementation is efficient when the indices used are densely +clustered; hashing the object and using the hash as the index will not +perform well. The XArray is optimised for small indices, but still has +good performance with large indices. If your index can be larger than +``ULONG_MAX`` then the XArray is not the data type for you. The most +important user of the XArray is the page cache. + +Each non-``NULL`` entry in the array has three bits associated with +it called marks. Each mark may be set or cleared independently of +the others. You can iterate over entries which are marked. + +Normal pointers may be stored in the XArray directly. They must be 4-byte +aligned, which is true for any pointer returned from :c:func:`kmalloc` and +:c:func:`alloc_page`. It isn't true for arbitrary user-space pointers, +nor for function pointers. You can store pointers to statically allocated +objects, as long as those objects have an alignment of at least 4. + +You can also store integers between 0 and ``LONG_MAX`` in the XArray. +You must first convert it into an entry using :c:func:`xa_mk_value`. +When you retrieve an entry from the XArray, you can check whether it is +a value entry by calling :c:func:`xa_is_value`, and convert it back to +an integer by calling :c:func:`xa_to_value`. + +Some users want to store tagged pointers instead of using the marks +described above. They can call :c:func:`xa_tag_pointer` to create an +entry with a tag, :c:func:`xa_untag_pointer` to turn a tagged entry +back into an untagged pointer and :c:func:`xa_pointer_tag` to retrieve +the tag of an entry. Tagged pointers use the same bits that are used +to distinguish value entries from normal pointers, so each user must +decide whether they want to store value entries or tagged pointers in +any particular XArray. + +The XArray does not support storing :c:func:`IS_ERR` pointers as some +conflict with value entries or internal entries. + +An unusual feature of the XArray is the ability to create entries which +occupy a range of indices. Once stored to, looking up any index in +the range will return the same entry as looking up any other index in +the range. Setting a mark on one index will set it on all of them. +Storing to any index will store to all of them. Multi-index entries can +be explicitly split into smaller entries, or storing ``NULL`` into any +entry will cause the XArray to forget about the range. + +Normal API +========== + +Start by initialising an XArray, either with :c:func:`DEFINE_XARRAY` +for statically allocated XArrays or :c:func:`xa_init` for dynamically +allocated ones. A freshly-initialised XArray contains a ``NULL`` +pointer at every index. + +You can then set entries using :c:func:`xa_store` and get entries +using :c:func:`xa_load`. xa_store will overwrite any entry with the +new entry and return the previous entry stored at that index. You can +use :c:func:`xa_erase` instead of calling :c:func:`xa_store` with a +``NULL`` entry. There is no difference between an entry that has never +been stored to and one that has most recently had ``NULL`` stored to it. + +You can conditionally replace an entry at an index by using +:c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if +the entry at that index has the 'old' value. It also returns the entry +which was at that index; if it returns the same entry which was passed as +'old', then :c:func:`xa_cmpxchg` succeeded. + +If you want to only store a new entry to an index if the current entry +at that index is ``NULL``, you can use :c:func:`xa_insert` which +returns ``-EEXIST`` if the entry is not empty. + +You can enquire whether a mark is set on an entry by using +:c:func:`xa_get_mark`. If the entry is not ``NULL``, you can set a mark +on it by using :c:func:`xa_set_mark` and remove the mark from an entry by +calling :c:func:`xa_clear_mark`. You can ask whether any entry in the +XArray has a particular mark set by calling :c:func:`xa_marked`. + +You can copy entries out of the XArray into a plain array by calling +:c:func:`xa_extract`. Or you can iterate over the present entries in +the XArray by calling :c:func:`xa_for_each`. You may prefer to use +:c:func:`xa_find` or :c:func:`xa_find_after` to move to the next present +entry in the XArray. + +Finally, you can remove all entries from an XArray by calling +:c:func:`xa_destroy`. If the XArray entries are pointers, you may wish +to free the entries first. You can do this by iterating over all present +entries in the XArray using the :c:func:`xa_for_each` iterator. + +Memory allocation +----------------- + +The :c:func:`xa_store`, :c:func:`xa_cmpxchg`, :c:func:`xa_reserve` +and :c:func:`xa_insert` functions take a gfp_t parameter in case +the XArray needs to allocate memory to store this entry. +If the entry is being deleted, no memory allocation needs to be performed, +and the GFP flags specified will be ignored. + +It is possible for no memory to be allocatable, particularly if you pass +a restrictive set of GFP flags. In that case, the functions return a +special value which can be turned into an errno using :c:func:`xa_err`. +If you don't need to know exactly which error occurred, using +:c:func:`xa_is_err` is slightly more efficient. + +Locking +------- + +When using the Normal API, you do not have to worry about locking. +The XArray uses RCU and an internal spinlock to synchronise access: + +No lock needed: + * :c:func:`xa_empty` + * :c:func:`xa_marked` + +Takes RCU read lock: + * :c:func:`xa_load` + * :c:func:`xa_for_each` + * :c:func:`xa_find` + * :c:func:`xa_find_after` + * :c:func:`xa_extract` + * :c:func:`xa_get_mark` + +Takes xa_lock internally: + * :c:func:`xa_store` + * :c:func:`xa_insert` + * :c:func:`xa_erase` + * :c:func:`xa_erase_bh` + * :c:func:`xa_erase_irq` + * :c:func:`xa_cmpxchg` + * :c:func:`xa_destroy` + * :c:func:`xa_set_mark` + * :c:func:`xa_clear_mark` + +Assumes xa_lock held on entry: + * :c:func:`__xa_store` + * :c:func:`__xa_insert` + * :c:func:`__xa_erase` + * :c:func:`__xa_cmpxchg` + * :c:func:`__xa_set_mark` + * :c:func:`__xa_clear_mark` + +If you want to take advantage of the lock to protect the data structures +that you are storing in the XArray, you can call :c:func:`xa_lock` +before calling :c:func:`xa_load`, then take a reference count on the +object you have found before calling :c:func:`xa_unlock`. This will +prevent stores from removing the object from the array between looking +up the object and incrementing the refcount. You can also use RCU to +avoid dereferencing freed memory, but an explanation of that is beyond +the scope of this document. + +The XArray does not disable interrupts or softirqs while modifying +the array. It is safe to read the XArray from interrupt or softirq +context as the RCU lock provides enough protection. + +If, for example, you want to store entries in the XArray in process +context and then erase them in softirq context, you can do that this way:: + + void foo_init(struct foo *foo) + { + xa_init_flags(&foo->array, XA_FLAGS_LOCK_BH); + } + + int foo_store(struct foo *foo, unsigned long index, void *entry) + { + int err; + + xa_lock_bh(&foo->array); + err = xa_err(__xa_store(&foo->array, index, entry, GFP_KERNEL)); + if (!err) + foo->count++; + xa_unlock_bh(&foo->array); + return err; + } + + /* foo_erase() is only called from softirq context */ + void foo_erase(struct foo *foo, unsigned long index) + { + xa_lock(&foo->array); + __xa_erase(&foo->array, index); + foo->count--; + xa_unlock(&foo->array); + } + +If you are going to modify the XArray from interrupt or softirq context, +you need to initialise the array using :c:func:`xa_init_flags`, passing +``XA_FLAGS_LOCK_IRQ`` or ``XA_FLAGS_LOCK_BH``. + +The above example also shows a common pattern of wanting to extend the +coverage of the xa_lock on the store side to protect some statistics +associated with the array. + +Sharing the XArray with interrupt context is also possible, either +using :c:func:`xa_lock_irqsave` in both the interrupt handler and process +context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` +in the interrupt handler. Some of the more common patterns have helper +functions such as :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`. + +Sometimes you need to protect access to the XArray with a mutex because +that lock sits above another mutex in the locking hierarchy. That does +not entitle you to use functions like :c:func:`__xa_erase` without taking +the xa_lock; the xa_lock is used for lockdep validation and will be used +for other purposes in the future. + +The :c:func:`__xa_set_mark` and :c:func:`__xa_clear_mark` functions are also +available for situations where you look up an entry and want to atomically +set or clear a mark. It may be more efficient to use the advanced API +in this case, as it will save you from walking the tree twice. + +Advanced API +============ + +The advanced API offers more flexibility and better performance at the +cost of an interface which can be harder to use and has fewer safeguards. +No locking is done for you by the advanced API, and you are required +to use the xa_lock while modifying the array. You can choose whether +to use the xa_lock or the RCU lock while doing read-only operations on +the array. You can mix advanced and normal operations on the same array; +indeed the normal API is implemented in terms of the advanced API. The +advanced API is only available to modules with a GPL-compatible license. + +The advanced API is based around the xa_state. This is an opaque data +structure which you declare on the stack using the :c:func:`XA_STATE` +macro. This macro initialises the xa_state ready to start walking +around the XArray. It is used as a cursor to maintain the position +in the XArray and let you compose various operations together without +having to restart from the top every time. + +The xa_state is also used to store errors. You can call +:c:func:`xas_error` to retrieve the error. All operations check whether +the xa_state is in an error state before proceeding, so there's no need +for you to check for an error after each call; you can make multiple +calls in succession and only check at a convenient point. The only +errors currently generated by the XArray code itself are ``ENOMEM`` and +``EINVAL``, but it supports arbitrary errors in case you want to call +:c:func:`xas_set_err` yourself. + +If the xa_state is holding an ``ENOMEM`` error, calling :c:func:`xas_nomem` +will attempt to allocate more memory using the specified gfp flags and +cache it in the xa_state for the next attempt. The idea is that you take +the xa_lock, attempt the operation and drop the lock. The operation +attempts to allocate memory while holding the lock, but it is more +likely to fail. Once you have dropped the lock, :c:func:`xas_nomem` +can try harder to allocate more memory. It will return ``true`` if it +is worth retrying the operation (i.e. that there was a memory error *and* +more memory was allocated). If it has previously allocated memory, and +that memory wasn't used, and there is no error (or some error that isn't +``ENOMEM``), then it will free the memory previously allocated. + +Internal Entries +---------------- + +The XArray reserves some entries for its own purposes. These are never +exposed through the normal API, but when using the advanced API, it's +possible to see them. Usually the best way to handle them is to pass them +to :c:func:`xas_retry`, and retry the operation if it returns ``true``. + +.. flat-table:: + :widths: 1 1 6 + + * - Name + - Test + - Usage + + * - Node + - :c:func:`xa_is_node` + - An XArray node. May be visible when using a multi-index xa_state. + + * - Sibling + - :c:func:`xa_is_sibling` + - A non-canonical entry for a multi-index entry. The value indicates + which slot in this node has the canonical entry. + + * - Retry + - :c:func:`xa_is_retry` + - This entry is currently being modified by a thread which has the + xa_lock. The node containing this entry may be freed at the end + of this RCU period. You should restart the lookup from the head + of the array. + +Other internal entries may be added in the future. As far as possible, they +will be handled by :c:func:`xas_retry`. + +Additional functionality +------------------------ + +The :c:func:`xas_create_range` function allocates all the necessary memory +to store every entry in a range. It will set ENOMEM in the xa_state if +it cannot allocate memory. + +You can use :c:func:`xas_init_marks` to reset the marks on an entry +to their default state. This is usually all marks clear, unless the +XArray is marked with ``XA_FLAGS_TRACK_FREE``, in which case mark 0 is set +and all other marks are clear. Replacing one entry with another using +:c:func:`xas_store` will not reset the marks on that entry; if you want +the marks reset, you should do that explicitly. + +The :c:func:`xas_load` will walk the xa_state as close to the entry +as it can. If you know the xa_state has already been walked to the +entry and need to check that the entry hasn't changed, you can use +:c:func:`xas_reload` to save a function call. + +If you need to move to a different index in the XArray, call +:c:func:`xas_set`. This resets the cursor to the top of the tree, which +will generally make the next operation walk the cursor to the desired +spot in the tree. If you want to move to the next or previous index, +call :c:func:`xas_next` or :c:func:`xas_prev`. Setting the index does +not walk the cursor around the array so does not require a lock to be +held, while moving to the next or previous index does. + +You can search for the next present entry using :c:func:`xas_find`. This +is the equivalent of both :c:func:`xa_find` and :c:func:`xa_find_after`; +if the cursor has been walked to an entry, then it will find the next +entry after the one currently referenced. If not, it will return the +entry at the index of the xa_state. Using :c:func:`xas_next_entry` to +move to the next present entry instead of :c:func:`xas_find` will save +a function call in the majority of cases at the expense of emitting more +inline code. + +The :c:func:`xas_find_marked` function is similar. If the xa_state has +not been walked, it will return the entry at the index of the xa_state, +if it is marked. Otherwise, it will return the first marked entry after +the entry referenced by the xa_state. The :c:func:`xas_next_marked` +function is the equivalent of :c:func:`xas_next_entry`. + +When iterating over a range of the XArray using :c:func:`xas_for_each` +or :c:func:`xas_for_each_marked`, it may be necessary to temporarily stop +the iteration. The :c:func:`xas_pause` function exists for this purpose. +After you have done the necessary work and wish to resume, the xa_state +is in an appropriate state to continue the iteration after the entry +you last processed. If you have interrupts disabled while iterating, +then it is good manners to pause the iteration and reenable interrupts +every ``XA_CHECK_SCHED`` entries. + +The :c:func:`xas_get_mark`, :c:func:`xas_set_mark` and +:c:func:`xas_clear_mark` functions require the xa_state cursor to have +been moved to the appropriate location in the xarray; they will do +nothing if you have called :c:func:`xas_pause` or :c:func:`xas_set` +immediately before. + +You can call :c:func:`xas_set_update` to have a callback function +called each time the XArray updates a node. This is used by the page +cache workingset code to maintain its list of nodes which contain only +shadow entries. + +Multi-Index Entries +------------------- + +The XArray has the ability to tie multiple indices together so that +operations on one index affect all indices. For example, storing into +any index will change the value of the entry retrieved from any index. +Setting or clearing a mark on any index will set or clear the mark +on every index that is tied together. The current implementation +only allows tying ranges which are aligned powers of two together; +eg indices 64-127 may be tied together, but 2-6 may not be. This may +save substantial quantities of memory; for example tying 512 entries +together will save over 4kB. + +You can create a multi-index entry by using :c:func:`XA_STATE_ORDER` +or :c:func:`xas_set_order` followed by a call to :c:func:`xas_store`. +Calling :c:func:`xas_load` with a multi-index xa_state will walk the +xa_state to the right location in the tree, but the return value is not +meaningful, potentially being an internal entry or ``NULL`` even when there +is an entry stored within the range. Calling :c:func:`xas_find_conflict` +will return the first entry within the range or ``NULL`` if there are no +entries in the range. The :c:func:`xas_for_each_conflict` iterator will +iterate over every entry which overlaps the specified range. + +If :c:func:`xas_load` encounters a multi-index entry, the xa_index +in the xa_state will not be changed. When iterating over an XArray +or calling :c:func:`xas_find`, if the initial index is in the middle +of a multi-index entry, it will not be altered. Subsequent calls +or iterations will move the index to the first index in the range. +Each entry will only be returned once, no matter how many indices it +occupies. + +Using :c:func:`xas_next` or :c:func:`xas_prev` with a multi-index xa_state +is not supported. Using either of these functions on a multi-index entry +will reveal sibling entries; these should be skipped over by the caller. + +Storing ``NULL`` into any index of a multi-index entry will set the entry +at every index to ``NULL`` and dissolve the tie. Splitting a multi-index +entry into entries occupying smaller ranges is not yet supported. + +Functions and structures +======================== + +.. kernel-doc:: include/linux/xarray.h +.. kernel-doc:: lib/xarray.c -- cgit v1.2.3 From 9f14d4f1f1045f161fd4db8a8e194b7825c2874a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 1 Oct 2018 14:54:59 -0400 Subject: xarray: Add xa_reserve and xa_release This function reserves a slot in the XArray for users which need to acquire multiple locks before storing their entry in the tree and so cannot use a plain xa_store(). Signed-off-by: Matthew Wilcox --- Documentation/core-api/xarray.rst | 6 +++++ include/linux/xarray.h | 34 ++++++++++++++++++++++++++-- lib/test_xarray.c | 40 +++++++++++++++++++++++++++++++++ lib/xarray.c | 47 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst index 4b101b4f3aa1..2b397da84bcd 100644 --- a/Documentation/core-api/xarray.rst +++ b/Documentation/core-api/xarray.rst @@ -293,6 +293,12 @@ to :c:func:`xas_retry`, and retry the operation if it returns ``true``. of this RCU period. You should restart the lookup from the head of the array. + * - Zero + - :c:func:`xa_is_zero` + - Zero entries appear as ``NULL`` through the Normal API, but occupy + an entry in the XArray which can be used to reserve the index for + future use. + Other internal entries may be added in the future. As far as possible, they will be handled by :c:func:`xas_retry`. diff --git a/include/linux/xarray.h b/include/linux/xarray.h index deae17aa0ed7..bed63d3cfea8 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -32,7 +32,8 @@ * The following internal entries have a special meaning: * * 0-62: Sibling entries - * 256: Retry entry + * 256: Zero entry + * 257: Retry entry * * Errors are also represented as internal entries, but use the negative * space (-4094 to -2). They're never stored in the slots array; only @@ -277,6 +278,7 @@ void *xa_load(struct xarray *, unsigned long index); void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); void *xa_cmpxchg(struct xarray *, unsigned long index, void *old, void *entry, gfp_t); +int xa_reserve(struct xarray *, unsigned long index, gfp_t); bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); @@ -371,6 +373,20 @@ static inline int xa_insert(struct xarray *xa, unsigned long index, return -EEXIST; } +/** + * xa_release() - Release a reserved entry. + * @xa: XArray. + * @index: Index of entry. + * + * After calling xa_reserve(), you can call this function to release the + * reservation. If the entry at @index has been stored to, this function + * will do nothing. + */ +static inline void xa_release(struct xarray *xa, unsigned long index) +{ + xa_cmpxchg(xa, index, NULL, NULL, 0); +} + /** * xa_for_each() - Iterate over a portion of an XArray. * @xa: XArray. @@ -658,7 +674,19 @@ static inline bool xa_is_sibling(const void *entry) (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1)); } -#define XA_RETRY_ENTRY xa_mk_internal(256) +#define XA_ZERO_ENTRY xa_mk_internal(256) +#define XA_RETRY_ENTRY xa_mk_internal(257) + +/** + * xa_is_zero() - Is the entry a zero entry? + * @entry: Entry retrieved from the XArray + * + * Return: %true if the entry is a zero entry. + */ +static inline bool xa_is_zero(const void *entry) +{ + return unlikely(entry == XA_ZERO_ENTRY); +} /** * xa_is_retry() - Is the entry a retry entry? @@ -880,6 +908,8 @@ static inline void xas_reset(struct xa_state *xas) */ static inline bool xas_retry(struct xa_state *xas, const void *entry) { + if (xa_is_zero(entry)) + return true; if (!xa_is_retry(entry)) return false; xas_reset(xas); diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 703370015d10..6aafd411a5c3 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c @@ -259,6 +259,45 @@ static noinline void check_cmpxchg(struct xarray *xa) XA_BUG_ON(xa, !xa_empty(xa)); } +static noinline void check_reserve(struct xarray *xa) +{ + void *entry; + unsigned long index = 0; + + /* An array with a reserved entry is not empty */ + XA_BUG_ON(xa, !xa_empty(xa)); + xa_reserve(xa, 12345678, GFP_KERNEL); + XA_BUG_ON(xa, xa_empty(xa)); + XA_BUG_ON(xa, xa_load(xa, 12345678)); + xa_release(xa, 12345678); + XA_BUG_ON(xa, !xa_empty(xa)); + + /* Releasing a used entry does nothing */ + xa_reserve(xa, 12345678, GFP_KERNEL); + XA_BUG_ON(xa, xa_store_index(xa, 12345678, GFP_NOWAIT) != NULL); + xa_release(xa, 12345678); + xa_erase_index(xa, 12345678); + XA_BUG_ON(xa, !xa_empty(xa)); + + /* cmpxchg sees a reserved entry as NULL */ + xa_reserve(xa, 12345678, GFP_KERNEL); + XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, NULL, xa_mk_value(12345678), + GFP_NOWAIT) != NULL); + xa_release(xa, 12345678); + xa_erase_index(xa, 12345678); + XA_BUG_ON(xa, !xa_empty(xa)); + + /* Can iterate through a reserved entry */ + xa_store_index(xa, 5, GFP_KERNEL); + xa_reserve(xa, 6, GFP_KERNEL); + xa_store_index(xa, 7, GFP_KERNEL); + + xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { + XA_BUG_ON(xa, index != 5 && index != 7); + } + xa_destroy(xa); +} + static noinline void check_xas_erase(struct xarray *xa) { XA_STATE(xas, xa, 0); @@ -808,6 +847,7 @@ static int xarray_checks(void) check_xa_shrink(&array); check_xas_erase(&array); check_cmpxchg(&array); + check_reserve(&array); check_multi_store(&array); check_find(&array); check_destroy(&array); diff --git a/lib/xarray.c b/lib/xarray.c index ff37516fe832..546461914282 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -1266,6 +1266,8 @@ void *xa_load(struct xarray *xa, unsigned long index) rcu_read_lock(); do { entry = xas_load(&xas); + if (xa_is_zero(entry)) + entry = NULL; } while (xas_retry(&xas, entry)); rcu_read_unlock(); @@ -1275,6 +1277,8 @@ EXPORT_SYMBOL(xa_load); static void *xas_result(struct xa_state *xas, void *curr) { + if (xa_is_zero(curr)) + return NULL; XA_NODE_BUG_ON(xas->xa_node, xa_is_internal(curr)); if (xas_error(xas)) curr = xas->xa_node; @@ -1394,6 +1398,8 @@ void *xa_cmpxchg(struct xarray *xa, unsigned long index, do { xas_lock(&xas); curr = xas_load(&xas); + if (curr == XA_ZERO_ENTRY) + curr = NULL; if (curr == old) xas_store(&xas, entry); xas_unlock(&xas); @@ -1430,6 +1436,8 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, do { curr = xas_load(&xas); + if (curr == XA_ZERO_ENTRY) + curr = NULL; if (curr == old) xas_store(&xas, entry); } while (__xas_nomem(&xas, gfp)); @@ -1438,6 +1446,43 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, } EXPORT_SYMBOL(__xa_cmpxchg); +/** + * xa_reserve() - Reserve this index in the XArray. + * @xa: XArray. + * @index: Index into array. + * @gfp: Memory allocation flags. + * + * Ensures there is somewhere to store an entry at @index in the array. + * If there is already something stored at @index, this function does + * nothing. If there was nothing there, the entry is marked as reserved. + * Loads from @index will continue to see a %NULL pointer until a + * subsequent store to @index. + * + * If you do not use the entry that you have reserved, call xa_release() + * or xa_erase() to free any unnecessary memory. + * + * Context: Process context. Takes and releases the xa_lock, IRQ or BH safe + * if specified in XArray flags. May sleep if the @gfp flags permit. + * Return: 0 if the reservation succeeded or -ENOMEM if it failed. + */ +int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) +{ + XA_STATE(xas, xa, index); + unsigned int lock_type = xa_lock_type(xa); + void *curr; + + do { + xas_lock_type(&xas, lock_type); + curr = xas_load(&xas); + if (!curr) + xas_store(&xas, XA_ZERO_ENTRY); + xas_unlock_type(&xas, lock_type); + } while (xas_nomem(&xas, gfp)); + + return xas_error(&xas); +} +EXPORT_SYMBOL(xa_reserve); + /** * __xa_set_mark() - Set this mark on this entry while locked. * @xa: XArray. @@ -1797,6 +1842,8 @@ void xa_dump_entry(const void *entry, unsigned long index, unsigned long shift) pr_cont("retry (%ld)\n", xa_to_internal(entry)); else if (xa_is_sibling(entry)) pr_cont("sibling (slot %ld)\n", xa_to_sibling(entry)); + else if (xa_is_zero(entry)) + pr_cont("zero (%ld)\n", xa_to_internal(entry)); else pr_cont("UNKNOWN ENTRY (%px)\n", entry); } -- cgit v1.2.3 From 371c752dc66948714ee3b66c3306f3ff1ff71d2e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 4 Jul 2018 10:50:12 -0400 Subject: xarray: Track free entries in an XArray Add the optional ability to track which entries in an XArray are free and provide xa_alloc() to replace most of the functionality of the IDR. Signed-off-by: Matthew Wilcox --- Documentation/core-api/xarray.rst | 23 +++++++-- include/linux/xarray.h | 101 ++++++++++++++++++++++++++++++++++++++ lib/test_xarray.c | 61 +++++++++++++++++++++++ lib/xarray.c | 88 +++++++++++++++++++++++++++++++-- 4 files changed, 266 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst index 2b397da84bcd..463e4c798ec1 100644 --- a/Documentation/core-api/xarray.rst +++ b/Documentation/core-api/xarray.rst @@ -103,12 +103,25 @@ Finally, you can remove all entries from an XArray by calling to free the entries first. You can do this by iterating over all present entries in the XArray using the :c:func:`xa_for_each` iterator. +ID assignment +------------- + +You can call :c:func:`xa_alloc` to store the entry at any unused index +in the XArray. If you need to modify the array from interrupt context, +you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable +interrupts while allocating the ID. Unlike :c:func:`xa_store`, allocating +a ``NULL`` pointer does not delete an entry. Instead it reserves an +entry like :c:func:`xa_reserve` and you can release it using either +:c:func:`xa_erase` or :c:func:`xa_release`. To use ID assignment, the +XArray must be defined with :c:func:`DEFINE_XARRAY_ALLOC`, or initialised +by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`, + Memory allocation ----------------- -The :c:func:`xa_store`, :c:func:`xa_cmpxchg`, :c:func:`xa_reserve` -and :c:func:`xa_insert` functions take a gfp_t parameter in case -the XArray needs to allocate memory to store this entry. +The :c:func:`xa_store`, :c:func:`xa_cmpxchg`, :c:func:`xa_alloc`, +:c:func:`xa_reserve` and :c:func:`xa_insert` functions take a gfp_t +parameter in case the XArray needs to allocate memory to store this entry. If the entry is being deleted, no memory allocation needs to be performed, and the GFP flags specified will be ignored. @@ -143,6 +156,9 @@ Takes xa_lock internally: * :c:func:`xa_erase_bh` * :c:func:`xa_erase_irq` * :c:func:`xa_cmpxchg` + * :c:func:`xa_alloc` + * :c:func:`xa_alloc_bh` + * :c:func:`xa_alloc_irq` * :c:func:`xa_destroy` * :c:func:`xa_set_mark` * :c:func:`xa_clear_mark` @@ -152,6 +168,7 @@ Assumes xa_lock held on entry: * :c:func:`__xa_insert` * :c:func:`__xa_erase` * :c:func:`__xa_cmpxchg` + * :c:func:`__xa_alloc` * :c:func:`__xa_set_mark` * :c:func:`__xa_clear_mark` diff --git a/include/linux/xarray.h b/include/linux/xarray.h index bed63d3cfea8..e0b57af52e9b 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -205,6 +205,7 @@ typedef unsigned __bitwise xa_mark_t; #define XA_MARK_2 ((__force xa_mark_t)2U) #define XA_PRESENT ((__force xa_mark_t)8U) #define XA_MARK_MAX XA_MARK_2 +#define XA_FREE_MARK XA_MARK_0 enum xa_lock_type { XA_LOCK_IRQ = 1, @@ -217,9 +218,12 @@ enum xa_lock_type { */ #define XA_FLAGS_LOCK_IRQ ((__force gfp_t)XA_LOCK_IRQ) #define XA_FLAGS_LOCK_BH ((__force gfp_t)XA_LOCK_BH) +#define XA_FLAGS_TRACK_FREE ((__force gfp_t)4U) #define XA_FLAGS_MARK(mark) ((__force gfp_t)((1U << __GFP_BITS_SHIFT) << \ (__force unsigned)(mark))) +#define XA_FLAGS_ALLOC (XA_FLAGS_TRACK_FREE | XA_FLAGS_MARK(XA_FREE_MARK)) + /** * struct xarray - The anchor of the XArray. * @xa_lock: Lock that protects the contents of the XArray. @@ -273,6 +277,15 @@ struct xarray { */ #define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) +/** + * DEFINE_XARRAY_ALLOC() - Define an XArray which can allocate IDs. + * @name: A string that names your XArray. + * + * This is intended for file scope definitions of allocating XArrays. + * See also DEFINE_XARRAY(). + */ +#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC) + void xa_init_flags(struct xarray *, gfp_t flags); void *xa_load(struct xarray *, unsigned long index); void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); @@ -439,6 +452,7 @@ void *__xa_erase(struct xarray *, unsigned long index); void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, void *entry, gfp_t); +int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); @@ -518,6 +532,93 @@ static inline void *xa_erase_irq(struct xarray *xa, unsigned long index) return entry; } +/** + * xa_alloc() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @max: Maximum ID to allocate (inclusive). + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Allocates an unused ID in the range specified by @id and @max. + * Updates the @id pointer with the index, then stores the entry at that + * index. A concurrent lookup will not see an uninitialised @id. + * + * Context: Process context. Takes and releases the xa_lock. May sleep if + * the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if + * there is no more space in the XArray. + */ +static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, + gfp_t gfp) +{ + int err; + + xa_lock(xa); + err = __xa_alloc(xa, id, max, entry, gfp); + xa_unlock(xa); + + return err; +} + +/** + * xa_alloc_bh() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @max: Maximum ID to allocate (inclusive). + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Allocates an unused ID in the range specified by @id and @max. + * Updates the @id pointer with the index, then stores the entry at that + * index. A concurrent lookup will not see an uninitialised @id. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling softirqs. May sleep if the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if + * there is no more space in the XArray. + */ +static inline int xa_alloc_bh(struct xarray *xa, u32 *id, u32 max, void *entry, + gfp_t gfp) +{ + int err; + + xa_lock_bh(xa); + err = __xa_alloc(xa, id, max, entry, gfp); + xa_unlock_bh(xa); + + return err; +} + +/** + * xa_alloc_irq() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @max: Maximum ID to allocate (inclusive). + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Allocates an unused ID in the range specified by @id and @max. + * Updates the @id pointer with the index, then stores the entry at that + * index. A concurrent lookup will not see an uninitialised @id. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. May sleep if the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if + * there is no more space in the XArray. + */ +static inline int xa_alloc_irq(struct xarray *xa, u32 *id, u32 max, void *entry, + gfp_t gfp) +{ + int err; + + xa_lock_irq(xa); + err = __xa_alloc(xa, id, max, entry, gfp); + xa_unlock_irq(xa); + + return err; +} + /* Everything below here is the Advanced API. Proceed with caution. */ /* diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 6aafd411a5c3..a752e6a37e6f 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c @@ -33,6 +33,15 @@ static void *xa_store_index(struct xarray *xa, unsigned long index, gfp_t gfp) return xa_store(xa, index, xa_mk_value(index & LONG_MAX), gfp); } +static void xa_alloc_index(struct xarray *xa, unsigned long index, gfp_t gfp) +{ + u32 id = 0; + + XA_BUG_ON(xa, xa_alloc(xa, &id, UINT_MAX, xa_mk_value(index & LONG_MAX), + gfp) != 0); + XA_BUG_ON(xa, id != index); +} + static void xa_erase_index(struct xarray *xa, unsigned long index) { XA_BUG_ON(xa, xa_erase(xa, index) != xa_mk_value(index & LONG_MAX)); @@ -404,6 +413,57 @@ static noinline void check_multi_store(struct xarray *xa) #endif } +static DEFINE_XARRAY_ALLOC(xa0); + +static noinline void check_xa_alloc(void) +{ + int i; + u32 id; + + /* An empty array should assign 0 to the first alloc */ + xa_alloc_index(&xa0, 0, GFP_KERNEL); + + /* Erasing it should make the array empty again */ + xa_erase_index(&xa0, 0); + XA_BUG_ON(&xa0, !xa_empty(&xa0)); + + /* And it should assign 0 again */ + xa_alloc_index(&xa0, 0, GFP_KERNEL); + + /* The next assigned ID should be 1 */ + xa_alloc_index(&xa0, 1, GFP_KERNEL); + xa_erase_index(&xa0, 1); + + /* Storing a value should mark it used */ + xa_store_index(&xa0, 1, GFP_KERNEL); + xa_alloc_index(&xa0, 2, GFP_KERNEL); + + /* If we then erase 0, it should be free */ + xa_erase_index(&xa0, 0); + xa_alloc_index(&xa0, 0, GFP_KERNEL); + + xa_erase_index(&xa0, 1); + xa_erase_index(&xa0, 2); + + for (i = 1; i < 5000; i++) { + xa_alloc_index(&xa0, i, GFP_KERNEL); + } + + xa_destroy(&xa0); + + id = 0xfffffffeU; + XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, UINT_MAX, xa_mk_value(0), + GFP_KERNEL) != 0); + XA_BUG_ON(&xa0, id != 0xfffffffeU); + XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, UINT_MAX, xa_mk_value(0), + GFP_KERNEL) != 0); + XA_BUG_ON(&xa0, id != 0xffffffffU); + XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, UINT_MAX, xa_mk_value(0), + GFP_KERNEL) != -ENOSPC); + XA_BUG_ON(&xa0, id != 0xffffffffU); + xa_destroy(&xa0); +} + static noinline void __check_store_iter(struct xarray *xa, unsigned long start, unsigned int order, unsigned int present) { @@ -849,6 +909,7 @@ static int xarray_checks(void) check_cmpxchg(&array); check_reserve(&array); check_multi_store(&array); + check_xa_alloc(); check_find(&array); check_destroy(&array); check_move(&array); diff --git a/lib/xarray.c b/lib/xarray.c index 546461914282..9a0d49d4b5f0 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -52,6 +52,11 @@ static inline void xas_unlock_type(struct xa_state *xas, unsigned int lock_type) xas_unlock(xas); } +static inline bool xa_track_free(const struct xarray *xa) +{ + return xa->xa_flags & XA_FLAGS_TRACK_FREE; +} + static inline void xa_mark_set(struct xarray *xa, xa_mark_t mark) { if (!(xa->xa_flags & XA_FLAGS_MARK(mark))) @@ -94,6 +99,11 @@ static inline bool node_any_mark(struct xa_node *node, xa_mark_t mark) return !bitmap_empty(node_marks(node, mark), XA_CHUNK_SIZE); } +static inline void node_mark_all(struct xa_node *node, xa_mark_t mark) +{ + bitmap_fill(node_marks(node, mark), XA_CHUNK_SIZE); +} + #define mark_inc(mark) do { \ mark = (__force xa_mark_t)((__force unsigned)(mark) + 1); \ } while (0) @@ -416,6 +426,8 @@ static void xas_shrink(struct xa_state *xas) xas->xa_node = XAS_BOUNDS; RCU_INIT_POINTER(xa->xa_head, entry); + if (xa_track_free(xa) && !node_get_mark(node, 0, XA_FREE_MARK)) + xa_mark_clear(xa, XA_FREE_MARK); node->count = 0; node->nr_values = 0; @@ -549,8 +561,15 @@ static int xas_expand(struct xa_state *xas, void *head) /* Propagate the aggregated mark info to the new child */ for (;;) { - if (xa_marked(xa, mark)) + if (xa_track_free(xa) && mark == XA_FREE_MARK) { + node_mark_all(node, XA_FREE_MARK); + if (!xa_marked(xa, XA_FREE_MARK)) { + node_clear_mark(node, 0, XA_FREE_MARK); + xa_mark_set(xa, XA_FREE_MARK); + } + } else if (xa_marked(xa, mark)) { node_set_mark(node, 0, mark); + } if (mark == XA_MARK_MAX) break; mark_inc(mark); @@ -624,6 +643,8 @@ static void *xas_create(struct xa_state *xas) node = xas_alloc(xas, shift); if (!node) break; + if (xa_track_free(xa)) + node_mark_all(node, XA_FREE_MARK); rcu_assign_pointer(*slot, xa_mk_node(node)); } else if (xa_is_node(entry)) { node = xa_to_node(entry); @@ -882,7 +903,10 @@ void xas_init_marks(const struct xa_state *xas) xa_mark_t mark = 0; for (;;) { - xas_clear_mark(xas, mark); + if (xa_track_free(xas->xa) && mark == XA_FREE_MARK) + xas_set_mark(xas, mark); + else + xas_clear_mark(xas, mark); if (mark == XA_MARK_MAX) break; mark_inc(mark); @@ -1333,6 +1357,8 @@ void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) do { xas_lock(&xas); curr = xas_store(&xas, entry); + if (xa_track_free(xa) && entry) + xas_clear_mark(&xas, XA_FREE_MARK); xas_unlock(&xas); } while (xas_nomem(&xas, gfp)); @@ -1365,6 +1391,8 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) do { curr = xas_store(&xas, entry); + if (xa_track_free(xa) && entry) + xas_clear_mark(&xas, XA_FREE_MARK); } while (__xas_nomem(&xas, gfp)); return xas_result(&xas, curr); @@ -1400,8 +1428,11 @@ void *xa_cmpxchg(struct xarray *xa, unsigned long index, curr = xas_load(&xas); if (curr == XA_ZERO_ENTRY) curr = NULL; - if (curr == old) + if (curr == old) { xas_store(&xas, entry); + if (xa_track_free(xa) && entry) + xas_clear_mark(&xas, XA_FREE_MARK); + } xas_unlock(&xas); } while (xas_nomem(&xas, gfp)); @@ -1438,8 +1469,11 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, curr = xas_load(&xas); if (curr == XA_ZERO_ENTRY) curr = NULL; - if (curr == old) + if (curr == old) { xas_store(&xas, entry); + if (xa_track_free(xa) && entry) + xas_clear_mark(&xas, XA_FREE_MARK); + } } while (__xas_nomem(&xas, gfp)); return xas_result(&xas, curr); @@ -1483,6 +1517,52 @@ int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) } EXPORT_SYMBOL(xa_reserve); +/** + * __xa_alloc() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @max: Maximum ID to allocate (inclusive). + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Allocates an unused ID in the range specified by @id and @max. + * Updates the @id pointer with the index, then stores the entry at that + * index. A concurrent lookup will not see an uninitialised @id. + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if + * there is no more space in the XArray. + */ +int __xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, gfp_t gfp) +{ + XA_STATE(xas, xa, 0); + int err; + + if (WARN_ON_ONCE(xa_is_internal(entry))) + return -EINVAL; + if (WARN_ON_ONCE(!xa_track_free(xa))) + return -EINVAL; + + if (!entry) + entry = XA_ZERO_ENTRY; + + do { + xas.xa_index = *id; + xas_find_marked(&xas, max, XA_FREE_MARK); + if (xas.xa_node == XAS_RESTART) + xas_set_err(&xas, -ENOSPC); + xas_store(&xas, entry); + xas_clear_mark(&xas, XA_FREE_MARK); + } while (__xas_nomem(&xas, gfp)); + + err = xas_error(&xas); + if (!err) + *id = xas.xa_index; + return err; +} +EXPORT_SYMBOL(__xa_alloc); + /** * __xa_set_mark() - Set this mark on this entry while locked. * @xa: XArray. -- cgit v1.2.3 From 0e9446c35a80931044b6d8d2d74a9cabd248539f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2018 14:13:29 -0400 Subject: xarray: Add range store functionality This version of xa_store_range() really only supports load and store. Our only user only needs basic load and store functionality, so there's no need to do the extra work to support marking and overlapping stores correctly yet. Signed-off-by: Matthew Wilcox --- Documentation/core-api/xarray.rst | 8 ++++ include/linux/xarray.h | 2 + lib/test_xarray.c | 34 ++++++++++++++ lib/xarray.c | 97 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 139 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst index 463e4c798ec1..a4e705108f42 100644 --- a/Documentation/core-api/xarray.rst +++ b/Documentation/core-api/xarray.rst @@ -98,6 +98,13 @@ the XArray by calling :c:func:`xa_for_each`. You may prefer to use :c:func:`xa_find` or :c:func:`xa_find_after` to move to the next present entry in the XArray. +Calling :c:func:`xa_store_range` stores the same entry in a range +of indices. If you do this, some of the other operations will behave +in a slightly odd way. For example, marking the entry at one index +may result in the entry being marked at some, but not all of the other +indices. Storing into one index may result in the entry retrieved by +some, but not all of the other indices changing. + Finally, you can remove all entries from an XArray by calling :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish to free the entries first. You can do this by iterating over all present @@ -156,6 +163,7 @@ Takes xa_lock internally: * :c:func:`xa_erase_bh` * :c:func:`xa_erase_irq` * :c:func:`xa_cmpxchg` + * :c:func:`xa_store_range` * :c:func:`xa_alloc` * :c:func:`xa_alloc_bh` * :c:func:`xa_alloc_irq` diff --git a/include/linux/xarray.h b/include/linux/xarray.h index e0b57af52e9b..d9514928ddac 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -292,6 +292,8 @@ void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); void *xa_cmpxchg(struct xarray *, unsigned long index, void *old, void *entry, gfp_t); int xa_reserve(struct xarray *, unsigned long index, gfp_t); +void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, + void *entry, gfp_t); bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 0f06a93b4d0e..aa47754150ce 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c @@ -1039,6 +1039,39 @@ static noinline void check_create_range(struct xarray *xa) check_create_range_3(); } +static noinline void __check_store_range(struct xarray *xa, unsigned long first, + unsigned long last) +{ +#ifdef CONFIG_XARRAY_MULTI + xa_store_range(xa, first, last, xa_mk_value(first), GFP_KERNEL); + + XA_BUG_ON(xa, xa_load(xa, first) != xa_mk_value(first)); + XA_BUG_ON(xa, xa_load(xa, last) != xa_mk_value(first)); + XA_BUG_ON(xa, xa_load(xa, first - 1) != NULL); + XA_BUG_ON(xa, xa_load(xa, last + 1) != NULL); + + xa_store_range(xa, first, last, NULL, GFP_KERNEL); +#endif + + XA_BUG_ON(xa, !xa_empty(xa)); +} + +static noinline void check_store_range(struct xarray *xa) +{ + unsigned long i, j; + + for (i = 0; i < 128; i++) { + for (j = i; j < 128; j++) { + __check_store_range(xa, i, j); + __check_store_range(xa, 128 + i, 128 + j); + __check_store_range(xa, 4095 + i, 4095 + j); + __check_store_range(xa, 4096 + i, 4096 + j); + __check_store_range(xa, 123456 + i, 123456 + j); + __check_store_range(xa, UINT_MAX + i, UINT_MAX + j); + } + } +} + static LIST_HEAD(shadow_nodes); static void test_update_node(struct xa_node *node) @@ -1184,6 +1217,7 @@ static int xarray_checks(void) check_destroy(&array); check_move(&array); check_create_range(&array); + check_store_range(&array); check_store_iter(&array); check_workingset(&array, 0); diff --git a/lib/xarray.c b/lib/xarray.c index 9a0d49d4b5f0..8b176f009c08 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -376,6 +376,14 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift) return node; } +#ifdef CONFIG_XARRAY_MULTI +/* Returns the number of indices covered by a given xa_state */ +static unsigned long xas_size(const struct xa_state *xas) +{ + return (xas->xa_sibs + 1UL) << xas->xa_shift; +} +#endif + /* * Use this to calculate the maximum index that will need to be created * in order to add the entry described by @xas. Because we cannot store a @@ -388,8 +396,7 @@ static unsigned long xas_max(struct xa_state *xas) #ifdef CONFIG_XARRAY_MULTI if (xas->xa_shift || xas->xa_sibs) { - unsigned long mask; - mask = (((xas->xa_sibs + 1UL) << xas->xa_shift) - 1); + unsigned long mask = xas_size(xas) - 1; max |= mask; if (mask == max) max++; @@ -1517,6 +1524,92 @@ int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) } EXPORT_SYMBOL(xa_reserve); +#ifdef CONFIG_XARRAY_MULTI +static void xas_set_range(struct xa_state *xas, unsigned long first, + unsigned long last) +{ + unsigned int shift = 0; + unsigned long sibs = last - first; + unsigned int offset = XA_CHUNK_MASK; + + xas_set(xas, first); + + while ((first & XA_CHUNK_MASK) == 0) { + if (sibs < XA_CHUNK_MASK) + break; + if ((sibs == XA_CHUNK_MASK) && (offset < XA_CHUNK_MASK)) + break; + shift += XA_CHUNK_SHIFT; + if (offset == XA_CHUNK_MASK) + offset = sibs & XA_CHUNK_MASK; + sibs >>= XA_CHUNK_SHIFT; + first >>= XA_CHUNK_SHIFT; + } + + offset = first & XA_CHUNK_MASK; + if (offset + sibs > XA_CHUNK_MASK) + sibs = XA_CHUNK_MASK - offset; + if ((((first + sibs + 1) << shift) - 1) > last) + sibs -= 1; + + xas->xa_shift = shift; + xas->xa_sibs = sibs; +} + +/** + * xa_store_range() - Store this entry at a range of indices in the XArray. + * @xa: XArray. + * @first: First index to affect. + * @last: Last index to affect. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * After this function returns, loads from any index between @first and @last, + * inclusive will return @entry. + * Storing into an existing multislot entry updates the entry of every index. + * The marks associated with @index are unaffected unless @entry is %NULL. + * + * Context: Process context. Takes and releases the xa_lock. May sleep + * if the @gfp flags permit. + * Return: %NULL on success, xa_err(-EINVAL) if @entry cannot be stored in + * an XArray, or xa_err(-ENOMEM) if memory allocation failed. + */ +void *xa_store_range(struct xarray *xa, unsigned long first, + unsigned long last, void *entry, gfp_t gfp) +{ + XA_STATE(xas, xa, 0); + + if (WARN_ON_ONCE(xa_is_internal(entry))) + return XA_ERROR(-EINVAL); + if (last < first) + return XA_ERROR(-EINVAL); + + do { + xas_lock(&xas); + if (entry) { + unsigned int order = (last == ~0UL) ? 64 : + ilog2(last + 1); + xas_set_order(&xas, last, order); + xas_create(&xas); + if (xas_error(&xas)) + goto unlock; + } + do { + xas_set_range(&xas, first, last); + xas_store(&xas, entry); + if (xas_error(&xas)) + goto unlock; + first += xas_size(&xas); + } while (first <= last); +unlock: + xas_unlock(&xas); + } while (xas_nomem(&xas, gfp)); + + return xas_result(&xas, NULL); +} +EXPORT_SYMBOL(xa_store_range); +#endif /* CONFIG_XARRAY_MULTI */ + /** * __xa_alloc() - Find somewhere to store this entry in the XArray. * @xa: XArray. -- cgit v1.2.3 From ea4cdc548e5e74a529cdd1aea885d74b4aa8f1b3 Mon Sep 17 00:00:00 2001 From: Luis Henriques Date: Mon, 15 Oct 2018 16:46:00 +0100 Subject: ceph: new mount option to disable usage of copy-from op Add a new mount option 'nocopyfrom' that will prevent the usage of the RADOS 'copy-from' operation in cephfs. This could be useful, for example, for an administrator to temporarily mitigate any possible bugs in the 'copy-from' implementation. Currently, only copy_file_range uses this RADOS operation. Setting this mount option will result in this syscall reverting to the default VFS implementation, i.e. to perform the copies locally instead of doing remote object copies. Signed-off-by: Luis Henriques Reviewed-by: "Yan, Zheng" Signed-off-by: Ilya Dryomov --- Documentation/filesystems/ceph.txt | 5 +++++ fs/ceph/file.c | 3 +++ fs/ceph/super.c | 13 +++++++++++++ fs/ceph/super.h | 1 + 4 files changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt index 8bf62240e10d..1177052701e1 100644 --- a/Documentation/filesystems/ceph.txt +++ b/Documentation/filesystems/ceph.txt @@ -151,6 +151,11 @@ Mount Options Report overall filesystem usage in statfs instead of using the root directory quota. + nocopyfrom + Don't use the RADOS 'copy-from' operation to perform remote object + copies. Currently, it's only used in copy_file_range, which will revert + to the default VFS implementation if this option is used. + More Information ================ diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 5557ec6760ea..f788496fafcc 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1917,6 +1917,9 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, * efficient). */ + if (ceph_test_mount_opt(ceph_inode_to_client(src_inode), NOCOPYFROM)) + return -EOPNOTSUPP; + if ((src_ci->i_layout.stripe_unit != dst_ci->i_layout.stripe_unit) || (src_ci->i_layout.stripe_count != dst_ci->i_layout.stripe_count) || (src_ci->i_layout.object_size != dst_ci->i_layout.object_size)) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index eab1359d0553..b5ecd6f50360 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -165,6 +165,8 @@ enum { Opt_noacl, Opt_quotadf, Opt_noquotadf, + Opt_copyfrom, + Opt_nocopyfrom, }; static match_table_t fsopt_tokens = { @@ -203,6 +205,8 @@ static match_table_t fsopt_tokens = { {Opt_noacl, "noacl"}, {Opt_quotadf, "quotadf"}, {Opt_noquotadf, "noquotadf"}, + {Opt_copyfrom, "copyfrom"}, + {Opt_nocopyfrom, "nocopyfrom"}, {-1, NULL} }; @@ -355,6 +359,12 @@ static int parse_fsopt_token(char *c, void *private) case Opt_noquotadf: fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF; break; + case Opt_copyfrom: + fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM; + break; + case Opt_nocopyfrom: + fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM; + break; #ifdef CONFIG_CEPH_FS_POSIX_ACL case Opt_acl: fsopt->sb_flags |= SB_POSIXACL; @@ -553,6 +563,9 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",noacl"); #endif + if (fsopt->flags & CEPH_MOUNT_OPT_NOCOPYFROM) + seq_puts(m, ",nocopyfrom"); + if (fsopt->mds_namespace) seq_show_option(m, "mds_namespace", fsopt->mds_namespace); if (fsopt->wsize != CEPH_MAX_WRITE_SIZE) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 91b13400badd..c005a5400f2e 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -40,6 +40,7 @@ #define CEPH_MOUNT_OPT_NOPOOLPERM (1<<11) /* no pool permission check */ #define CEPH_MOUNT_OPT_MOUNTWAIT (1<<12) /* mount waits if no mds is up */ #define CEPH_MOUNT_OPT_NOQUOTADF (1<<13) /* no root dir quota in statfs */ +#define CEPH_MOUNT_OPT_NOCOPYFROM (1<<14) /* don't use RADOS 'copy-from' op */ #define CEPH_MOUNT_OPT_DEFAULT CEPH_MOUNT_OPT_DCACHE -- cgit v1.2.3 From 19fef6c4893d0321ec07978cb56bda0a753dde8c Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Wed, 5 Sep 2018 14:25:22 +0800 Subject: dt-bindings: csky CPU Bindings This patch adds the documentation to describe that how to add cpu nodes in dts for SMP. Signed-off-by: Guo Ren Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/csky/cpus.txt | 73 +++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/csky/cpus.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/csky/cpus.txt b/Documentation/devicetree/bindings/csky/cpus.txt new file mode 100644 index 000000000000..ae79412f2680 --- /dev/null +++ b/Documentation/devicetree/bindings/csky/cpus.txt @@ -0,0 +1,73 @@ +================== +C-SKY CPU Bindings +================== + +The device tree allows to describe the layout of CPUs in a system through +the "cpus" node, which in turn contains a number of subnodes (ie "cpu") +defining properties for every cpu. + +Only SMP system need to care about the cpus node and single processor +needn't define cpus node at all. + +===================================== +cpus and cpu node bindings definition +===================================== + +- cpus node + + Description: Container of cpu nodes + + The node name must be "cpus". + + A cpus node must define the following properties: + + - #address-cells + Usage: required + Value type: + Definition: must be set to 1 + - #size-cells + Usage: required + Value type: + Definition: must be set to 0 + +- cpu node + + Description: Describes one of SMP cores + + PROPERTIES + + - device_type + Usage: required + Value type: + Definition: must be "cpu" + - reg + Usage: required + Value type: + Definition: CPU index + - compatible: + Usage: required + Value type: + Definition: must contain "csky", eg: + "csky,610" + "csky,807" + "csky,810" + "csky,860" + +Example: +-------- + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + reg = <0>; + status = "ok"; + }; + + cpu@1 { + device_type = "cpu"; + reg = <1>; + status = "ok"; + }; + }; -- cgit v1.2.3 From f746650f9cdce67419041b8c2cc1f11db2d666d1 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Wed, 12 Sep 2018 21:03:06 +0800 Subject: dt-bindings: Add vendor prefix for csky Add csky vendor definition. Signed-off-by: Guo Ren Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 2c3fc512e746..a728ee3817c0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -84,6 +84,7 @@ cosmic Cosmic Circuits crane Crane Connectivity Solutions creative Creative Technology Ltd crystalfontz Crystalfontz America, Inc. +csky Hangzhou C-SKY Microsystems Co., Ltd cubietech Cubietech, Ltd. cypress Cypress Semiconductor Corporation cznic CZ.NIC, z.s.p.o. -- cgit v1.2.3 From 3fe5d5bd2dd92124f2a773c19fbc117e023a2ce3 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 18 Sep 2018 21:07:00 +0800 Subject: dt-bindings: interrupt-controller: C-SKY SMP intc Dt-bindings doc about C-SKY Multi-processors interrupt controller. Changelog: - Should be: '#interrupt-cells' not 'interrupt-cells' Signed-off-by: Guo Ren Reviewed-by: Rob Herring --- .../bindings/interrupt-controller/csky,mpintc.txt | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt new file mode 100644 index 000000000000..ab921f1698fb --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt @@ -0,0 +1,40 @@ +=========================================== +C-SKY Multi-processors Interrupt Controller +=========================================== + +C-SKY Multi-processors Interrupt Controller is designed for ck807/ck810/ck860 +SMP soc, and it also could be used in non-SMP system. + +Interrupt number definition: + + 0-15 : software irq, and we use 15 as our IPI_IRQ. + 16-31 : private irq, and we use 16 as the co-processor timer. + 31-1024: common irq for soc ip. + +============================= +intc node bindings definition +============================= + + Description: Describes SMP interrupt controller + + PROPERTIES + + - compatible + Usage: required + Value type: + Definition: must be "csky,mpintc" + - #interrupt-cells + Usage: required + Value type: + Definition: must be <1> + - interrupt-controller: + Usage: required + +Examples: +--------- + + intc: interrupt-controller { + compatible = "csky,mpintc"; + #interrupt-cells = <1>; + interrupt-controller; + }; -- cgit v1.2.3 From 2347e7e1aea410865e3c3f92014b07ff7d4c5b02 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Wed, 5 Sep 2018 14:25:23 +0800 Subject: dt-bindings: interrupt-controller: C-SKY APB intc - Dt-bindings doc about C-SKY apb bus interrupt controller. Signed-off-by: Guo Ren Reviewed-by: Rob Herring --- .../interrupt-controller/csky,apb-intc.txt | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/csky,apb-intc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/csky,apb-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/csky,apb-intc.txt new file mode 100644 index 000000000000..44286dcbac62 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/csky,apb-intc.txt @@ -0,0 +1,62 @@ +============================== +C-SKY APB Interrupt Controller +============================== + +C-SKY APB Interrupt Controller is a simple soc interrupt controller +on the apb bus and we only use it as root irq controller. + + - csky,apb-intc is used in a lot of csky fpgas and socs, it support 64 irq nums. + - csky,dual-apb-intc consists of 2 apb-intc and 128 irq nums supported. + - csky,gx6605s-intc is gx6605s soc internal irq interrupt controller, 64 irq nums. + +============================= +intc node bindings definition +============================= + + Description: Describes APB interrupt controller + + PROPERTIES + + - compatible + Usage: required + Value type: + Definition: must be "csky,apb-intc" + "csky,dual-apb-intc" + "csky,gx6605s-intc" + - #interrupt-cells + Usage: required + Value type: + Definition: must be <1> + - reg + Usage: required + Value type: + Definition: in soc from cpu view + - interrupt-controller: + Usage: required + - csky,support-pulse-signal: + Usage: select + Description: to support pulse signal flag + +Examples: +--------- + + intc: interrupt-controller@500000 { + compatible = "csky,apb-intc"; + #interrupt-cells = <1>; + reg = <0x00500000 0x400>; + interrupt-controller; + }; + + intc: interrupt-controller@500000 { + compatible = "csky,dual-apb-intc"; + #interrupt-cells = <1>; + reg = <0x00500000 0x400>; + interrupt-controller; + }; + + intc: interrupt-controller@500000 { + compatible = "csky,gx6605s-intc"; + #interrupt-cells = <1>; + reg = <0x00500000 0x400>; + interrupt-controller; + }; -- cgit v1.2.3 From ede95a63b5e84ddeea6b0c473b36ab8bfd8c6ce3 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 23 Oct 2018 01:11:04 +0200 Subject: bpf: add bpf_jit_limit knob to restrict unpriv allocations Rick reported that the BPF JIT could potentially fill the entire module space with BPF programs from unprivileged users which would prevent later attempts to load normal kernel modules or privileged BPF programs, for example. If JIT was enabled but unsuccessful to generate the image, then before commit 290af86629b2 ("bpf: introduce BPF_JIT_ALWAYS_ON config") we would always fall back to the BPF interpreter. Nowadays in the case where the CONFIG_BPF_JIT_ALWAYS_ON could be set, then the load will abort with a failure since the BPF interpreter was compiled out. Add a global limit and enforce it for unprivileged users such that in case of BPF interpreter compiled out we fail once the limit has been reached or we fall back to BPF interpreter earlier w/o using module mem if latter was compiled in. In a next step, fair share among unprivileged users can be resolved in particular for the case where we would fail hard once limit is reached. Fixes: 290af86629b2 ("bpf: introduce BPF_JIT_ALWAYS_ON config") Fixes: 0a14842f5a3c ("net: filter: Just In Time compiler for x86-64") Co-Developed-by: Rick Edgecombe Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Cc: Eric Dumazet Cc: Jann Horn Cc: Kees Cook Cc: LKML Signed-off-by: Alexei Starovoitov --- Documentation/sysctl/net.txt | 8 ++++++++ include/linux/filter.h | 1 + kernel/bpf/core.c | 49 +++++++++++++++++++++++++++++++++++++++++--- net/core/sysctl_net_core.c | 10 +++++++-- 4 files changed, 63 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index 9ecde517728c..2793d4eac55f 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -92,6 +92,14 @@ Values : 0 - disable JIT kallsyms export (default value) 1 - enable JIT kallsyms export for privileged users only +bpf_jit_limit +------------- + +This enforces a global limit for memory allocations to the BPF JIT +compiler in order to reject unprivileged JIT requests once it has +been surpassed. bpf_jit_limit contains the value of the global limit +in bytes. + dev_weight -------------- diff --git a/include/linux/filter.h b/include/linux/filter.h index 91b4c934f02e..de629b706d1d 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -854,6 +854,7 @@ bpf_run_sk_reuseport(struct sock_reuseport *reuse, struct sock *sk, extern int bpf_jit_enable; extern int bpf_jit_harden; extern int bpf_jit_kallsyms; +extern int bpf_jit_limit; typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 7c7eeea8cffc..6377225b2082 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -365,10 +365,13 @@ void bpf_prog_kallsyms_del_all(struct bpf_prog *fp) } #ifdef CONFIG_BPF_JIT +# define BPF_JIT_LIMIT_DEFAULT (PAGE_SIZE * 40000) + /* All BPF JIT sysctl knobs here. */ int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON); int bpf_jit_harden __read_mostly; int bpf_jit_kallsyms __read_mostly; +int bpf_jit_limit __read_mostly = BPF_JIT_LIMIT_DEFAULT; static __always_inline void bpf_get_prog_addr_region(const struct bpf_prog *prog, @@ -577,27 +580,64 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type, return ret; } +static atomic_long_t bpf_jit_current; + +#if defined(MODULES_VADDR) +static int __init bpf_jit_charge_init(void) +{ + /* Only used as heuristic here to derive limit. */ + bpf_jit_limit = min_t(u64, round_up((MODULES_END - MODULES_VADDR) >> 2, + PAGE_SIZE), INT_MAX); + return 0; +} +pure_initcall(bpf_jit_charge_init); +#endif + +static int bpf_jit_charge_modmem(u32 pages) +{ + if (atomic_long_add_return(pages, &bpf_jit_current) > + (bpf_jit_limit >> PAGE_SHIFT)) { + if (!capable(CAP_SYS_ADMIN)) { + atomic_long_sub(pages, &bpf_jit_current); + return -EPERM; + } + } + + return 0; +} + +static void bpf_jit_uncharge_modmem(u32 pages) +{ + atomic_long_sub(pages, &bpf_jit_current); +} + struct bpf_binary_header * bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, unsigned int alignment, bpf_jit_fill_hole_t bpf_fill_ill_insns) { struct bpf_binary_header *hdr; - unsigned int size, hole, start; + u32 size, hole, start, pages; /* Most of BPF filters are really small, but if some of them * fill a page, allow at least 128 extra bytes to insert a * random section of illegal instructions. */ size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE); + pages = size / PAGE_SIZE; + + if (bpf_jit_charge_modmem(pages)) + return NULL; hdr = module_alloc(size); - if (hdr == NULL) + if (!hdr) { + bpf_jit_uncharge_modmem(pages); return NULL; + } /* Fill space with illegal/arch-dep instructions. */ bpf_fill_ill_insns(hdr, size); - hdr->pages = size / PAGE_SIZE; + hdr->pages = pages; hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)), PAGE_SIZE - sizeof(*hdr)); start = (get_random_int() % hole) & ~(alignment - 1); @@ -610,7 +650,10 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, void bpf_jit_binary_free(struct bpf_binary_header *hdr) { + u32 pages = hdr->pages; + module_memfree(hdr); + bpf_jit_uncharge_modmem(pages); } /* This symbol is only overridden by archs that have different diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index b1a2c5e38530..37b4667128a3 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -279,7 +279,6 @@ static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write, return ret; } -# ifdef CONFIG_HAVE_EBPF_JIT static int proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, @@ -290,7 +289,6 @@ proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, return proc_dointvec_minmax(table, write, buffer, lenp, ppos); } -# endif #endif static struct ctl_table net_core_table[] = { @@ -397,6 +395,14 @@ static struct ctl_table net_core_table[] = { .extra2 = &one, }, # endif + { + .procname = "bpf_jit_limit", + .data = &bpf_jit_limit, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = proc_dointvec_minmax_bpf_restricted, + .extra1 = &one, + }, #endif { .procname = "netdev_tstamp_prequeue", -- cgit v1.2.3 From d48cf356a13073853f19be6ca5ebbecfc2762ebe Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 1 Oct 2018 10:41:51 -0400 Subject: SUNRPC: Remove non-RCU protected lookup Clean up the cache code by removing the non-RCU protected lookup. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- Documentation/filesystems/nfs/rpc-cache.txt | 6 +-- include/linux/sunrpc/cache.h | 6 --- net/sunrpc/cache.c | 61 ++--------------------------- 3 files changed, 7 insertions(+), 66 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/nfs/rpc-cache.txt b/Documentation/filesystems/nfs/rpc-cache.txt index ebcaaee21616..c4dac829db0f 100644 --- a/Documentation/filesystems/nfs/rpc-cache.txt +++ b/Documentation/filesystems/nfs/rpc-cache.txt @@ -84,7 +84,7 @@ Creating a Cache A message from user space has arrived to fill out a cache entry. It is in 'buf' of length 'len'. cache_parse should parse this, find the item in the - cache with sunrpc_cache_lookup, and update the item + cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update. @@ -95,7 +95,7 @@ Creating a Cache Using a cache ------------- -To find a value in a cache, call sunrpc_cache_lookup passing a pointer +To find a value in a cache, call sunrpc_cache_lookup_rcu passing a pointer to the cache_head in a sample item with the 'key' fields filled in. This will be passed to ->match to identify the target entry. If no entry is found, a new entry will be create, added to the cache, and @@ -116,7 +116,7 @@ item does become valid, the deferred copy of the request will be revisited (->revisit). It is expected that this method will reschedule the request for processing. -The value returned by sunrpc_cache_lookup can also be passed to +The value returned by sunrpc_cache_lookup_rcu can also be passed to sunrpc_cache_update to set the content for the item. A second item is passed which should hold the content. If the item found by _lookup has valid data, then it is discarded and a new item is created. This diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index cf3e17ee2786..c3d67e893430 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -171,9 +171,6 @@ extern struct cache_head * sunrpc_cache_lookup_rcu(struct cache_detail *detail, struct cache_head *key, int hash); extern struct cache_head * -sunrpc_cache_lookup(struct cache_detail *detail, - struct cache_head *key, int hash); -extern struct cache_head * sunrpc_cache_update(struct cache_detail *detail, struct cache_head *new, struct cache_head *old, int hash); @@ -233,9 +230,6 @@ extern void sunrpc_cache_unregister_pipefs(struct cache_detail *); extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *); /* Must store cache_detail in seq_file->private if using next three functions */ -extern void *cache_seq_start(struct seq_file *file, loff_t *pos); -extern void *cache_seq_next(struct seq_file *file, void *p, loff_t *pos); -extern void cache_seq_stop(struct seq_file *file, void *p); extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos); extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos); extern void cache_seq_stop_rcu(struct seq_file *file, void *p); diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 7593afed9036..593cf8607414 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -75,27 +75,6 @@ static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail, return NULL; } -static struct cache_head *sunrpc_cache_find(struct cache_detail *detail, - struct cache_head *key, int hash) -{ - struct hlist_head *head = &detail->hash_table[hash]; - struct cache_head *tmp; - - read_lock(&detail->hash_lock); - hlist_for_each_entry(tmp, head, cache_list) { - if (detail->match(tmp, key)) { - if (cache_is_expired(detail, tmp)) - /* This entry is expired, we will discard it. */ - break; - cache_get(tmp); - read_unlock(&detail->hash_lock); - return tmp; - } - } - read_unlock(&detail->hash_lock); - return NULL; -} - static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail, struct cache_head *key, int hash) @@ -154,20 +133,6 @@ struct cache_head *sunrpc_cache_lookup_rcu(struct cache_detail *detail, } EXPORT_SYMBOL_GPL(sunrpc_cache_lookup_rcu); -struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, - struct cache_head *key, int hash) -{ - struct cache_head *ret; - - ret = sunrpc_cache_find(detail, key, hash); - if (ret) - return ret; - /* Didn't find anything, insert an empty entry */ - return sunrpc_cache_add_entry(detail, key, hash); -} -EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); - - static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch); static void cache_fresh_locked(struct cache_head *head, time_t expiry, @@ -1369,17 +1334,7 @@ static void *__cache_seq_start(struct seq_file *m, loff_t *pos) struct cache_head, cache_list); } -void *cache_seq_start(struct seq_file *m, loff_t *pos) - __acquires(cd->hash_lock) -{ - struct cache_detail *cd = m->private; - - read_lock(&cd->hash_lock); - return __cache_seq_start(m, pos); -} -EXPORT_SYMBOL_GPL(cache_seq_start); - -void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos) +static void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos) { struct cache_head *ch = p; int hash = (*pos >> 32); @@ -1411,14 +1366,6 @@ void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos) } EXPORT_SYMBOL_GPL(cache_seq_next); -void cache_seq_stop(struct seq_file *m, void *p) - __releases(cd->hash_lock) -{ - struct cache_detail *cd = m->private; - read_unlock(&cd->hash_lock); -} -EXPORT_SYMBOL_GPL(cache_seq_stop); - void *cache_seq_start_rcu(struct seq_file *m, loff_t *pos) __acquires(RCU) { @@ -1466,9 +1413,9 @@ static int c_show(struct seq_file *m, void *p) } static const struct seq_operations cache_content_op = { - .start = cache_seq_start, - .next = cache_seq_next, - .stop = cache_seq_stop, + .start = cache_seq_start_rcu, + .next = cache_seq_next_rcu, + .stop = cache_seq_stop_rcu, .show = c_show, }; -- cgit v1.2.3 From 530d4c0cfd5b71caf2d17f73a80696c4a4509813 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 30 Oct 2018 15:09:54 -0700 Subject: docs/boot-time-mm: remove bootmem documentation Link: http://lkml.kernel.org/r/1536927045-23536-31-git-send-email-rppt@linux.vnet.ibm.com Signed-off-by: Mike Rapoport Cc: Catalin Marinas Cc: Chris Zankel Cc: "David S. Miller" Cc: Geert Uytterhoeven Cc: Greentime Hu Cc: Greg Kroah-Hartman Cc: Guan Xuetao Cc: Ingo Molnar Cc: "James E.J. Bottomley" Cc: Jonas Bonn Cc: Jonathan Corbet Cc: Ley Foon Tan Cc: Mark Salter Cc: Martin Schwidefsky Cc: Matt Turner Cc: Michael Ellerman Cc: Michal Hocko Cc: Michal Simek Cc: Palmer Dabbelt Cc: Paul Burton Cc: Richard Kuo Cc: Richard Weinberger Cc: Rich Felker Cc: Russell King Cc: Serge Semin Cc: Thomas Gleixner Cc: Tony Luck Cc: Vineet Gupta Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/core-api/boot-time-mm.rst | 69 +++++---------------------------- 1 file changed, 9 insertions(+), 60 deletions(-) (limited to 'Documentation') diff --git a/Documentation/core-api/boot-time-mm.rst b/Documentation/core-api/boot-time-mm.rst index 6e12e89a03e0..e5ec9f1a563d 100644 --- a/Documentation/core-api/boot-time-mm.rst +++ b/Documentation/core-api/boot-time-mm.rst @@ -5,54 +5,23 @@ Boot time memory management Early system initialization cannot use "normal" memory management simply because it is not set up yet. But there is still need to allocate memory for various data structures, for instance for the -physical page allocator. To address this, a specialized allocator -called the :ref:`Boot Memory Allocator `, or bootmem, was -introduced. Several years later PowerPC developers added a "Logical -Memory Blocks" allocator, which was later adopted by other -architectures and renamed to :ref:`memblock `. There is also -a compatibility layer called `nobootmem` that translates bootmem -allocation interfaces to memblock calls. +physical page allocator. -The selection of the early allocator is done using -``CONFIG_NO_BOOTMEM`` and ``CONFIG_HAVE_MEMBLOCK`` kernel -configuration options. These options are enabled or disabled -statically by the architectures' Kconfig files. - -* Architectures that rely only on bootmem select - ``CONFIG_NO_BOOTMEM=n && CONFIG_HAVE_MEMBLOCK=n``. -* The users of memblock with the nobootmem compatibility layer set - ``CONFIG_NO_BOOTMEM=y && CONFIG_HAVE_MEMBLOCK=y``. -* And for those that use both memblock and bootmem the configuration - includes ``CONFIG_NO_BOOTMEM=n && CONFIG_HAVE_MEMBLOCK=y``. - -Whichever allocator is used, it is the responsibility of the -architecture specific initialization to set it up in -:c:func:`setup_arch` and tear it down in :c:func:`mem_init` functions. +A specialized allocator called ``memblock`` performs the +boot time memory management. The architecture specific initialization +must set it up in :c:func:`setup_arch` and tear it down in +:c:func:`mem_init` functions. Once the early memory management is available it offers a variety of functions and macros for memory allocations. The allocation request may be directed to the first (and probably the only) node or to a particular node in a NUMA system. There are API variants that panic -when an allocation fails and those that don't. And more recent and -advanced memblock even allows controlling its own behaviour. - -.. _bootmem: - -Bootmem -======= +when an allocation fails and those that don't. -(mostly stolen from Mel Gorman's "Understanding the Linux Virtual -Memory Manager" `book`_) +Memblock also offers a variety of APIs that control its own behaviour. -.. _book: https://www.kernel.org/doc/gorman/ - -.. kernel-doc:: mm/bootmem.c - :doc: bootmem overview - -.. _memblock: - -Memblock -======== +Memblock Overview +================= .. kernel-doc:: mm/memblock.c :doc: memblock overview @@ -61,26 +30,6 @@ Memblock Functions and structures ======================== -Common API ----------- - -The functions that are described in this section are available -regardless of what early memory manager is enabled. - -.. kernel-doc:: mm/nobootmem.c - -Bootmem specific API --------------------- - -These interfaces available only with bootmem, i.e when ``CONFIG_NO_BOOTMEM=n`` - -.. kernel-doc:: include/linux/bootmem.h -.. kernel-doc:: mm/bootmem.c - :functions: - -Memblock specific API ---------------------- - Here is the description of memblock data structures, functions and macros. Some of them are actually internal, but since they are documented it would be silly to omit them. Besides, reading the -- cgit v1.2.3 From dee6da22efac451d361f5224a60be2796d847b51 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 30 Oct 2018 15:10:44 -0700 Subject: memory-hotplug.rst: add some details about locking internals Let's document the magic a bit, especially why device_hotplug_lock is required when adding/removing memory and how it all play together with requests to online/offline memory from user space. Link: http://lkml.kernel.org/r/20180925091457.28651-7-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Pavel Tatashin Reviewed-by: Rashmica Gupta Reviewed-by: Oscar Salvador Cc: Jonathan Corbet Cc: Michal Hocko Cc: Balbir Singh Cc: Benjamin Herrenschmidt Cc: Boris Ostrovsky Cc: Dan Williams Cc: Greg Kroah-Hartman Cc: Haiyang Zhang Cc: Heiko Carstens Cc: John Allen Cc: Joonsoo Kim Cc: Juergen Gross Cc: Kate Stewart Cc: "K. Y. Srinivasan" Cc: Len Brown Cc: Martin Schwidefsky Cc: Mathieu Malaterre Cc: Michael Ellerman Cc: Michael Neuling Cc: Nathan Fontenot Cc: Paul Mackerras Cc: Philippe Ombredanne Cc: Rafael J. Wysocki Cc: "Rafael J. Wysocki" Cc: Stephen Hemminger Cc: Thomas Gleixner Cc: Vlastimil Babka Cc: YASUAKI ISHIMATSU Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/admin-guide/mm/memory-hotplug.rst | 42 ++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst index 25157aec5b31..5c4432c96c4b 100644 --- a/Documentation/admin-guide/mm/memory-hotplug.rst +++ b/Documentation/admin-guide/mm/memory-hotplug.rst @@ -5,7 +5,7 @@ Memory Hotplug ============== :Created: Jul 28 2007 -:Updated: Add description of notifier of memory hotplug: Oct 11 2007 +:Updated: Add some details about locking internals: Aug 20 2018 This document is about memory hotplug including how-to-use and current status. Because Memory Hotplug is still under development, contents of this text will @@ -392,6 +392,46 @@ Need more implementation yet.... - Notification completion of remove works by OS to firmware. - Guard from remove if not yet. + +Locking Internals +================= + +When adding/removing memory that uses memory block devices (i.e. ordinary RAM), +the device_hotplug_lock should be held to: + +- synchronize against online/offline requests (e.g. via sysfs). This way, memory + block devices can only be accessed (.online/.state attributes) by user + space once memory has been fully added. And when removing memory, we + know nobody is in critical sections. +- synchronize against CPU hotplug and similar (e.g. relevant for ACPI and PPC) + +Especially, there is a possible lock inversion that is avoided using +device_hotplug_lock when adding memory and user space tries to online that +memory faster than expected: + +- device_online() will first take the device_lock(), followed by + mem_hotplug_lock +- add_memory_resource() will first take the mem_hotplug_lock, followed by + the device_lock() (while creating the devices, during bus_add_device()). + +As the device is visible to user space before taking the device_lock(), this +can result in a lock inversion. + +onlining/offlining of memory should be done via device_online()/ +device_offline() - to make sure it is properly synchronized to actions +via sysfs. Holding device_hotplug_lock is advised (to e.g. protect online_type) + +When adding/removing/onlining/offlining memory or adding/removing +heterogeneous/device memory, we should always hold the mem_hotplug_lock in +write mode to serialise memory hotplug (e.g. access to global/zone +variables). + +In addition, mem_hotplug_lock (in contrast to device_hotplug_lock) in read +mode allows for a quite efficient get_online_mems/put_online_mems +implementation, so code accessing memory can protect from that memory +vanishing. + + Future Work =========== -- cgit v1.2.3