summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.txt41
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.yaml74
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-dpaux.yaml152
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-sor.yaml197
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml72
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.yaml85
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-display.yaml310
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dsi-padctl.yaml45
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml183
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml159
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml70
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml74
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml215
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml126
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt675
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml431
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml67
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml73
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml58
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml163
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra210-csi.yaml52
-rw-r--r--Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt59
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/gpu/drm/tegra/dc.c1
-rw-r--r--drivers/gpu/drm/tegra/drm.c1
-rw-r--r--drivers/gpu/drm/tegra/drm.h11
-rw-r--r--drivers/gpu/drm/tegra/falcon.c8
-rw-r--r--drivers/gpu/drm/tegra/falcon.h1
-rw-r--r--drivers/gpu/drm/tegra/gem.c11
-rw-r--r--drivers/gpu/drm/tegra/hub.c1
-rw-r--r--drivers/gpu/drm/tegra/nvdec.c14
-rw-r--r--drivers/gpu/drm/tegra/plane.c1
-rw-r--r--drivers/gpu/drm/tegra/submit.c48
-rw-r--r--drivers/gpu/drm/tegra/uapi.c43
-rw-r--r--drivers/gpu/drm/tegra/vic.c92
-rw-r--r--drivers/gpu/host1x/Makefile6
-rw-r--r--drivers/gpu/host1x/cdma.c43
-rw-r--r--drivers/gpu/host1x/channel.c8
-rw-r--r--drivers/gpu/host1x/context.c160
-rw-r--r--drivers/gpu/host1x/context.h38
-rw-r--r--drivers/gpu/host1x/context_bus.c5
-rw-r--r--drivers/gpu/host1x/dev.c124
-rw-r--r--drivers/gpu/host1x/dev.h13
-rw-r--r--drivers/gpu/host1x/hw/cdma_hw.c34
-rw-r--r--drivers/gpu/host1x/hw/channel_hw.c137
-rw-r--r--drivers/gpu/host1x/hw/host1x01_hardware.h114
-rw-r--r--drivers/gpu/host1x/hw/host1x02_hardware.h113
-rw-r--r--drivers/gpu/host1x/hw/host1x04_hardware.h113
-rw-r--r--drivers/gpu/host1x/hw/host1x05_hardware.h113
-rw-r--r--drivers/gpu/host1x/hw/host1x06_hardware.h118
-rw-r--r--drivers/gpu/host1x/hw/host1x07_hardware.h118
-rw-r--r--drivers/gpu/host1x/hw/host1x08.c33
-rw-r--r--drivers/gpu/host1x/hw/host1x08.h15
-rw-r--r--drivers/gpu/host1x/hw/host1x08_hardware.h21
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x08_channel.h11
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x08_common.h11
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x08_hypervisor.h9
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x08_uclass.h181
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x08_vm.h36
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c11
-rw-r--r--drivers/gpu/host1x/hw/opcodes.h150
-rw-r--r--include/linux/host1x.h42
62 files changed, 3815 insertions, 1579 deletions
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.txt
deleted file mode 100644
index e4a25cedc5cf..000000000000
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-NVIDIA Tegra MIPI pad calibration controller
-
-Required properties:
-- compatible: "nvidia,tegra<chip>-mipi"
-- reg: Physical base address and length of the controller's registers.
-- clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
-- clock-names: Must include the following entries:
- - mipi-cal
-- #nvidia,mipi-calibrate-cells: Should be 1. The cell is a bitmask of the pads
- that need to be calibrated for a given device.
-
-User nodes need to contain an nvidia,mipi-calibrate property that has a
-phandle to refer to the calibration controller node and a bitmask of the pads
-that need to be calibrated.
-
-Example:
-
- mipi: mipi@700e3000 {
- compatible = "nvidia,tegra114-mipi";
- reg = <0x700e3000 0x100>;
- clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
- clock-names = "mipi-cal";
- #nvidia,mipi-calibrate-cells = <1>;
- };
-
- ...
-
- host1x@50000000 {
- ...
-
- dsi@54300000 {
- ...
-
- nvidia,mipi-calibrate = <&mipi 0x060>;
-
- ...
- };
-
- ...
- };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.yaml
new file mode 100644
index 000000000000..d5ca8cf86e8e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-mipi.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra114-mipi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra MIPI pad calibration controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^mipi@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra114-mipi
+ - nvidia,tegra210-mipi
+ - nvidia,tegra186-mipi
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ clock-names:
+ items:
+ - const: mipi-cal
+
+ power-domains:
+ maxItems: 1
+
+ "#nvidia,mipi-calibrate-cells":
+ description: The number of cells in a MIPI calibration specifier.
+ Should be 1. The single cell specifies a bitmask of the pads that
+ need to be calibrated for a given device.
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ const: 1
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#nvidia,mipi-calibrate-cells"
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra114-car.h>
+
+ mipi@700e3000 {
+ compatible = "nvidia,tegra114-mipi";
+ reg = <0x700e3000 0x100>;
+ clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
+ clock-names = "mipi-cal";
+ #nvidia,mipi-calibrate-cells = <1>;
+ };
+
+ dsia: dsi@54300000 {
+ compatible = "nvidia,tegra114-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_DSIA>,
+ <&tegra_car TEGRA114_CLK_DSIALP>,
+ <&tegra_car TEGRA114_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x060>; /* DSIA & DSIB pads */
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-dpaux.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-dpaux.yaml
new file mode 100644
index 000000000000..9ab123cd2325
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-dpaux.yaml
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-dpaux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra DisplayPort AUX Interface
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Tegra Display Port Auxiliary (DPAUX) pad controller manages two
+ pins which can be assigned to either the DPAUX channel or to an I2C
+ controller.
+
+ When configured for DisplayPort AUX operation, the DPAUX controller
+ can also be used to communicate with a DisplayPort device using the
+ AUX channel.
+
+properties:
+ $nodename:
+ pattern: "^dpaux@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra124-dpaux
+ - nvidia,tegra210-dpaux
+ - nvidia,tegra186-dpaux
+ - nvidia,tegra194-dpaux
+
+ - items:
+ - const: nvidia,tegra132-dpaux
+ - const: nvidia,tegra124-dpaux
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: clock input for the DPAUX hardware
+ - description: reference clock
+
+ clock-names:
+ items:
+ - const: dpaux
+ - const: parent
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: dpaux
+
+ power-domains:
+ maxItems: 1
+
+ i2c-bus:
+ description: Subnode where I2C slave devices are listed. This
+ subnode must be always present. If there are no I2C slave
+ devices, an empty node should be added. See ../../i2c/i2c.yaml
+ for more information.
+ type: object
+
+ aux-bus:
+ $ref: /schemas/display/dp-aux-bus.yaml#
+
+ vdd-supply:
+ description: phandle of a supply that powers the DisplayPort
+ link
+
+patternProperties:
+ "^pinmux-[a-z0-9]+$":
+ description:
+ Since only three configurations are possible, only three child
+ nodes are needed to describe the pin mux'ing options for the
+ DPAUX pads. Furthermore, given that the pad functions are only
+ applicable to a single set of pads, the child nodes only need
+ to describe the pad group the functions are being applied to
+ rather than the individual pads.
+ type: object
+ properties:
+ groups:
+ const: dpaux-io
+
+ function:
+ enum:
+ - aux
+ - i2c
+ - off
+
+ additionalProperties: false
+
+ required:
+ - groups
+ - function
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ dpaux: dpaux@545c0000 {
+ compatible = "nvidia,tegra210-dpaux";
+ reg = <0x545c0000 0x00040000>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_DPAUX>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>;
+ clock-names = "dpaux", "parent";
+ resets = <&tegra_car 181>;
+ reset-names = "dpaux";
+ power-domains = <&pd_sor>;
+ status = "disabled";
+
+ state_dpaux_aux: pinmux-aux {
+ groups = "dpaux-io";
+ function = "aux";
+ };
+
+ state_dpaux_i2c: pinmux-i2c {
+ groups = "dpaux-io";
+ function = "i2c";
+ };
+
+ state_dpaux_off: pinmux-off {
+ groups = "dpaux-io";
+ function = "off";
+ };
+
+ i2c-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-sor.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-sor.yaml
new file mode 100644
index 000000000000..907fb0baccae
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-sor.yaml
@@ -0,0 +1,197 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-sor.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra SOR Output Encoder
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The Serial Output Resource (SOR) can be used to drive HDMI, LVDS, eDP
+ and DP outputs.
+
+properties:
+ $nodename:
+ pattern: "^sor@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra124-sor
+ - nvidia,tegra210-sor
+ - nvidia,tegra210-sor1
+ - nvidia,tegra186-sor
+ - nvidia,tegra186-sor1
+ - nvidia,tegra194-sor
+
+ - items:
+ - const: nvidia,tegra132-sor
+ - const: nvidia,tegra124-sor
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 5
+ maxItems: 6
+
+ clock-names:
+ minItems: 5
+ maxItems: 6
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: sor
+
+ power-domains:
+ maxItems: 1
+
+ avdd-io-hdmi-dp-supply:
+ description: I/O supply for HDMI/DP
+
+ vdd-hdmi-dp-pll-supply:
+ description: PLL supply for HDMI/DP
+
+ hdmi-supply:
+ description: +5.0V HDMI connector supply, required for HDMI
+
+ # Tegra186 and later
+ nvidia,interface:
+ description: index of the SOR interface
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+
+ nvidia,ddc-i2c-bus:
+ description: phandle of an I2C controller used for DDC EDID
+ probing
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ nvidia,hpd-gpio:
+ description: specifies a GPIO used for hotplug detection
+ maxItems: 1
+
+ nvidia,edid:
+ description: supplies a binary EDID blob
+ $ref: "/schemas/types.yaml#/definitions/uint8-array"
+
+ nvidia,panel:
+ description: phandle of a display panel, required for eDP
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ nvidia,xbar-cfg:
+ description: 5 cells containing the crossbar configuration.
+ Each lane of the SOR, identified by the cell's index, is
+ mapped via the crossbar to the pad specified by the cell's
+ value.
+ $ref: "/schemas/types.yaml#/definitions/uint32-array"
+
+ # optional when driving an eDP output
+ nvidia,dpaux:
+ description: phandle to a DispayPort AUX interface
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra186-sor
+ - nvidia,tegra194-sor
+ then:
+ properties:
+ clocks:
+ items:
+ - description: clock input for the SOR hardware
+ - description: SOR output clock
+ - description: input for the pixel clock
+ - description: reference clock for the SOR clock
+ - description: safe reference clock for the SOR clock
+ during power up
+ - description: SOR pad output clock
+
+ clock-names:
+ items:
+ - const: sor
+ - enum:
+ - source # deprecated
+ - out
+ - const: parent
+ - const: dp
+ - const: safe
+ - const: pad
+ else:
+ properties:
+ clocks:
+ items:
+ - description: clock input for the SOR hardware
+ - description: SOR output clock
+ - description: input for the pixel clock
+ - description: reference clock for the SOR clock
+ - description: safe reference clock for the SOR clock
+ during power up
+
+ clock-names:
+ items:
+ - const: sor
+ - enum:
+ - source # deprecated
+ - out
+ - const: parent
+ - const: dp
+ - const: safe
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - avdd-io-hdmi-dp-supply
+ - vdd-hdmi-dp-pll-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/gpio/tegra-gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ sor0: sor@54540000 {
+ compatible = "nvidia,tegra210-sor";
+ reg = <0x54540000 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SOR0>,
+ <&tegra_car TEGRA210_CLK_SOR0_OUT>,
+ <&tegra_car TEGRA210_CLK_PLL_D_OUT0>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>,
+ <&tegra_car TEGRA210_CLK_SOR_SAFE>;
+ clock-names = "sor", "out", "parent", "dp", "safe";
+ resets = <&tegra_car 182>;
+ reset-names = "sor";
+ pinctrl-0 = <&state_dpaux_aux>;
+ pinctrl-1 = <&state_dpaux_i2c>;
+ pinctrl-2 = <&state_dpaux_off>;
+ pinctrl-names = "aux", "i2c", "off";
+ power-domains = <&pd_sor>;
+
+ avdd-io-hdmi-dp-supply = <&avdd_1v05>;
+ vdd-hdmi-dp-pll-supply = <&vdd_1v8>;
+ hdmi-supply = <&vdd_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(CC, 1) GPIO_ACTIVE_LOW>;
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml
new file mode 100644
index 000000000000..7200095ef19e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-vic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Video Image Composer
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^vic@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra124-vic
+ - nvidia,tegra210-vic
+ - nvidia,tegra186-vic
+ - nvidia,tegra194-vic
+ - nvidia,tegra234-vic
+
+ - items:
+ - const: nvidia,tegra132-vic
+ - const: nvidia,tegra124-vic
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: clock input for the VIC hardware
+
+ clock-names:
+ items:
+ - const: vic
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: vic
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ description: Description of the interconnect paths for the VIC;
+ see ../interconnect/interconnect.txt for details.
+ items:
+ - description: memory read client for VIC
+ - description: memory write client for VIC
+
+ interconnect-names:
+ items:
+ - const: dma-mem # read
+ - const: write
+
+ dma-coherent: true
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.yaml
new file mode 100644
index 000000000000..265a60d79d89
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 (and later) Display Controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^display@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra186-dc
+ - nvidia,tegra194-dc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: display controller pixel clock
+
+ clock-names:
+ items:
+ - const: dc
+
+ resets:
+ items:
+ - description: display controller reset
+
+ reset-names:
+ items:
+ - const: dc
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ description: Description of the interconnect paths for the
+ display controller; see ../interconnect/interconnect.txt
+ for details.
+
+ interconnect-names:
+ items:
+ - const: dma-mem # read-0
+ - const: read-1
+
+ nvidia,outputs:
+ description: A list of phandles of outputs that this display
+ controller can drive.
+ $ref: "/schemas/types.yaml#/definitions/phandle-array"
+
+ nvidia,head:
+ description: The number of the display controller head. This
+ is used to setup the various types of output to receive
+ video data from the given head.
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - power-domains
+ - nvidia,outputs
+ - nvidia,head
+
+# see nvidia,tegra186-display.yaml for examples
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-display.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-display.yaml
new file mode 100644
index 000000000000..8c0231345529
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-display.yaml
@@ -0,0 +1,310 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-display.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 (and later) Display Hub
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^display-hub@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra186-display
+ - nvidia,tegra194-display
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 1
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 2
+ maxItems: 3
+
+ clock-names:
+ minItems: 2
+ maxItems: 3
+
+ resets:
+ items:
+ - description: display hub reset
+ - description: window group 0 reset
+ - description: window group 1 reset
+ - description: window group 2 reset
+ - description: window group 3 reset
+ - description: window group 4 reset
+ - description: window group 5 reset
+
+ reset-names:
+ items:
+ - const: misc
+ - const: wgrp0
+ - const: wgrp1
+ - const: wgrp2
+ - const: wgrp3
+ - const: wgrp4
+ - const: wgrp5
+
+ power-domains:
+ maxItems: 1
+
+ ranges:
+ maxItems: 1
+
+patternProperties:
+ "^display@[0-9a-f]+$":
+ type: object
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra186-display
+ then:
+ properties:
+ clocks:
+ items:
+ - description: display core clock
+ - description: display stream compression clock
+ - description: display hub clock
+
+ clock-names:
+ items:
+ - const: disp
+ - const: dsc
+ - const: hub
+ else:
+ properties:
+ clocks:
+ items:
+ - description: display core clock
+ - description: display hub clock
+
+ clock-names:
+ items:
+ - const: disp
+ - const: hub
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - power-domains
+ - "#address-cells"
+ - "#size-cells"
+ - ranges
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra186-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/tegra186-mc.h>
+ #include <dt-bindings/power/tegra186-powergate.h>
+ #include <dt-bindings/reset/tegra186-reset.h>
+
+ display-hub@15200000 {
+ compatible = "nvidia,tegra186-display";
+ reg = <0x15200000 0x00040000>;
+ resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_MISC>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP0>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP1>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP2>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP3>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP4>,
+ <&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP5>;
+ reset-names = "misc", "wgrp0", "wgrp1", "wgrp2",
+ "wgrp3", "wgrp4", "wgrp5";
+ clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_DISP>,
+ <&bpmp TEGRA186_CLK_NVDISPLAY_DSC>,
+ <&bpmp TEGRA186_CLK_NVDISPLAYHUB>;
+ clock-names = "disp", "dsc", "hub";
+ status = "disabled";
+
+ power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x15200000 0x15200000 0x40000>;
+
+ display@15200000 {
+ compatible = "nvidia,tegra186-dc";
+ reg = <0x15200000 0x10000>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P0>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD0>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
+ interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+ iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
+
+ nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
+ nvidia,head = <0>;
+ };
+
+ display@15210000 {
+ compatible = "nvidia,tegra186-dc";
+ reg = <0x15210000 0x10000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P1>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD1>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISPB>;
+ interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+ iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
+
+ nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
+ nvidia,head = <1>;
+ };
+
+ display@15220000 {
+ compatible = "nvidia,tegra186-dc";
+ reg = <0x15220000 0x10000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P2>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD2>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISPC>;
+ interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+ iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
+
+ nvidia,outputs = <&sor0 &sor1>;
+ nvidia,head = <2>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/clock/tegra194-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/tegra194-mc.h>
+ #include <dt-bindings/power/tegra194-powergate.h>
+ #include <dt-bindings/reset/tegra194-reset.h>
+
+ display-hub@15200000 {
+ compatible = "nvidia,tegra194-display";
+ reg = <0x15200000 0x00040000>;
+ resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_MISC>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP0>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP1>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP2>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP3>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP4>,
+ <&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP5>;
+ reset-names = "misc", "wgrp0", "wgrp1", "wgrp2",
+ "wgrp3", "wgrp4", "wgrp5";
+ clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_DISP>,
+ <&bpmp TEGRA194_CLK_NVDISPLAYHUB>;
+ clock-names = "disp", "hub";
+ status = "disabled";
+
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x15200000 0x15200000 0x40000>;
+
+ display@15200000 {
+ compatible = "nvidia,tegra194-dc";
+ reg = <0x15200000 0x10000>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P0>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD0>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+
+ nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
+ nvidia,head = <0>;
+ };
+
+ display@15210000 {
+ compatible = "nvidia,tegra194-dc";
+ reg = <0x15210000 0x10000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P1>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD1>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPB>;
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+
+ nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
+ nvidia,head = <1>;
+ };
+
+ display@15220000 {
+ compatible = "nvidia,tegra194-dc";
+ reg = <0x15220000 0x10000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P2>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD2>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPC>;
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+
+ nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
+ nvidia,head = <2>;
+ };
+
+ display@15230000 {
+ compatible = "nvidia,tegra194-dc";
+ reg = <0x15230000 0x10000>;
+ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P3>;
+ clock-names = "dc";
+ resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD3>;
+ reset-names = "dc";
+
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPC>;
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
+ <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
+ interconnect-names = "dma-mem", "read-1";
+
+ nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
+ nvidia,head = <3>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dsi-padctl.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dsi-padctl.yaml
new file mode 100644
index 000000000000..e5a6145c8c53
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dsi-padctl.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-dsi-padctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra MIPI DSI pad controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^padctl@[0-9a-f]+$"
+
+ compatible:
+ const: nvidia,tegra186-dsi-padctl
+
+ reg:
+ maxItems: 1
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: dsi
+
+allOf:
+ - $ref: "/schemas/reset/reset.yaml"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/reset/tegra186-reset.h>
+
+ padctl@15880000 {
+ compatible = "nvidia,tegra186-dsi-padctl";
+ reg = <0x15880000 0x10000>;
+ resets = <&bpmp TEGRA186_RESET_DSI>;
+ reset-names = "dsi";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml
new file mode 100644
index 000000000000..6eedee503aa0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml
@@ -0,0 +1,183 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Display Controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^dc@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra20-dc
+ - nvidia,tegra30-dc
+ - nvidia,tegra114-dc
+ - nvidia,tegra124-dc
+ - nvidia,tegra210-dc
+
+ - items:
+ - const: nvidia,tegra124-dc
+ - const: nvidia,tegra132-dc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ items:
+ - description: display controller pixel clock
+ - description: parent clock # optional
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: dc
+ - const: parent # optional
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: dc
+
+ interconnect-names: true
+ interconnects: true
+
+ iommus:
+ maxItems: 1
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the core power domain
+
+ memory-region: true
+
+ nvidia,head:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: The number of the display controller head. This is used to setup the various
+ types of output to receive video data from the given head.
+
+ nvidia,outputs:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description: A list of phandles of outputs that this display controller can drive.
+
+ rgb:
+ type: object
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra20-dc
+ - nvidia,tegra30-dc
+ - nvidia,tegra114-dc
+ then:
+ properties:
+ interconnects:
+ items:
+ - description: window A memory client
+ - description: window B memory client
+ - description: window B memory client (vertical filter)
+ - description: window C memory client
+ - description: cursor memory client
+
+ interconnect-names:
+ items:
+ - const: wina
+ - const: winb
+ - const: winb-vfilter
+ - const: winc
+ - const: cursor
+
+ rgb:
+ description: Each display controller node has a child node, named "rgb", that represents
+ the RGB output associated with the controller.
+ type: object
+ properties:
+ nvidia,ddc-i2c-bus:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle of an I2C controller used for DDC EDID probing
+
+ nvidia,hpd-gpio:
+ description: specifies a GPIO used for hotplug detection
+ maxItems: 1
+
+ nvidia,edid:
+ $ref: /schemas/types.yaml#/definitions/uint8-array
+ description: supplies a binary EDID blob
+
+ nvidia,panel:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle of a display panel
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra124-dc
+ then:
+ properties:
+ interconnects:
+ minItems: 4
+ items:
+ - description: window A memory client
+ - description: window B memory client
+ - description: window C memory client
+ - description: cursor memory client
+ - description: window D memory client
+ - description: window T memory client
+
+ interconnect-names:
+ minItems: 4
+ items:
+ - const: wina
+ - const: winb
+ - const: winc
+ - const: cursor
+ - const: wind
+ - const: wint
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ dc@54200000 {
+ compatible = "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_DISP1>;
+ clock-names = "dc";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml
new file mode 100644
index 000000000000..75546f250ad7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml
@@ -0,0 +1,159 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-dsi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Display Serial Interface
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra20-dsi
+ - nvidia,tegra30-dsi
+ - nvidia,tegra114-dsi
+ - nvidia,tegra124-dsi
+ - nvidia,tegra210-dsi
+ - nvidia,tegra186-dsi
+
+ - items:
+ - const: nvidia,tegra132-dsi
+ - const: nvidia,tegra124-dsi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 2
+ maxItems: 3
+
+ clock-names:
+ minItems: 2
+ maxItems: 3
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: dsi
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ maxItems: 1
+
+ avdd-dsi-csi-supply:
+ description: phandle of a supply that powers the DSI controller
+
+ nvidia,mipi-calibrate:
+ description: Should contain a phandle and a specifier specifying
+ which pads are used by this DSI output and need to be
+ calibrated. See nvidia,tegra114-mipi.yaml for details.
+ $ref: "/schemas/types.yaml#/definitions/phandle-array"
+
+ nvidia,ddc-i2c-bus:
+ description: phandle of an I2C controller used for DDC EDID
+ probing
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ nvidia,hpd-gpio:
+ description: specifies a GPIO used for hotplug detection
+ maxItems: 1
+
+ nvidia,edid:
+ description: supplies a binary EDID blob
+ $ref: "/schemas/types.yaml#/definitions/uint8-array"
+
+ nvidia,panel:
+ description: phandle of a display panel
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ nvidia,ganged-mode:
+ description: contains a phandle to a second DSI controller to
+ gang up with in order to support up to 8 data lanes
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+allOf:
+ - $ref: "../dsi-controller.yaml#"
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra20-dsi
+ - nvidia,tegra30-dsi
+ then:
+ properties:
+ clocks:
+ items:
+ - description: DSI module clock
+ - description: input for the pixel clock
+
+ clock-names:
+ items:
+ - const: dsi
+ - const: parent
+ else:
+ properties:
+ clocks:
+ items:
+ - description: DSI module clock
+ - description: low-power module clock
+ - description: input for the pixel clock
+
+ clock-names:
+ items:
+ - const: dsi
+ - const: lp
+ - const: parent
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra186-dsi
+ then:
+ required:
+ - interrupts
+
+unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra186-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/tegra186-powergate.h>
+ #include <dt-bindings/reset/tegra186-reset.h>
+
+ dsi@15300000 {
+ compatible = "nvidia,tegra186-dsi";
+ reg = <0x15300000 0x10000>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA186_CLK_DSI>,
+ <&bpmp TEGRA186_CLK_DSIA_LP>,
+ <&bpmp TEGRA186_CLK_PLLD>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&bpmp TEGRA186_RESET_DSI>;
+ reset-names = "dsi";
+
+ power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml
new file mode 100644
index 000000000000..0d55e6206b5e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-epp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Encoder Pre-Processor
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^epp@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra20-epp
+ - nvidia,tegra30-epp
+ - nvidia,tegra114-epp
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: epp
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ maxItems: 4
+
+ interconnect-names:
+ maxItems: 4
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the core power domain
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ epp@540c0000 {
+ compatible = "nvidia,tegra20-epp";
+ reg = <0x540c0000 0x00040000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_EPP>;
+ resets = <&tegra_car 19>;
+ reset-names = "epp";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml
new file mode 100644
index 000000000000..bf38accd98eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-gr2d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA 2D graphics engine
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^gr2d@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra20-gr2d
+ - nvidia,tegra30-gr2d
+ - nvidia,tegra114-gr2d
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ resets:
+ items:
+ - description: module reset
+ - description: memory client hotflush reset
+
+ reset-names:
+ items:
+ - const: 2d
+ - const: mc
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ maxItems: 4
+
+ interconnect-names:
+ maxItems: 4
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the HEG or core power domain
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/tegra20-mc.h>
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra20-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_GR2D>;
+ resets = <&tegra_car 21>, <&mc TEGRA20_MC_RESET_2D>;
+ reset-names = "2d", "mc";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml
new file mode 100644
index 000000000000..dbdf0229d9f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml
@@ -0,0 +1,215 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-gr3d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA 3D graphics engine
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^gr3d@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra20-gr3d
+ - nvidia,tegra30-gr3d
+ - nvidia,tegra114-gr3d
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ maxItems: 2
+
+ resets:
+ minItems: 2
+ maxItems: 4
+
+ reset-names:
+ minItems: 2
+ maxItems: 4
+
+ iommus:
+ minItems: 1
+ maxItems: 2
+
+ interconnects:
+ minItems: 4
+ maxItems: 10
+
+ interconnect-names:
+ minItems: 4
+ maxItems: 10
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ minItems: 1
+ maxItems: 2
+
+ power-domain-names:
+ minItems: 2
+ maxItems: 2
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra20-gr2d
+ then:
+ properties:
+ clocks:
+ items:
+ - description: module clock
+
+ clock-names:
+ items:
+ - const: 3d
+
+ resets:
+ items:
+ - description: module reset
+ - description: memory client hotflush reset
+
+ reset-names:
+ items:
+ - const: 3d
+ - const: mc
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ minItems: 4
+ maxItems: 4
+
+ interconnect-names:
+ minItems: 4
+ maxItems: 4
+
+ power-domains:
+ items:
+ - description: phandle to the TD power domain
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra30-gr3d
+ then:
+ properties:
+ clocks:
+ items:
+ - description: primary module clock
+ - description: secondary module clock
+
+ clock-names:
+ items:
+ - const: 3d
+ - const: 3d2
+
+ resets:
+ items:
+ - description: primary module reset
+ - description: secondary module reset
+ - description: primary memory client hotflush reset
+ - description: secondary memory client hotflush reset
+
+ reset-names:
+ items:
+ - const: 3d
+ - const: 3d2
+ - const: mc
+ - const: mc2
+
+ iommus:
+ minItems: 2
+ maxItems: 2
+
+ interconnects:
+ minItems: 8
+ maxItems: 8
+
+ interconnect-names:
+ minItems: 8
+ maxItems: 8
+
+ power-domains:
+ items:
+ - description: phandle to the TD power domain
+ - description: phandle to the TD2 power domain
+
+ power-domain-names:
+ items:
+ - const: 3d0
+ - const: 3d1
+
+ dependencies:
+ power-domains: [ power-domain-names ]
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra114-gr2d
+ then:
+ properties:
+ clocks:
+ items:
+ - description: module clock
+
+ clock-names:
+ items:
+ - const: 3d
+
+ resets:
+ items:
+ - description: module reset
+ - description: memory client hotflush reset
+
+ reset-names:
+ items:
+ - const: 3d
+ - const: mc
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ minItems: 10
+ maxItems: 10
+
+ interconnect-names:
+ minItems: 10
+ maxItems: 10
+
+ power-domains:
+ items:
+ - description: phandle to the TD power domain
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/memory/tegra20-mc.h>
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra20-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA20_CLK_GR3D>;
+ resets = <&tegra_car 24>, <&mc TEGRA20_MC_RESET_3D>;
+ reset-names = "3d", "mc";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml
new file mode 100644
index 000000000000..035b9f1f2eb5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-hdmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra HDMI Output Encoder
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^hdmi@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra20-hdmi
+ - nvidia,tegra30-hdmi
+ - nvidia,tegra114-hdmi
+ - nvidia,tegra124-hdmi
+
+ - items:
+ - const: nvidia,tegra132-hdmi
+ - const: nvidia,tegra124-hdmi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+ - description: parent clock
+
+ clock-names:
+ items:
+ - const: hdmi
+ - const: parent
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: hdmi
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the core power domain
+
+ hdmi-supply:
+ description: supply for the +5V HDMI connector pin
+
+ vdd-supply:
+ description: regulator for supply voltage
+
+ pll-supply:
+ description: regulator for PLL
+
+ nvidia,ddc-i2c-bus:
+ description: phandle of an I2C controller used for DDC EDID
+ probing
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ nvidia,hpd-gpio:
+ description: specifies a GPIO used for hotplug detection
+ maxItems: 1
+
+ nvidia,edid:
+ description: supplies a binary EDID blob
+ $ref: "/schemas/types.yaml#/definitions/uint8-array"
+
+ nvidia,panel:
+ description: phandle of a display panel
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ "#sound-dai-cells":
+ const: 0
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - pll-supply
+ - vdd-supply
+ - nvidia,ddc-i2c-bus
+ - nvidia,hpd-gpio
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra124-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/gpio/tegra-gpio.h>
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra124-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_HDMI>,
+ <&tegra_car TEGRA124_CLK_PLL_D2_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ pll-supply = <&vdd_hdmi_pll>;
+ vdd-supply = <&vdd_3v3_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
deleted file mode 100644
index e61999ce54e9..000000000000
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ /dev/null
@@ -1,675 +0,0 @@
-NVIDIA Tegra host1x
-
-Required properties:
-- compatible: "nvidia,tegra<chip>-host1x"
-- reg: Physical base address and length of the controller's registers.
- For pre-Tegra186, one entry describing the whole register area.
- For Tegra186, one entry for each entry in reg-names:
- "vm" - VM region assigned to Linux
- "hypervisor" - Hypervisor region (only if Linux acts as hypervisor)
-- interrupts: The interrupt outputs from the controller.
-- #address-cells: The number of cells used to represent physical base addresses
- in the host1x address space. Should be 1.
-- #size-cells: The number of cells used to represent the size of an address
- range in the host1x address space. Should be 1.
-- ranges: The mapping of the host1x address space to the CPU address space.
-- clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
-- resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
-- reset-names: Must include the following entries:
- - host1x
- - mc
-
-Optional properties:
-- operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to HEG or core power domain.
-
-For each opp entry in 'operating-points-v2' table of host1x and its modules:
-- opp-supported-hw: One bitfield indicating:
- On Tegra20: SoC process ID mask
- On Tegra30+: SoC speedo ID mask
-
- A bitwise AND is performed against the value and if any bit
- matches, the OPP gets enabled.
-
-Each host1x client module having to perform DMA through the Memory Controller
-should have the interconnect endpoints set to the Memory Client and External
-Memory respectively.
-
-The host1x top-level node defines a number of children, each representing one
-of the following host1x client modules:
-
-- mpe: video encoder
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-mpe"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - mpe
-
- Optional properties:
- - interconnects: Must contain entry for the MPE memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to MPE power domain.
-
-- vi: video input
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-vi"
- - reg: Physical base address and length of the controller registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
- - Tegra20/Tegra30/Tegra114/Tegra124:
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - vi
- - Tegra210:
- - power-domains: Must include venc powergate node as vi is in VE partition.
-
- ports (optional node)
- vi can have optional ports node and max 6 ports are supported. Each port
- should have single 'endpoint' child node. All port nodes are grouped under
- ports node. Please refer to the bindings defined in
- Documentation/devicetree/bindings/media/video-interfaces.txt
-
- csi (required node)
- Tegra210 has CSI part of VI sharing same host interface and register space.
- So, VI device node should have CSI child node.
-
- - csi: mipi csi interface to vi
-
- Required properties:
- - compatible: "nvidia,tegra210-csi"
- - reg: Physical base address offset to parent and length of the controller
- registers.
- - clocks: Must contain entries csi, cilab, cilcd, cile, csi_tpg clocks.
- See ../clocks/clock-bindings.txt for details.
- - power-domains: Must include sor powergate node as csicil is in
- SOR partition.
-
- channel (optional nodes)
- Maximum 6 channels are supported with each csi brick as either x4 or x2
- based on hw connectivity to sensor.
-
- Required properties:
- - reg: csi port number. Valid port numbers are 0 through 5.
- - nvidia,mipi-calibrate: Should contain a phandle and a specifier
- specifying which pads are used by this CSI port and need to be
- calibrated. See also ../display/tegra/nvidia,tegra114-mipi.txt.
-
- Each channel node must contain 2 port nodes which can be grouped
- under 'ports' node and each port should have a single child 'endpoint'
- node.
-
- ports node
- Please refer to the bindings defined in
- Documentation/devicetree/bindings/media/video-interfaces.txt
-
- ports node must contain below 2 port nodes.
- port@0 with single child 'endpoint' node always a sink.
- port@1 with single child 'endpoint' node always a source.
-
- port@0 (required node)
- Required properties:
- - reg: 0
-
- endpoint (required node)
- Required properties:
- - data-lanes: an array of data lane from 1 to 8. Valid array
- lengths are 1/2/4/8.
- - remote-endpoint: phandle to sensor 'endpoint' node.
-
- port@1 (required node)
- Required properties:
- - reg: 1
-
- endpoint (required node)
- Required properties:
- - remote-endpoint: phandle to vi port 'endpoint' node.
-
- Optional properties:
- - interconnects: Must contain entry for the VI memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to VENC power domain.
-
-- epp: encoder pre-processor
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-epp"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - epp
-
- Optional properties:
- - interconnects: Must contain entry for the EPP memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to HEG or core power domain.
-
-- isp: image signal processor
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-isp"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - isp
-
- Optional properties:
- - interconnects: Must contain entry for the ISP memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - power-domains: Phandle to VENC or core power domain.
-
-- gr2d: 2D graphics engine
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-gr2d"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - 2d
- - mc
-
- Optional properties:
- - interconnects: Must contain entry for the GR2D memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to HEG or core power domain.
-
-- gr3d: 3D graphics engine
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-gr3d"
- - reg: Physical base address and length of the controller's registers.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- (This property may be omitted if the only clock in the list is "3d")
- - 3d
- This MUST be the first entry.
- - 3d2 (Only required on SoCs with two 3D clocks)
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - 3d
- - 3d2 (Only required on SoCs with two 3D clocks)
- - mc
- - mc2 (Only required on SoCs with two 3D clocks)
-
- Optional properties:
- - interconnects: Must contain entry for the GR3D memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandles to 3D or core power domain.
-
-- dc: display controller
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-dc"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - dc
- This MUST be the first entry.
- - parent
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - dc
- - nvidia,head: The number of the display controller head. This is used to
- setup the various types of output to receive video data from the given
- head.
-
- Each display controller node has a child node, named "rgb", that represents
- the RGB output associated with the controller. It can take the following
- optional properties:
- - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- - nvidia,edid: supplies a binary EDID blob
- - nvidia,panel: phandle of a display panel
- - interconnects: Must contain entry for the DC memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to core power domain.
-
-- hdmi: High Definition Multimedia Interface
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-hdmi"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - hdmi-supply: supply for the +5V HDMI connector pin
- - vdd-supply: regulator for supply voltage
- - pll-supply: regulator for PLL
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - hdmi
- This MUST be the first entry.
- - parent
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - hdmi
-
- Optional properties:
- - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- - nvidia,edid: supplies a binary EDID blob
- - nvidia,panel: phandle of a display panel
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
-
-- tvo: TV encoder output
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-tvo"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
-
- Optional properties:
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
- - power-domains: Phandle to core power domain.
-
-- dsi: display serial interface
-
- Required properties:
- - compatible: "nvidia,tegra<chip>-dsi"
- - reg: Physical base address and length of the controller's registers.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - dsi
- This MUST be the first entry.
- - lp
- - parent
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - dsi
- - avdd-dsi-supply: phandle of a supply that powers the DSI controller
- - nvidia,mipi-calibrate: Should contain a phandle and a specifier specifying
- which pads are used by this DSI output and need to be calibrated. See also
- ../display/tegra/nvidia,tegra114-mipi.txt.
-
- Optional properties:
- - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- - nvidia,edid: supplies a binary EDID blob
- - nvidia,panel: phandle of a display panel
- - nvidia,ganged-mode: contains a phandle to a second DSI controller to gang
- up with in order to support up to 8 data lanes
- - operating-points-v2: See ../bindings/opp/opp.txt for details.
-
-- sor: serial output resource
-
- Required properties:
- - compatible: Should be:
- - "nvidia,tegra124-sor": for Tegra124 and Tegra132
- - "nvidia,tegra132-sor": for Tegra132
- - "nvidia,tegra210-sor": for Tegra210
- - "nvidia,tegra210-sor1": for Tegra210
- - "nvidia,tegra186-sor": for Tegra186
- - "nvidia,tegra186-sor1": for Tegra186
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - sor: clock input for the SOR hardware
- - out: SOR output clock
- - parent: input for the pixel clock
- - dp: reference clock for the SOR clock
- - safe: safe reference for the SOR clock during power up
-
- For Tegra186 and later:
- - pad: SOR pad output clock (on Tegra186 and later)
-
- Obsolete:
- - source: source clock for the SOR clock (obsolete, use "out" instead)
-
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - sor
-
- Required properties on Tegra186 and later:
- - nvidia,interface: index of the SOR interface
-
- Optional properties:
- - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
- - nvidia,edid: supplies a binary EDID blob
- - nvidia,panel: phandle of a display panel
- - nvidia,xbar-cfg: 5 cells containing the crossbar configuration. Each lane
- of the SOR, identified by the cell's index, is mapped via the crossbar to
- the pad specified by the cell's value.
-
- Optional properties when driving an eDP output:
- - nvidia,dpaux: phandle to a DispayPort AUX interface
-
-- dpaux: DisplayPort AUX interface
- - compatible : Should contain one of the following:
- - "nvidia,tegra124-dpaux": for Tegra124 and Tegra132
- - "nvidia,tegra210-dpaux": for Tegra210
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - dpaux: clock input for the DPAUX hardware
- - parent: reference clock
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - dpaux
- - vdd-supply: phandle of a supply that powers the DisplayPort link
- - i2c-bus: Subnode where I2C slave devices are listed. This subnode
- must be always present. If there are no I2C slave devices, an empty
- node should be added. See ../../i2c/i2c.txt for more information.
-
- See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information
- regarding the DPAUX pad controller bindings.
-
-- vic: Video Image Compositor
- - compatible : "nvidia,tegra<chip>-vic"
- - reg: Physical base address and length of the controller's registers.
- - interrupts: The interrupt outputs from the controller.
- - clocks: Must contain an entry for each entry in clock-names.
- See ../clocks/clock-bindings.txt for details.
- - clock-names: Must include the following entries:
- - vic: clock input for the VIC hardware
- - resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
- - reset-names: Must include the following entries:
- - vic
-
- Optional properties:
- - interconnects: Must contain entry for the VIC memory clients.
- - interconnect-names: Must include name of the interconnect path for each
- interconnect entry. Consult TRM documentation for information about
- available memory clients, see MEMORY CONTROLLER section.
-
-Example:
-
-/ {
- ...
-
- host1x {
- compatible = "nvidia,tegra20-host1x", "simple-bus";
- reg = <0x50000000 0x00024000>;
- interrupts = <0 65 0x04 /* mpcore syncpt */
- 0 67 0x04>; /* mpcore general */
- clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
- resets = <&tegra_car 28>;
- reset-names = "host1x";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- ranges = <0x54000000 0x54000000 0x04000000>;
-
- mpe {
- compatible = "nvidia,tegra20-mpe";
- reg = <0x54040000 0x00040000>;
- interrupts = <0 68 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_MPE>;
- resets = <&tegra_car 60>;
- reset-names = "mpe";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
- };
-
- vi@54080000 {
- compatible = "nvidia,tegra210-vi";
- reg = <0x0 0x54080000 0x0 0x700>;
- interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
- assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
- assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
- operating-points-v2 = <&dvfs_opp_table>;
-
- clocks = <&tegra_car TEGRA210_CLK_VI>;
- power-domains = <&pd_venc>;
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- ranges = <0x0 0x0 0x54080000 0x2000>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- imx219_vi_in0: endpoint {
- remote-endpoint = <&imx219_csi_out0>;
- };
- };
- };
-
- csi@838 {
- compatible = "nvidia,tegra210-csi";
- reg = <0x838 0x1300>;
- assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
- <&tegra_car TEGRA210_CLK_CILCD>,
- <&tegra_car TEGRA210_CLK_CILE>,
- <&tegra_car TEGRA210_CLK_CSI_TPG>;
- assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
- <&tegra_car TEGRA210_CLK_PLL_P>,
- <&tegra_car TEGRA210_CLK_PLL_P>;
- assigned-clock-rates = <102000000>,
- <102000000>,
- <102000000>,
- <972000000>;
-
- clocks = <&tegra_car TEGRA210_CLK_CSI>,
- <&tegra_car TEGRA210_CLK_CILAB>,
- <&tegra_car TEGRA210_CLK_CILCD>,
- <&tegra_car TEGRA210_CLK_CILE>,
- <&tegra_car TEGRA210_CLK_CSI_TPG>;
- clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
- power-domains = <&pd_sor>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- channel@0 {
- reg = <0>;
- nvidia,mipi-calibrate = <&mipi 0x001>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- imx219_csi_in0: endpoint {
- data-lanes = <1 2>;
- remote-endpoint = <&imx219_out0>;
- };
- };
-
- port@1 {
- reg = <1>;
- imx219_csi_out0: endpoint {
- remote-endpoint = <&imx219_vi_in0>;
- };
- };
- };
- };
- };
- };
-
- epp {
- compatible = "nvidia,tegra20-epp";
- reg = <0x540c0000 0x00040000>;
- interrupts = <0 70 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_EPP>;
- resets = <&tegra_car 19>;
- reset-names = "epp";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
- };
-
- isp {
- compatible = "nvidia,tegra20-isp";
- reg = <0x54100000 0x00040000>;
- interrupts = <0 71 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_ISP>;
- resets = <&tegra_car 23>;
- reset-names = "isp";
- };
-
- gr2d {
- compatible = "nvidia,tegra20-gr2d";
- reg = <0x54140000 0x00040000>;
- interrupts = <0 72 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_GR2D>;
- resets = <&tegra_car 21>;
- reset-names = "2d";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
- };
-
- gr3d {
- compatible = "nvidia,tegra20-gr3d";
- reg = <0x54180000 0x00040000>;
- clocks = <&tegra_car TEGRA20_CLK_GR3D>;
- resets = <&tegra_car 24>;
- reset-names = "3d";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
- };
-
- dc@54200000 {
- compatible = "nvidia,tegra20-dc";
- reg = <0x54200000 0x00040000>;
- interrupts = <0 73 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_DISP1>,
- <&tegra_car TEGRA20_CLK_PLL_P>;
- clock-names = "dc", "parent";
- resets = <&tegra_car 27>;
- reset-names = "dc";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
-
- interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
- <&mc TEGRA20_MC_DISPLAY0B &emc>,
- <&mc TEGRA20_MC_DISPLAY0C &emc>,
- <&mc TEGRA20_MC_DISPLAYHC &emc>;
- interconnect-names = "wina",
- "winb",
- "winc",
- "cursor";
-
- rgb {
- status = "disabled";
- };
- };
-
- dc@54240000 {
- compatible = "nvidia,tegra20-dc";
- reg = <0x54240000 0x00040000>;
- interrupts = <0 74 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_DISP2>,
- <&tegra_car TEGRA20_CLK_PLL_P>;
- clock-names = "dc", "parent";
- resets = <&tegra_car 26>;
- reset-names = "dc";
- operating-points-v2 = <&dvfs_opp_table>;
- power-domains = <&domain>;
-
- interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
- <&mc TEGRA20_MC_DISPLAY0BB &emc>,
- <&mc TEGRA20_MC_DISPLAY0CB &emc>,
- <&mc TEGRA20_MC_DISPLAYHCB &emc>;
- interconnect-names = "wina",
- "winb",
- "winc",
- "cursor";
-
- rgb {
- status = "disabled";
- };
- };
-
- hdmi {
- compatible = "nvidia,tegra20-hdmi";
- reg = <0x54280000 0x00040000>;
- interrupts = <0 75 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_HDMI>,
- <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
- clock-names = "hdmi", "parent";
- resets = <&tegra_car 51>;
- reset-names = "hdmi";
- status = "disabled";
- operating-points-v2 = <&dvfs_opp_table>;
- };
-
- tvo {
- compatible = "nvidia,tegra20-tvo";
- reg = <0x542c0000 0x00040000>;
- interrupts = <0 76 0x04>;
- clocks = <&tegra_car TEGRA20_CLK_TVO>;
- status = "disabled";
- operating-points-v2 = <&dvfs_opp_table>;
- };
-
- dsi {
- compatible = "nvidia,tegra20-dsi";
- reg = <0x54300000 0x00040000>;
- clocks = <&tegra_car TEGRA20_CLK_DSI>,
- <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
- clock-names = "dsi", "parent";
- resets = <&tegra_car 48>;
- reset-names = "dsi";
- status = "disabled";
- operating-points-v2 = <&dvfs_opp_table>;
- };
- };
-
- ...
-};
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
new file mode 100644
index 000000000000..913ca104c871
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
@@ -0,0 +1,431 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-host1x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra host1x controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: The host1x top-level node defines a number of children, each
+ representing one of the host1x client modules defined in this binding.
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - nvidia,tegra20-host1x
+ - nvidia,tegra30-host1x
+ - nvidia,tegra114-host1x
+ - nvidia,tegra124-host1x
+ - nvidia,tegra210-host1x
+ - nvidia,tegra186-host1x
+ - nvidia,tegra194-host1x
+ - nvidia,tegra234-host1x
+
+ - items:
+ - const: nvidia,tegra132-host1x
+ - const: nvidia,tegra124-host1x
+
+ reg:
+ minItems: 1
+ maxItems: 3
+
+ reg-names:
+ minItems: 1
+ maxItems: 3
+
+ interrupts:
+ minItems: 1
+ maxItems: 9
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 9
+
+ '#address-cells':
+ description: The number of cells used to represent physical base addresses
+ in the host1x address space.
+ enum: [1, 2]
+
+ '#size-cells':
+ description: The number of cells used to represent the size of an address
+ range in the host1x address space.
+ enum: [1, 2]
+
+ ranges:
+ maxItems: 1
+
+ clocks:
+ description: Must contain one entry, for the module clock. See
+ ../clocks/clock-bindings.txt for details.
+
+ clock-names:
+ items:
+ - const: host1x
+
+ resets:
+ minItems: 1 # MC reset is optional on Tegra186 and later
+ items:
+ - description: module reset
+ - description: memory client hotflush reset
+
+ reset-names:
+ minItems: 1 # MC reset is optional on Tegra186 and later
+ items:
+ - const: host1x
+ - const: mc
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ items:
+ - description: memory read client for host1x
+
+ interconnect-names:
+ items:
+ - const: dma-mem # read
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the HEG or core power domain
+
+required:
+ - compatible
+ - interrupts
+ - interrupt-names
+ - '#address-cells'
+ - '#size-cells'
+ - ranges
+ - reg
+ - clocks
+ - clock-names
+
+unevaluatedProperties:
+ type: object
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra20-host1x
+ - nvidia,tegra30-host1x
+ - nvidia,tegra114-host1x
+ - nvidia,tegra124-host1x
+ - nvidia,tegra210-host1x
+ then:
+ properties:
+ interrupts:
+ items:
+ - description: host1x syncpoint interrupt
+ - description: host1x general interrupt
+
+ interrupt-names:
+ items:
+ - const: syncpt
+ - const: host1x
+ required:
+ - resets
+ - reset-names
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra186-host1x
+ - nvidia,tegra194-host1x
+ then:
+ properties:
+ reg-names:
+ items:
+ - const: hypervisor
+ - const: vm
+
+ reg:
+ items:
+ - description: region used by the hypervisor
+ - description: region assigned to the virtual machine
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ maxItems: 1
+
+ interrupts:
+ items:
+ - description: host1x syncpoint interrupt
+ - description: host1x general interrupt
+
+ interrupt-names:
+ items:
+ - const: syncpt
+ - const: host1x
+
+ iommu-map:
+ description: Specification of stream IDs available for memory context device
+ use. Should be a mapping of IDs 0..n to IOMMU entries corresponding to
+ usable stream IDs.
+
+ required:
+ - reg-names
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra234-host1x
+ then:
+ properties:
+ reg-names:
+ items:
+ - const: common
+ - const: hypervisor
+ - const: vm
+
+ reg:
+ items:
+ - description: region used by host1x server
+ - description: region used by the hypervisor
+ - description: region assigned to the virtual machine
+
+ interrupts:
+ items:
+ - description: host1x syncpoint interrupt 0
+ - description: host1x syncpoint interrupt 1
+ - description: host1x syncpoint interrupt 2
+ - description: host1x syncpoint interrupt 3
+ - description: host1x syncpoint interrupt 4
+ - description: host1x syncpoint interrupt 5
+ - description: host1x syncpoint interrupt 6
+ - description: host1x syncpoint interrupt 7
+ - description: host1x general interrupt
+
+ interrupt-names:
+ items:
+ - const: syncpt0
+ - const: syncpt1
+ - const: syncpt2
+ - const: syncpt3
+ - const: syncpt4
+ - const: syncpt5
+ - const: syncpt6
+ - const: syncpt7
+ - const: host1x
+
+ iommu-map:
+ description: Specification of stream IDs available for memory context device
+ use. Should be a mapping of IDs 0..n to IOMMU entries corresponding to
+ usable stream IDs.
+
+ required:
+ - reg-names
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/gpio/tegra-gpio.h>
+ #include <dt-bindings/memory/tegra20-mc.h>
+
+ host1x@50000000 {
+ compatible = "nvidia,tegra20-host1x";
+ reg = <0x50000000 0x00024000>;
+ interrupts = <0 65 0x04>, /* mpcore syncpt */
+ <0 67 0x04>; /* mpcore general */
+ interrupt-names = "syncpt", "host1x";
+ clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
+ clock-names = "host1x";
+ resets = <&tegra_car 28>, <&mc TEGRA20_MC_RESET_HC>;
+ reset-names = "host1x", "mc";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x04000000>;
+
+ mpe@54040000 {
+ compatible = "nvidia,tegra20-mpe";
+ reg = <0x54040000 0x00040000>;
+ interrupts = <0 68 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_MPE>;
+ resets = <&tegra_car 60>;
+ reset-names = "mpe";
+ };
+
+ vi@54080000 {
+ compatible = "nvidia,tegra20-vi";
+ reg = <0x54080000 0x00040000>;
+ interrupts = <0 69 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_VI>;
+ resets = <&tegra_car 100>;
+ reset-names = "vi";
+ };
+
+ epp@540c0000 {
+ compatible = "nvidia,tegra20-epp";
+ reg = <0x540c0000 0x00040000>;
+ interrupts = <0 70 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_EPP>;
+ resets = <&tegra_car 19>;
+ reset-names = "epp";
+ };
+
+ isp@54100000 {
+ compatible = "nvidia,tegra20-isp";
+ reg = <0x54100000 0x00040000>;
+ interrupts = <0 71 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_ISP>;
+ resets = <&tegra_car 23>;
+ reset-names = "isp";
+ };
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra20-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <0 72 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_GR2D>;
+ resets = <&tegra_car 21>, <&mc TEGRA20_MC_RESET_2D>;
+ reset-names = "2d", "mc";
+ };
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra20-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA20_CLK_GR3D>;
+ resets = <&tegra_car 24>, <&mc TEGRA20_MC_RESET_3D>;
+ reset-names = "3d", "mc";
+ };
+
+ dc@54200000 {
+ compatible = "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <0 73 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_DISP1>;
+ clock-names = "dc";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ rgb {
+ };
+ };
+
+ dc@54240000 {
+ compatible = "nvidia,tegra20-dc";
+ reg = <0x54240000 0x00040000>;
+ interrupts = <0 74 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_DISP2>;
+ clock-names = "dc";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ rgb {
+ };
+ };
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra20-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <0 75 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_HDMI>,
+ <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+
+ hdmi-supply = <&vdd_5v0_hdmi>;
+ pll-supply = <&vdd_hdmi_pll>;
+ vdd-supply = <&vdd_3v3_hdmi>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ tvo@542c0000 {
+ compatible = "nvidia,tegra20-tvo";
+ reg = <0x542c0000 0x00040000>;
+ interrupts = <0 76 0x04>;
+ clocks = <&tegra_car TEGRA20_CLK_TVO>;
+ };
+
+ dsi@54300000 {
+ compatible = "nvidia,tegra20-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA20_CLK_DSI>,
+ <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "parent";
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ };
+ };
+
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/tegra210-mc.h>
+
+ host1x@50000000 {
+ compatible = "nvidia,tegra210-host1x";
+ reg = <0x50000000 0x00024000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, /* mpcore syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* mpcore general */
+ interrupt-names = "syncpt", "host1x";
+ clocks = <&tegra_car TEGRA210_CLK_HOST1X>;
+ clock-names = "host1x";
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x01000000>;
+ iommus = <&mc TEGRA_SWGROUP_HC>;
+
+ vi@54080000 {
+ compatible = "nvidia,tegra210-vi";
+ reg = <0x54080000 0x00000700>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+
+ clocks = <&tegra_car TEGRA210_CLK_VI>;
+ power-domains = <&pd_venc>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x0 0x54080000 0x2000>;
+
+ csi@838 {
+ compatible = "nvidia,tegra210-csi";
+ reg = <0x838 0x1300>;
+ assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
+ <&tegra_car TEGRA210_CLK_CILCD>,
+ <&tegra_car TEGRA210_CLK_CILE>,
+ <&tegra_car TEGRA210_CLK_CSI_TPG>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
+ <&tegra_car TEGRA210_CLK_PLL_P>,
+ <&tegra_car TEGRA210_CLK_PLL_P>;
+ assigned-clock-rates = <102000000>,
+ <102000000>,
+ <102000000>,
+ <972000000>;
+
+ clocks = <&tegra_car TEGRA210_CLK_CSI>,
+ <&tegra_car TEGRA210_CLK_CILAB>,
+ <&tegra_car TEGRA210_CLK_CILCD>,
+ <&tegra_car TEGRA210_CLK_CILE>,
+ <&tegra_car TEGRA210_CLK_CSI_TPG>;
+ clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
+ power-domains = <&pd_sor>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml
new file mode 100644
index 000000000000..3bc3b22e98e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-isp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra ISP processor
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ compatible:
+ enum:
+ - nvidia,tegra20-isp
+ - nvidia,tegra30-isp
+ - nvidia,tegra210-isp
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: isp
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ items:
+ - description: memory write client
+
+ interconnect-names:
+ items:
+ - const: dma-mem # write
+
+ power-domains:
+ items:
+ - description: phandle to the VENC or core power domain
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ isp@54100000 {
+ compatible = "nvidia,tegra20-isp";
+ reg = <0x54100000 0x00040000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_ISP>;
+ resets = <&tegra_car 23>;
+ reset-names = "isp";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml
new file mode 100644
index 000000000000..4154ae01ad13
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-mpe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Video Encoder
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^mpe@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra20-mpe
+ - nvidia,tegra30-mpe
+ - nvidia,tegra114-mpe
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: mpe
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ minItems: 6
+ maxItems: 6
+
+ interconnect-names:
+ minItems: 6
+ maxItems: 6
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the MPE power domain
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ mpe@54040000 {
+ compatible = "nvidia,tegra20-mpe";
+ reg = <0x54040000 0x00040000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_MPE>;
+ resets = <&tegra_car 60>;
+ reset-names = "mpe";
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml
new file mode 100644
index 000000000000..467b015e5700
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-tvo.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra TV Encoder Output
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^tvo@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra20-tvo
+ - nvidia,tegra30-tvo
+ - nvidia,tegra114-tvo
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the core power domain
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ tvo@542c0000 {
+ compatible = "nvidia,tegra20-tvo";
+ reg = <0x542c0000 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_TVO>;
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
new file mode 100644
index 000000000000..782a4b10150a
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-vi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Video Input controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^vi@[0-9a-f]+$"
+
+ compatible:
+ oneOf:
+ - const: nvidia,tegra20-vi
+ - const: nvidia,tegra30-vi
+ - const: nvidia,tegra114-vi
+ - const: nvidia,tegra124-vi
+ - items:
+ - const: nvidia,tegra132-vi
+ - const: nvidia,tegra124-vi
+ - const: nvidia,tegra210-vi
+ - const: nvidia,tegra186-vi
+ - const: nvidia,tegra194-vi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ items:
+ - description: module reset
+
+ reset-names:
+ items:
+ - const: vi
+
+ iommus:
+ maxItems: 1
+
+ interconnects:
+ minItems: 4
+ maxItems: 5
+
+ interconnect-names:
+ minItems: 4
+ maxItems: 5
+
+ operating-points-v2:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ power-domains:
+ items:
+ - description: phandle to the VENC power domain
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges:
+ maxItems: 1
+
+ avdd-dsi-csi-supply:
+ description: DSI/CSI power supply. Must supply 1.2 V.
+
+patternProperties:
+ "^csi@[0-9a-f]+$":
+ type: object
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nvidia,tegra20-vi
+ - nvidia,tegra30-vi
+ - nvidia,tegra114-vi
+ - nvidia,tegra124-vi
+ then:
+ required:
+ - resets
+ - reset-names
+ else:
+ required:
+ - power-domains
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra20-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ vi@54080000 {
+ compatible = "nvidia,tegra20-vi";
+ reg = <0x54080000 0x00040000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA20_CLK_VI>;
+ resets = <&tegra_car 100>;
+ reset-names = "vi";
+ };
+
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ vi@54080000 {
+ compatible = "nvidia,tegra210-vi";
+ reg = <0x54080000 0x00000700>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+
+ clocks = <&tegra_car TEGRA210_CLK_VI>;
+ power-domains = <&pd_venc>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x0 0x54080000 0x2000>;
+
+ csi@838 {
+ compatible = "nvidia,tegra210-csi";
+ reg = <0x838 0x1300>;
+ assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
+ <&tegra_car TEGRA210_CLK_CILCD>,
+ <&tegra_car TEGRA210_CLK_CILE>,
+ <&tegra_car TEGRA210_CLK_CSI_TPG>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
+ <&tegra_car TEGRA210_CLK_PLL_P>,
+ <&tegra_car TEGRA210_CLK_PLL_P>;
+ assigned-clock-rates = <102000000>,
+ <102000000>,
+ <102000000>,
+ <972000000>;
+
+ clocks = <&tegra_car TEGRA210_CLK_CSI>,
+ <&tegra_car TEGRA210_CLK_CILAB>,
+ <&tegra_car TEGRA210_CLK_CILCD>,
+ <&tegra_car TEGRA210_CLK_CILE>,
+ <&tegra_car TEGRA210_CLK_CSI_TPG>;
+ clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
+ power-domains = <&pd_sor>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra210-csi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra210-csi.yaml
new file mode 100644
index 000000000000..fa07a40d1004
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra210-csi.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra210-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra CSI controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+properties:
+ $nodename:
+ pattern: "^csi@[0-9a-f]+$"
+
+ compatible:
+ enum:
+ - nvidia,tegra210-csi
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+ - description: A/B lanes clock
+ - description: C/D lanes clock
+ - description: E lane clock
+ - description: test pattern generator clock
+
+ clock-names:
+ items:
+ - const: csi
+ - const: cilab
+ - const: cilcd
+ - const: cile
+ - const: csi_tpg
+
+ power-domains:
+ maxItems: 1
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - power-domains
+
+# see nvidia,tegra20-vi.yaml for an example
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
deleted file mode 100644
index e0e886b73527..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-Device tree binding for NVIDIA Tegra DPAUX pad controller
-========================================================
-
-The Tegra Display Port Auxiliary (DPAUX) pad controller manages two pins
-which can be assigned to either the DPAUX channel or to an I2C
-controller.
-
-This document defines the device-specific binding for the DPAUX pad
-controller. Refer to pinctrl-bindings.txt in this directory for generic
-information about pin controller device tree bindings. Please refer to
-the binding document ../display/tegra/nvidia,tegra20-host1x.txt for more
-details on the DPAUX binding.
-
-Pin muxing:
------------
-
-Child nodes contain the pinmux configurations following the conventions
-from the pinctrl-bindings.txt document.
-
-Since only three configurations are possible, only three child nodes are
-needed to describe the pin mux'ing options for the DPAUX pads.
-Furthermore, given that the pad functions are only applicable to a
-single set of pads, the child nodes only need to describe the pad group
-the functions are being applied to rather than the individual pads.
-
-Required properties:
-- groups: Must be "dpaux-io"
-- function: Must be either "aux", "i2c" or "off".
-
-Example:
---------
-
- dpaux@545c0000 {
- ...
-
- state_dpaux_aux: pinmux-aux {
- groups = "dpaux-io";
- function = "aux";
- };
-
- state_dpaux_i2c: pinmux-i2c {
- groups = "dpaux-io";
- function = "i2c";
- };
-
- state_dpaux_off: pinmux-off {
- groups = "dpaux-io";
- function = "off";
- };
- };
-
- ...
-
- i2c@7000d100 {
- ...
- pinctrl-0 = <&state_dpaux_i2c>;
- pinctrl-1 = <&state_dpaux_off>;
- pinctrl-names = "default", "idle";
- };
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a66d91e02a2..ab50c102177b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6748,7 +6748,7 @@ L: dri-devel@lists.freedesktop.org
L: linux-tegra@vger.kernel.org
S: Supported
T: git git://anongit.freedesktop.org/tegra/linux.git
-F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
F: Documentation/devicetree/bindings/gpu/host1x/
F: drivers/gpu/drm/tegra/
F: drivers/gpu/host1x/
@@ -19682,7 +19682,7 @@ M: Sowjanya Komatineni <skomatineni@nvidia.com>
L: linux-media@vger.kernel.org
L: linux-tegra@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
F: drivers/staging/media/tegra-video/
TEGRA XUSB PADCTL DRIVER
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index a2a731e8a8a3..747abafb6a5c 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/iommu.h>
#include <linux/interconnect.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 4cdc8faf798f..6748ec1e0005 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1381,6 +1381,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra194-sor", },
{ .compatible = "nvidia,tegra194-vic", },
{ .compatible = "nvidia,tegra194-nvdec", },
+ { .compatible = "nvidia,tegra234-vic", },
{ /* sentinel */ }
};
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index fc0a19554eac..845e60f144c7 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -80,6 +80,7 @@ struct tegra_drm_context {
/* Only used by new UAPI. */
struct xarray mappings;
+ struct host1x_memory_context *memory_context;
};
struct tegra_drm_client_ops {
@@ -91,12 +92,22 @@ struct tegra_drm_client_ops {
int (*submit)(struct tegra_drm_context *context,
struct drm_tegra_submit *args, struct drm_device *drm,
struct drm_file *file);
+ int (*get_streamid_offset)(struct tegra_drm_client *client, u32 *offset);
+ int (*can_use_memory_ctx)(struct tegra_drm_client *client, bool *supported);
};
int tegra_drm_submit(struct tegra_drm_context *context,
struct drm_tegra_submit *args, struct drm_device *drm,
struct drm_file *file);
+static inline int
+tegra_drm_get_streamid_offset_thi(struct tegra_drm_client *client, u32 *offset)
+{
+ *offset = 0x30;
+
+ return 0;
+}
+
struct tegra_drm_client {
struct host1x_client base;
struct list_head list;
diff --git a/drivers/gpu/drm/tegra/falcon.c b/drivers/gpu/drm/tegra/falcon.c
index 3762d87759d9..c0d85463eb1a 100644
--- a/drivers/gpu/drm/tegra/falcon.c
+++ b/drivers/gpu/drm/tegra/falcon.c
@@ -48,6 +48,14 @@ static int falcon_copy_chunk(struct falcon *falcon,
if (target == FALCON_MEMORY_IMEM)
cmd |= FALCON_DMATRFCMD_IMEM;
+ /*
+ * Use second DMA context (i.e. the one for firmware). Strictly
+ * speaking, at this point both DMA contexts point to the firmware
+ * stream ID, but this register's value will be reused by the firmware
+ * for later DMA transactions, so we need to use the correct value.
+ */
+ cmd |= FALCON_DMATRFCMD_DMACTX(1);
+
falcon_writel(falcon, offset, FALCON_DMATRFMOFFS);
falcon_writel(falcon, base, FALCON_DMATRFFBOFFS);
falcon_writel(falcon, cmd, FALCON_DMATRFCMD);
diff --git a/drivers/gpu/drm/tegra/falcon.h b/drivers/gpu/drm/tegra/falcon.h
index c56ee32d92ee..1955cf11a8a6 100644
--- a/drivers/gpu/drm/tegra/falcon.h
+++ b/drivers/gpu/drm/tegra/falcon.h
@@ -50,6 +50,7 @@
#define FALCON_DMATRFCMD_IDLE (1 << 1)
#define FALCON_DMATRFCMD_IMEM (1 << 4)
#define FALCON_DMATRFCMD_SIZE_256B (6 << 8)
+#define FALCON_DMATRFCMD_DMACTX(v) (((v) & 0x7) << 12)
#define FALCON_DMATRFFBOFFS 0x0000111c
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 7c7dd84e6db8..81991090adcc 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -704,14 +704,23 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, struct iosys_map *map)
{
struct drm_gem_object *gem = buf->priv;
struct tegra_bo *bo = to_tegra_bo(gem);
+ void *vaddr;
- iosys_map_set_vaddr(map, bo->vaddr);
+ vaddr = tegra_bo_mmap(&bo->base);
+ if (IS_ERR(vaddr))
+ return PTR_ERR(vaddr);
+
+ iosys_map_set_vaddr(map, vaddr);
return 0;
}
static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct iosys_map *map)
{
+ struct drm_gem_object *gem = buf->priv;
+ struct tegra_bo *bo = to_tegra_bo(gem);
+
+ tegra_bo_munmap(&bo->base, map->vaddr);
}
static const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index 61729ea9f0af..b872527a123c 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/of.h>
diff --git a/drivers/gpu/drm/tegra/nvdec.c b/drivers/gpu/drm/tegra/nvdec.c
index 79e1e88203cf..276fe0472730 100644
--- a/drivers/gpu/drm/tegra/nvdec.c
+++ b/drivers/gpu/drm/tegra/nvdec.c
@@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/host1x.h>
#include <linux/iommu.h>
#include <linux/module.h>
@@ -21,6 +22,8 @@
#include "falcon.h"
#include "vic.h"
+#define NVDEC_TFBIF_TRANSCFG 0x2c44
+
struct nvdec_config {
const char *firmware;
unsigned int version;
@@ -63,7 +66,7 @@ static int nvdec_boot(struct nvdec *nvdec)
u32 value;
value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) | TRANSCFG_ATT(0, TRANSCFG_SID_HW);
- nvdec_writel(nvdec, value, VIC_TFBIF_TRANSCFG);
+ nvdec_writel(nvdec, value, NVDEC_TFBIF_TRANSCFG);
if (spec->num_ids > 0) {
value = spec->ids[0] & 0xffff;
@@ -304,10 +307,19 @@ static void nvdec_close_channel(struct tegra_drm_context *context)
host1x_channel_put(context->channel);
}
+static int nvdec_can_use_memory_ctx(struct tegra_drm_client *client, bool *supported)
+{
+ *supported = true;
+
+ return 0;
+}
+
static const struct tegra_drm_client_ops nvdec_ops = {
.open_channel = nvdec_open_channel,
.close_channel = nvdec_close_channel,
.submit = tegra_drm_submit,
+ .get_streamid_offset = tegra_drm_get_streamid_offset_thi,
+ .can_use_memory_ctx = nvdec_can_use_memory_ctx,
};
#define NVIDIA_TEGRA_210_NVDEC_FIRMWARE "nvidia/tegra210/nvdec.bin"
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index d049b211c9b3..ca9f03e3675b 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -3,6 +3,7 @@
* Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
*/
+#include <linux/dma-mapping.h>
#include <linux/iommu.h>
#include <linux/interconnect.h>
diff --git a/drivers/gpu/drm/tegra/submit.c b/drivers/gpu/drm/tegra/submit.c
index 6d6dd8c35475..b24738bdf3df 100644
--- a/drivers/gpu/drm/tegra/submit.c
+++ b/drivers/gpu/drm/tegra/submit.c
@@ -498,6 +498,9 @@ static void release_job(struct host1x_job *job)
struct tegra_drm_submit_data *job_data = job->user_data;
u32 i;
+ if (job->memory_context)
+ host1x_memory_context_put(job->memory_context);
+
for (i = 0; i < job_data->num_used_mappings; i++)
tegra_drm_mapping_put(job_data->used_mappings[i].mapping);
@@ -588,11 +591,51 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
goto put_job;
}
+ if (context->client->ops->get_streamid_offset) {
+ err = context->client->ops->get_streamid_offset(
+ context->client, &job->engine_streamid_offset);
+ if (err) {
+ SUBMIT_ERR(context, "failed to get streamid offset: %d", err);
+ goto unpin_job;
+ }
+ }
+
+ if (context->memory_context && context->client->ops->can_use_memory_ctx) {
+ bool supported;
+
+ err = context->client->ops->can_use_memory_ctx(context->client, &supported);
+ if (err) {
+ SUBMIT_ERR(context, "failed to detect if engine can use memory context: %d", err);
+ goto unpin_job;
+ }
+
+ if (supported) {
+ job->memory_context = context->memory_context;
+ host1x_memory_context_get(job->memory_context);
+ }
+ } else if (context->client->ops->get_streamid_offset) {
+#ifdef CONFIG_IOMMU_API
+ struct iommu_fwspec *spec;
+
+ /*
+ * Job submission will need to temporarily change stream ID,
+ * so need to tell it what to change it back to.
+ */
+ spec = dev_iommu_fwspec_get(context->client->base.dev);
+ if (spec && spec->num_ids > 0)
+ job->engine_fallback_streamid = spec->ids[0] & 0xffff;
+ else
+ job->engine_fallback_streamid = 0x7f;
+#else
+ job->engine_fallback_streamid = 0x7f;
+#endif
+ }
+
/* Boot engine. */
err = pm_runtime_resume_and_get(context->client->base.dev);
if (err < 0) {
SUBMIT_ERR(context, "could not power up engine: %d", err);
- goto unpin_job;
+ goto put_memory_context;
}
job->user_data = job_data;
@@ -627,6 +670,9 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
goto put_job;
+put_memory_context:
+ if (job->memory_context)
+ host1x_memory_context_put(job->memory_context);
unpin_job:
host1x_job_unpin(job);
put_job:
diff --git a/drivers/gpu/drm/tegra/uapi.c b/drivers/gpu/drm/tegra/uapi.c
index 9ab9179d2026..a98239cb0e29 100644
--- a/drivers/gpu/drm/tegra/uapi.c
+++ b/drivers/gpu/drm/tegra/uapi.c
@@ -33,6 +33,9 @@ static void tegra_drm_channel_context_close(struct tegra_drm_context *context)
struct tegra_drm_mapping *mapping;
unsigned long id;
+ if (context->memory_context)
+ host1x_memory_context_put(context->memory_context);
+
xa_for_each(&context->mappings, id, mapping)
tegra_drm_mapping_put(mapping);
@@ -72,6 +75,7 @@ static struct tegra_drm_client *tegra_drm_find_client(struct tegra_drm *tegra, u
int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_file *file)
{
+ struct host1x *host = tegra_drm_to_host1x(drm->dev_private);
struct tegra_drm_file *fpriv = file->driver_priv;
struct tegra_drm *tegra = drm->dev_private;
struct drm_tegra_channel_open *args = data;
@@ -102,10 +106,36 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_
}
}
+ /* Only allocate context if the engine supports context isolation. */
+ if (device_iommu_mapped(client->base.dev) && client->ops->can_use_memory_ctx) {
+ bool supported;
+
+ err = client->ops->can_use_memory_ctx(client, &supported);
+ if (err)
+ goto put_channel;
+
+ if (supported)
+ context->memory_context = host1x_memory_context_alloc(
+ host, get_task_pid(current, PIDTYPE_TGID));
+
+ if (IS_ERR(context->memory_context)) {
+ if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) {
+ err = PTR_ERR(context->memory_context);
+ goto put_channel;
+ } else {
+ /*
+ * OK, HW does not support contexts or contexts
+ * are disabled.
+ */
+ context->memory_context = NULL;
+ }
+ }
+ }
+
err = xa_alloc(&fpriv->contexts, &args->context, context, XA_LIMIT(1, U32_MAX),
GFP_KERNEL);
if (err < 0)
- goto put_channel;
+ goto put_memctx;
context->client = client;
xa_init_flags(&context->mappings, XA_FLAGS_ALLOC1);
@@ -118,6 +148,9 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_
return 0;
+put_memctx:
+ if (context->memory_context)
+ host1x_memory_context_put(context->memory_context);
put_channel:
host1x_channel_put(context->channel);
free:
@@ -156,6 +189,7 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f
struct tegra_drm_mapping *mapping;
struct tegra_drm_context *context;
enum dma_data_direction direction;
+ struct device *mapping_dev;
int err = 0;
if (args->flags & ~DRM_TEGRA_CHANNEL_MAP_READ_WRITE)
@@ -177,6 +211,11 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f
kref_init(&mapping->ref);
+ if (context->memory_context)
+ mapping_dev = &context->memory_context->dev;
+ else
+ mapping_dev = context->client->base.dev;
+
mapping->bo = tegra_gem_lookup(file, args->handle);
if (!mapping->bo) {
err = -EINVAL;
@@ -201,7 +240,7 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f
goto put_gem;
}
- mapping->map = host1x_bo_pin(context->client->base.dev, mapping->bo, direction, NULL);
+ mapping->map = host1x_bo_pin(mapping_dev, mapping->bo, direction, NULL);
if (IS_ERR(mapping->map)) {
err = PTR_ERR(mapping->map);
goto put_gem;
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index f56f5921a8c2..7382ee132eb7 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -38,6 +38,8 @@ struct vic {
struct clk *clk;
struct reset_control *rst;
+ bool can_use_context;
+
/* Platform configuration */
const struct vic_config *config;
};
@@ -229,28 +231,38 @@ static int vic_load_firmware(struct vic *vic)
{
struct host1x_client *client = &vic->client.base;
struct tegra_drm *tegra = vic->client.drm;
+ static DEFINE_MUTEX(lock);
+ u32 fce_bin_data_offset;
dma_addr_t iova;
size_t size;
void *virt;
int err;
- if (vic->falcon.firmware.virt)
- return 0;
+ mutex_lock(&lock);
+
+ if (vic->falcon.firmware.virt) {
+ err = 0;
+ goto unlock;
+ }
err = falcon_read_firmware(&vic->falcon, vic->config->firmware);
if (err < 0)
- return err;
+ goto unlock;
size = vic->falcon.firmware.size;
if (!client->group) {
virt = dma_alloc_coherent(vic->dev, size, &iova, GFP_KERNEL);
- if (!virt)
- return -ENOMEM;
+ if (!virt) {
+ err = -ENOMEM;
+ goto unlock;
+ }
} else {
virt = tegra_drm_alloc(tegra, size, &iova);
- if (IS_ERR(virt))
- return PTR_ERR(virt);
+ if (IS_ERR(virt)) {
+ err = PTR_ERR(virt);
+ goto unlock;
+ }
}
vic->falcon.firmware.virt = virt;
@@ -277,7 +289,28 @@ static int vic_load_firmware(struct vic *vic)
vic->falcon.firmware.phys = phys;
}
- return 0;
+ /*
+ * Check if firmware is new enough to not require mapping firmware
+ * to data buffer domains.
+ */
+ fce_bin_data_offset = *(u32 *)(virt + VIC_UCODE_FCE_DATA_OFFSET);
+
+ if (!vic->config->supports_sid) {
+ vic->can_use_context = false;
+ } else if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
+ /*
+ * Firmware will access FCE through STREAMID0, so context
+ * isolation cannot be used.
+ */
+ vic->can_use_context = false;
+ dev_warn_once(vic->dev, "context isolation disabled due to old firmware\n");
+ } else {
+ vic->can_use_context = true;
+ }
+
+unlock:
+ mutex_unlock(&lock);
+ return err;
cleanup:
if (!client->group)
@@ -285,11 +318,12 @@ cleanup:
else
tegra_drm_free(tegra, size, virt, iova);
+ mutex_unlock(&lock);
return err;
}
-static int vic_runtime_resume(struct device *dev)
+static int __maybe_unused vic_runtime_resume(struct device *dev)
{
struct vic *vic = dev_get_drvdata(dev);
int err;
@@ -323,7 +357,7 @@ disable:
return err;
}
-static int vic_runtime_suspend(struct device *dev)
+static int __maybe_unused vic_runtime_suspend(struct device *dev)
{
struct vic *vic = dev_get_drvdata(dev);
int err;
@@ -358,10 +392,27 @@ static void vic_close_channel(struct tegra_drm_context *context)
host1x_channel_put(context->channel);
}
+static int vic_can_use_memory_ctx(struct tegra_drm_client *client, bool *supported)
+{
+ struct vic *vic = to_vic(client);
+ int err;
+
+ /* This doesn't access HW so it's safe to call without powering up. */
+ err = vic_load_firmware(vic);
+ if (err < 0)
+ return err;
+
+ *supported = vic->can_use_context;
+
+ return 0;
+}
+
static const struct tegra_drm_client_ops vic_ops = {
.open_channel = vic_open_channel,
.close_channel = vic_close_channel,
.submit = tegra_drm_submit,
+ .get_streamid_offset = tegra_drm_get_streamid_offset_thi,
+ .can_use_memory_ctx = vic_can_use_memory_ctx,
};
#define NVIDIA_TEGRA_124_VIC_FIRMWARE "nvidia/tegra124/vic03_ucode.bin"
@@ -396,11 +447,20 @@ static const struct vic_config vic_t194_config = {
.supports_sid = true,
};
+#define NVIDIA_TEGRA_234_VIC_FIRMWARE "nvidia/tegra234/vic.bin"
+
+static const struct vic_config vic_t234_config = {
+ .firmware = NVIDIA_TEGRA_234_VIC_FIRMWARE,
+ .version = 0x23,
+ .supports_sid = true,
+};
+
static const struct of_device_id tegra_vic_of_match[] = {
{ .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config },
{ .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config },
{ .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config },
{ .compatible = "nvidia,tegra194-vic", .data = &vic_t194_config },
+ { .compatible = "nvidia,tegra234-vic", .data = &vic_t234_config },
{ },
};
MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
@@ -409,7 +469,6 @@ static int vic_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct host1x_syncpt **syncpts;
- struct resource *regs;
struct vic *vic;
int err;
@@ -430,13 +489,7 @@ static int vic_probe(struct platform_device *pdev)
if (!syncpts)
return -ENOMEM;
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_err(&pdev->dev, "failed to get registers\n");
- return -ENXIO;
- }
-
- vic->regs = devm_ioremap_resource(dev, regs);
+ vic->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vic->regs))
return PTR_ERR(vic->regs);
@@ -539,3 +592,6 @@ MODULE_FIRMWARE(NVIDIA_TEGRA_186_VIC_FIRMWARE);
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
MODULE_FIRMWARE(NVIDIA_TEGRA_194_VIC_FIRMWARE);
#endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_234_VIC_FIRMWARE);
+#endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index c891a3e33844..ee5286ffe08d 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,7 +15,11 @@ host1x-y = \
hw/host1x04.o \
hw/host1x05.o \
hw/host1x06.o \
- hw/host1x07.o
+ hw/host1x07.o \
+ hw/host1x08.o
+
+host1x-$(CONFIG_IOMMU_API) += \
+ context.o
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
obj-$(CONFIG_TEGRA_HOST1X_CONTEXT_BUS) += context_bus.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 765e5aa64eb6..103fda055394 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -457,9 +457,24 @@ syncpt_incr:
* to offset 0xbad. This does nothing but
* has a easily detected signature in debug
* traces.
+ *
+ * On systems with MLOCK enforcement enabled,
+ * the above 0 word writes would fall foul of
+ * the enforcement. As such, in the first slot
+ * put a RESTART_W opcode to the beginning
+ * of the next job. We don't use this for older
+ * chips since those only support the RESTART
+ * opcode with inconvenient alignment requirements.
*/
- mapped[2*slot+0] = 0x1bad0000;
- mapped[2*slot+1] = 0x1bad0000;
+ if (i == 0 && host1x->info->has_wide_gather) {
+ unsigned int next_job = (job->first_get/8 + job->num_slots)
+ % HOST1X_PUSHBUFFER_SLOTS;
+ mapped[2*slot+0] = (0xd << 28) | (next_job * 2);
+ mapped[2*slot+1] = 0x0;
+ } else {
+ mapped[2*slot+0] = 0x1bad0000;
+ mapped[2*slot+1] = 0x1bad0000;
+ }
}
job->cancelled = true;
@@ -600,8 +615,8 @@ void host1x_cdma_push_wide(struct host1x_cdma *cdma, u32 op1, u32 op2,
struct host1x_channel *channel = cdma_to_channel(cdma);
struct host1x *host1x = cdma_to_host1x(cdma);
struct push_buffer *pb = &cdma->push_buffer;
- unsigned int needed = 2, extra = 0, i;
unsigned int space = cdma->slots_free;
+ unsigned int needed = 2, extra = 0;
if (host1x_debug_trace_cmdbuf)
trace_host1x_cdma_push_wide(dev_name(channel->dev), op1, op2,
@@ -619,20 +634,14 @@ void host1x_cdma_push_wide(struct host1x_cdma *cdma, u32 op1, u32 op2,
cdma->slots_free = space - needed;
cdma->slots_used += needed;
- /*
- * Note that we rely on the fact that this is only used to submit wide
- * gather opcodes, which consist of 3 words, and they are padded with
- * a NOP to avoid having to deal with fractional slots (a slot always
- * represents 2 words). The fourth opcode passed to this function will
- * therefore always be a NOP.
- *
- * This works around a slight ambiguity when it comes to opcodes. For
- * all current host1x incarnations the NOP opcode uses the exact same
- * encoding (0x20000000), so we could hard-code the value here, but a
- * new incarnation may change it and break that assumption.
- */
- for (i = 0; i < extra; i++)
- host1x_pushbuffer_push(pb, op4, op4);
+ if (extra > 0) {
+ /*
+ * If there isn't enough space at the tail of the pushbuffer,
+ * insert a RESTART(0) here to go back to the beginning.
+ * The code above adjusted the indexes appropriately.
+ */
+ host1x_pushbuffer_push(pb, (0x5 << 28), 0xdead0000);
+ }
host1x_pushbuffer_push(pb, op1, op2);
host1x_pushbuffer_push(pb, op3, op4);
diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
index 2a9a3a8d5931..2d0051d6314c 100644
--- a/drivers/gpu/host1x/channel.c
+++ b/drivers/gpu/host1x/channel.c
@@ -21,22 +21,18 @@ int host1x_channel_list_init(struct host1x_channel_list *chlist,
if (!chlist->channels)
return -ENOMEM;
- chlist->allocated_channels =
- kcalloc(BITS_TO_LONGS(num_channels), sizeof(unsigned long),
- GFP_KERNEL);
+ chlist->allocated_channels = bitmap_zalloc(num_channels, GFP_KERNEL);
if (!chlist->allocated_channels) {
kfree(chlist->channels);
return -ENOMEM;
}
- bitmap_zero(chlist->allocated_channels, num_channels);
-
return 0;
}
void host1x_channel_list_free(struct host1x_channel_list *chlist)
{
- kfree(chlist->allocated_channels);
+ bitmap_free(chlist->allocated_channels);
kfree(chlist->channels);
}
diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c
new file mode 100644
index 000000000000..b08cf11f9a66
--- /dev/null
+++ b/drivers/gpu/host1x/context.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, NVIDIA Corporation.
+ */
+
+#include <linux/device.h>
+#include <linux/kref.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pid.h>
+#include <linux/slab.h>
+
+#include "context.h"
+#include "dev.h"
+
+int host1x_memory_context_list_init(struct host1x *host1x)
+{
+ struct host1x_memory_context_list *cdl = &host1x->context_list;
+ struct device_node *node = host1x->dev->of_node;
+ struct host1x_memory_context *ctx;
+ unsigned int i;
+ int err;
+
+ cdl->devs = NULL;
+ cdl->len = 0;
+ mutex_init(&cdl->lock);
+
+ err = of_property_count_u32_elems(node, "iommu-map");
+ if (err < 0)
+ return 0;
+
+ cdl->devs = kcalloc(err, sizeof(*cdl->devs), GFP_KERNEL);
+ if (!cdl->devs)
+ return -ENOMEM;
+ cdl->len = err / 4;
+
+ for (i = 0; i < cdl->len; i++) {
+ struct iommu_fwspec *fwspec;
+
+ ctx = &cdl->devs[i];
+
+ ctx->host = host1x;
+
+ device_initialize(&ctx->dev);
+
+ /*
+ * Due to an issue with T194 NVENC, only 38 bits can be used.
+ * Anyway, 256GiB of IOVA ought to be enough for anyone.
+ */
+ ctx->dma_mask = DMA_BIT_MASK(38);
+ ctx->dev.dma_mask = &ctx->dma_mask;
+ ctx->dev.coherent_dma_mask = ctx->dma_mask;
+ dev_set_name(&ctx->dev, "host1x-ctx.%d", i);
+ ctx->dev.bus = &host1x_context_device_bus_type;
+ ctx->dev.parent = host1x->dev;
+
+ dma_set_max_seg_size(&ctx->dev, UINT_MAX);
+
+ err = device_add(&ctx->dev);
+ if (err) {
+ dev_err(host1x->dev, "could not add context device %d: %d\n", i, err);
+ goto del_devices;
+ }
+
+ err = of_dma_configure_id(&ctx->dev, node, true, &i);
+ if (err) {
+ dev_err(host1x->dev, "IOMMU configuration failed for context device %d: %d\n",
+ i, err);
+ device_del(&ctx->dev);
+ goto del_devices;
+ }
+
+ fwspec = dev_iommu_fwspec_get(&ctx->dev);
+ if (!fwspec || !device_iommu_mapped(&ctx->dev)) {
+ dev_err(host1x->dev, "Context device %d has no IOMMU!\n", i);
+ device_del(&ctx->dev);
+ goto del_devices;
+ }
+
+ ctx->stream_id = fwspec->ids[0] & 0xffff;
+ }
+
+ return 0;
+
+del_devices:
+ while (i--)
+ device_del(&cdl->devs[i].dev);
+
+ kfree(cdl->devs);
+ cdl->len = 0;
+
+ return err;
+}
+
+void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
+{
+ unsigned int i;
+
+ for (i = 0; i < cdl->len; i++)
+ device_del(&cdl->devs[i].dev);
+
+ kfree(cdl->devs);
+ cdl->len = 0;
+}
+
+struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+ struct pid *pid)
+{
+ struct host1x_memory_context_list *cdl = &host1x->context_list;
+ struct host1x_memory_context *free = NULL;
+ int i;
+
+ if (!cdl->len)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ mutex_lock(&cdl->lock);
+
+ for (i = 0; i < cdl->len; i++) {
+ struct host1x_memory_context *cd = &cdl->devs[i];
+
+ if (cd->owner == pid) {
+ refcount_inc(&cd->ref);
+ mutex_unlock(&cdl->lock);
+ return cd;
+ } else if (!cd->owner && !free) {
+ free = cd;
+ }
+ }
+
+ if (!free) {
+ mutex_unlock(&cdl->lock);
+ return ERR_PTR(-EBUSY);
+ }
+
+ refcount_set(&free->ref, 1);
+ free->owner = get_pid(pid);
+
+ mutex_unlock(&cdl->lock);
+
+ return free;
+}
+EXPORT_SYMBOL_GPL(host1x_memory_context_alloc);
+
+void host1x_memory_context_get(struct host1x_memory_context *cd)
+{
+ refcount_inc(&cd->ref);
+}
+EXPORT_SYMBOL_GPL(host1x_memory_context_get);
+
+void host1x_memory_context_put(struct host1x_memory_context *cd)
+{
+ struct host1x_memory_context_list *cdl = &cd->host->context_list;
+
+ if (refcount_dec_and_mutex_lock(&cd->ref, &cdl->lock)) {
+ put_pid(cd->owner);
+ cd->owner = NULL;
+ mutex_unlock(&cdl->lock);
+ }
+}
+EXPORT_SYMBOL_GPL(host1x_memory_context_put);
diff --git a/drivers/gpu/host1x/context.h b/drivers/gpu/host1x/context.h
new file mode 100644
index 000000000000..3e03bc1d3bac
--- /dev/null
+++ b/drivers/gpu/host1x/context.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Host1x context devices
+ *
+ * Copyright (c) 2020, NVIDIA Corporation.
+ */
+
+#ifndef __HOST1X_CONTEXT_H
+#define __HOST1X_CONTEXT_H
+
+#include <linux/mutex.h>
+#include <linux/refcount.h>
+
+struct host1x;
+
+extern struct bus_type host1x_context_device_bus_type;
+
+struct host1x_memory_context_list {
+ struct mutex lock;
+ struct host1x_memory_context *devs;
+ unsigned int len;
+};
+
+#ifdef CONFIG_IOMMU_API
+int host1x_memory_context_list_init(struct host1x *host1x);
+void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl);
+#else
+static inline int host1x_memory_context_list_init(struct host1x *host1x)
+{
+ return 0;
+}
+
+static inline void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/host1x/context_bus.c b/drivers/gpu/host1x/context_bus.c
index b0d35b2bbe89..d9421179d7b4 100644
--- a/drivers/gpu/host1x/context_bus.c
+++ b/drivers/gpu/host1x/context_bus.c
@@ -15,11 +15,6 @@ static int __init host1x_context_device_bus_init(void)
{
int err;
- if (!of_machine_is_compatible("nvidia,tegra186") &&
- !of_machine_is_compatible("nvidia,tegra194") &&
- !of_machine_is_compatible("nvidia,tegra234"))
- return 0;
-
err = bus_register(&host1x_context_device_bus_type);
if (err < 0) {
pr_err("bus type registration failed: %d\n", err);
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 80c685ab3e30..0cd3f97e7e49 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
#include "bus.h"
#include "channel.h"
+#include "context.h"
#include "debug.h"
#include "dev.h"
#include "intr.h"
@@ -38,6 +39,12 @@
#include "hw/host1x05.h"
#include "hw/host1x06.h"
#include "hw/host1x07.h"
+#include "hw/host1x08.h"
+
+void host1x_common_writel(struct host1x *host1x, u32 v, u32 r)
+{
+ writel(v, host1x->common_regs + r);
+}
void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r)
{
@@ -199,7 +206,48 @@ static const struct host1x_info host1x07_info = {
.reserve_vblank_syncpts = false,
};
+/*
+ * Tegra234 has two stream ID protection tables, one for setting stream IDs
+ * through the channel path via SETSTREAMID, and one for setting them via
+ * MMIO. We program each engine's data stream ID in the channel path table
+ * and firmware stream ID in the MMIO path table.
+ */
+static const struct host1x_sid_entry tegra234_sid_table[] = {
+ {
+ /* VIC channel */
+ .base = 0x17b8,
+ .offset = 0x30,
+ .limit = 0x30
+ },
+ {
+ /* VIC MMIO */
+ .base = 0x1688,
+ .offset = 0x34,
+ .limit = 0x34
+ },
+};
+
+static const struct host1x_info host1x08_info = {
+ .nb_channels = 63,
+ .nb_pts = 1024,
+ .nb_mlocks = 24,
+ .nb_bases = 0,
+ .init = host1x08_init,
+ .sync_offset = 0x0,
+ .dma_mask = DMA_BIT_MASK(40),
+ .has_wide_gather = true,
+ .has_hypervisor = true,
+ .has_common = true,
+ .num_sid_entries = ARRAY_SIZE(tegra234_sid_table),
+ .sid_table = tegra234_sid_table,
+ .streamid_vm_table = { 0x1004, 128 },
+ .classid_vm_table = { 0x1404, 25 },
+ .mmio_vm_table = { 0x1504, 25 },
+ .reserve_vblank_syncpts = false,
+};
+
static const struct of_device_id host1x_of_match[] = {
+ { .compatible = "nvidia,tegra234-host1x", .data = &host1x08_info, },
{ .compatible = "nvidia,tegra194-host1x", .data = &host1x07_info, },
{ .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, },
{ .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
@@ -211,7 +259,7 @@ static const struct of_device_id host1x_of_match[] = {
};
MODULE_DEVICE_TABLE(of, host1x_of_match);
-static void host1x_setup_sid_table(struct host1x *host)
+static void host1x_setup_virtualization_tables(struct host1x *host)
{
const struct host1x_info *info = host->info;
unsigned int i;
@@ -225,6 +273,21 @@ static void host1x_setup_sid_table(struct host1x *host)
host1x_hypervisor_writel(host, entry->offset, entry->base);
host1x_hypervisor_writel(host, entry->limit, entry->base + 4);
}
+
+ for (i = 0; i < info->streamid_vm_table.count; i++) {
+ /* Allow access to all stream IDs to all VMs. */
+ host1x_hypervisor_writel(host, 0xff, info->streamid_vm_table.base + 4 * i);
+ }
+
+ for (i = 0; i < info->classid_vm_table.count; i++) {
+ /* Allow access to all classes to all VMs. */
+ host1x_hypervisor_writel(host, 0xff, info->classid_vm_table.base + 4 * i);
+ }
+
+ for (i = 0; i < info->mmio_vm_table.count; i++) {
+ /* Use VM1 (that's us) as originator VMID for engine MMIO accesses. */
+ host1x_hypervisor_writel(host, 0x1, info->mmio_vm_table.base + 4 * i);
+ }
}
static bool host1x_wants_iommu(struct host1x *host1x)
@@ -402,16 +465,12 @@ static int host1x_get_resets(struct host1x *host)
return err;
}
- if (WARN_ON(!host->resets[1].rstc))
- return -ENOENT;
-
return 0;
}
static int host1x_probe(struct platform_device *pdev)
{
struct host1x *host;
- struct resource *regs, *hv_regs = NULL;
int syncpt_irq;
int err;
@@ -422,25 +481,23 @@ static int host1x_probe(struct platform_device *pdev)
host->info = of_device_get_match_data(&pdev->dev);
if (host->info->has_hypervisor) {
- regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm");
- if (!regs) {
- dev_err(&pdev->dev, "failed to get vm registers\n");
- return -ENXIO;
- }
+ host->regs = devm_platform_ioremap_resource_byname(pdev, "vm");
+ if (IS_ERR(host->regs))
+ return PTR_ERR(host->regs);
+
+ host->hv_regs = devm_platform_ioremap_resource_byname(pdev, "hypervisor");
+ if (IS_ERR(host->hv_regs))
+ return PTR_ERR(host->hv_regs);
- hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "hypervisor");
- if (!hv_regs) {
- dev_err(&pdev->dev,
- "failed to get hypervisor registers\n");
- return -ENXIO;
+ if (host->info->has_common) {
+ host->common_regs = devm_platform_ioremap_resource_byname(pdev, "common");
+ if (IS_ERR(host->common_regs))
+ return PTR_ERR(host->common_regs);
}
} else {
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_err(&pdev->dev, "failed to get registers\n");
- return -ENXIO;
- }
+ host->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(host->regs))
+ return PTR_ERR(host->regs);
}
syncpt_irq = platform_get_irq(pdev, 0);
@@ -455,16 +512,6 @@ static int host1x_probe(struct platform_device *pdev)
/* set common host1x device data */
platform_set_drvdata(pdev, host);
- host->regs = devm_ioremap_resource(&pdev->dev, regs);
- if (IS_ERR(host->regs))
- return PTR_ERR(host->regs);
-
- if (host->info->has_hypervisor) {
- host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs);
- if (IS_ERR(host->hv_regs))
- return PTR_ERR(host->hv_regs);
- }
-
host->dev->dma_parms = &host->dma_parms;
dma_set_max_seg_size(host->dev, UINT_MAX);
@@ -503,10 +550,16 @@ static int host1x_probe(struct platform_device *pdev)
goto iommu_exit;
}
+ err = host1x_memory_context_list_init(host);
+ if (err) {
+ dev_err(&pdev->dev, "failed to initialize context list\n");
+ goto free_channels;
+ }
+
err = host1x_syncpt_init(host);
if (err) {
dev_err(&pdev->dev, "failed to initialize syncpts\n");
- goto free_channels;
+ goto free_contexts;
}
err = host1x_intr_init(host, syncpt_irq);
@@ -550,6 +603,8 @@ pm_disable:
host1x_intr_deinit(host);
deinit_syncpt:
host1x_syncpt_deinit(host);
+free_contexts:
+ host1x_memory_context_list_free(&host->context_list);
free_channels:
host1x_channel_list_free(&host->channel_list);
iommu_exit:
@@ -571,6 +626,7 @@ static int host1x_remove(struct platform_device *pdev)
host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
+ host1x_memory_context_list_free(&host->context_list);
host1x_channel_list_free(&host->channel_list);
host1x_iommu_exit(host);
host1x_bo_cache_destroy(&host->cache);
@@ -600,7 +656,7 @@ static int __maybe_unused host1x_runtime_suspend(struct device *dev)
return 0;
resume_host1x:
- host1x_setup_sid_table(host);
+ host1x_setup_virtualization_tables(host);
host1x_syncpt_restore(host);
host1x_intr_start(host);
@@ -630,7 +686,7 @@ static int __maybe_unused host1x_runtime_resume(struct device *dev)
goto disable_clk;
}
- host1x_setup_sid_table(host);
+ host1x_setup_virtualization_tables(host);
host1x_syncpt_restore(host);
host1x_intr_start(host);
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index ca4b082f0cd4..920e5548cfbc 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -14,6 +14,7 @@
#include "cdma.h"
#include "channel.h"
+#include "context.h"
#include "intr.h"
#include "job.h"
#include "syncpt.h"
@@ -89,6 +90,11 @@ struct host1x_sid_entry {
unsigned int limit;
};
+struct host1x_table_desc {
+ unsigned int base;
+ unsigned int count;
+};
+
struct host1x_info {
unsigned int nb_channels; /* host1x: number of channels supported */
unsigned int nb_pts; /* host1x: number of syncpoints supported */
@@ -99,8 +105,12 @@ struct host1x_info {
u64 dma_mask; /* mask of addressable memory */
bool has_wide_gather; /* supports GATHER_W opcode */
bool has_hypervisor; /* has hypervisor registers */
+ bool has_common; /* has common registers separate from hypervisor */
unsigned int num_sid_entries;
const struct host1x_sid_entry *sid_table;
+ struct host1x_table_desc streamid_vm_table;
+ struct host1x_table_desc classid_vm_table;
+ struct host1x_table_desc mmio_vm_table;
/*
* On T20-T148, the boot chain may setup DC to increment syncpoints
* 26/27 on VBLANK. As such we cannot use these syncpoints until
@@ -114,6 +124,7 @@ struct host1x {
void __iomem *regs;
void __iomem *hv_regs; /* hypervisor region */
+ void __iomem *common_regs;
struct host1x_syncpt *syncpt;
struct host1x_syncpt_base *bases;
struct device *dev;
@@ -141,6 +152,7 @@ struct host1x {
struct mutex syncpt_mutex;
struct host1x_channel_list channel_list;
+ struct host1x_memory_context_list context_list;
struct dentry *debugfs;
@@ -154,6 +166,7 @@ struct host1x {
struct host1x_bo_cache cache;
};
+void host1x_common_writel(struct host1x *host1x, u32 v, u32 r);
void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v);
u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r);
void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index e49cd5b8f735..1b65a10b9dfc 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -238,6 +238,37 @@ static void cdma_resume(struct host1x_cdma *cdma, u32 getptr)
cdma_timeout_restart(cdma, getptr);
}
+static void timeout_release_mlock(struct host1x_cdma *cdma)
+{
+#if HOST1X_HW >= 8
+ /* Tegra186 and Tegra194 require a more complicated MLOCK release
+ * sequence. Furthermore, those chips by default don't enforce MLOCKs,
+ * so it turns out that if we don't /actually/ need MLOCKs, we can just
+ * ignore them.
+ *
+ * As such, for now just implement this on Tegra234 where things are
+ * stricter but also easy to implement.
+ */
+ struct host1x_channel *ch = cdma_to_channel(cdma);
+ struct host1x *host1x = cdma_to_host1x(cdma);
+ u32 offset;
+
+ switch (ch->client->class) {
+ case HOST1X_CLASS_VIC:
+ offset = HOST1X_COMMON_VIC_MLOCK;
+ break;
+ case HOST1X_CLASS_NVDEC:
+ offset = HOST1X_COMMON_NVDEC_MLOCK;
+ break;
+ default:
+ WARN(1, "%s was not updated for class %u", __func__, ch->client->class);
+ return;
+ }
+
+ host1x_common_writel(host1x, 0x0, offset);
+#endif
+}
+
/*
* If this timeout fires, it indicates the current sync_queue entry has
* exceeded its TTL and the userctx should be timed out and remaining
@@ -288,6 +319,9 @@ static void cdma_timeout_handler(struct work_struct *work)
/* stop HW, resetting channel/module */
host1x_hw_cdma_freeze(host1x, cdma);
+ /* release any held MLOCK */
+ timeout_release_mlock(cdma);
+
host1x_cdma_update_sync_queue(cdma, ch->dev);
mutex_unlock(&cdma->lock);
}
diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c
index 6b40e9af1e88..732abe0750ff 100644
--- a/drivers/gpu/host1x/hw/channel_hw.c
+++ b/drivers/gpu/host1x/hw/channel_hw.c
@@ -47,10 +47,41 @@ static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo,
}
}
-static void submit_wait(struct host1x_cdma *cdma, u32 id, u32 threshold,
+static void submit_wait(struct host1x_job *job, u32 id, u32 threshold,
u32 next_class)
{
-#if HOST1X_HW >= 2
+ struct host1x_cdma *cdma = &job->channel->cdma;
+
+#if HOST1X_HW >= 6
+ u32 stream_id;
+
+ /*
+ * If a memory context has been set, use it. Otherwise
+ * (if context isolation is disabled) use the engine's
+ * firmware stream ID.
+ */
+ if (job->memory_context)
+ stream_id = job->memory_context->stream_id;
+ else
+ stream_id = job->engine_fallback_streamid;
+
+ host1x_cdma_push_wide(cdma,
+ host1x_opcode_setclass(
+ HOST1X_CLASS_HOST1X,
+ HOST1X_UCLASS_LOAD_SYNCPT_PAYLOAD_32,
+ /* WAIT_SYNCPT_32 is at SYNCPT_PAYLOAD_32+2 */
+ BIT(0) | BIT(2)
+ ),
+ threshold,
+ id,
+ HOST1X_OPCODE_NOP
+ );
+ host1x_cdma_push_wide(&job->channel->cdma,
+ host1x_opcode_setclass(job->class, 0, 0),
+ host1x_opcode_setpayload(stream_id),
+ host1x_opcode_setstreamid(job->engine_streamid_offset / 4),
+ HOST1X_OPCODE_NOP);
+#elif HOST1X_HW >= 2
host1x_cdma_push_wide(cdma,
host1x_opcode_setclass(
HOST1X_CLASS_HOST1X,
@@ -97,7 +128,7 @@ static void submit_gathers(struct host1x_job *job, u32 job_syncpt_base)
else
threshold = cmd->wait.threshold;
- submit_wait(cdma, cmd->wait.id, threshold, cmd->wait.next_class);
+ submit_wait(job, cmd->wait.id, threshold, cmd->wait.next_class);
} else {
struct host1x_job_gather *g = &cmd->gather;
@@ -180,11 +211,77 @@ static void host1x_enable_gather_filter(struct host1x_channel *ch)
#endif
}
+static void channel_program_cdma(struct host1x_job *job)
+{
+ struct host1x_cdma *cdma = &job->channel->cdma;
+ struct host1x_syncpt *sp = job->syncpt;
+
+#if HOST1X_HW >= 6
+ u32 fence;
+
+ /* Enter engine class with invalid stream ID. */
+ host1x_cdma_push_wide(cdma,
+ host1x_opcode_acquire_mlock(job->class),
+ host1x_opcode_setclass(job->class, 0, 0),
+ host1x_opcode_setpayload(0),
+ host1x_opcode_setstreamid(job->engine_streamid_offset / 4));
+
+ /* Before switching stream ID to real stream ID, ensure engine is idle. */
+ fence = host1x_syncpt_incr_max(sp, 1);
+ host1x_cdma_push(&job->channel->cdma,
+ host1x_opcode_nonincr(HOST1X_UCLASS_INCR_SYNCPT, 1),
+ HOST1X_UCLASS_INCR_SYNCPT_INDX_F(job->syncpt->id) |
+ HOST1X_UCLASS_INCR_SYNCPT_COND_F(4));
+ submit_wait(job, job->syncpt->id, fence, job->class);
+
+ /* Submit work. */
+ job->syncpt_end = host1x_syncpt_incr_max(sp, job->syncpt_incrs);
+ submit_gathers(job, job->syncpt_end - job->syncpt_incrs);
+
+ /* Before releasing MLOCK, ensure engine is idle again. */
+ fence = host1x_syncpt_incr_max(sp, 1);
+ host1x_cdma_push(&job->channel->cdma,
+ host1x_opcode_nonincr(HOST1X_UCLASS_INCR_SYNCPT, 1),
+ HOST1X_UCLASS_INCR_SYNCPT_INDX_F(job->syncpt->id) |
+ HOST1X_UCLASS_INCR_SYNCPT_COND_F(4));
+ submit_wait(job, job->syncpt->id, fence, job->class);
+
+ /* Release MLOCK. */
+ host1x_cdma_push(cdma,
+ HOST1X_OPCODE_NOP, host1x_opcode_release_mlock(job->class));
+#else
+ if (job->serialize) {
+ /*
+ * Force serialization by inserting a host wait for the
+ * previous job to finish before this one can commence.
+ */
+ host1x_cdma_push(cdma,
+ host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
+ host1x_uclass_wait_syncpt_r(), 1),
+ host1x_class_host_wait_syncpt(job->syncpt->id,
+ host1x_syncpt_read_max(sp)));
+ }
+
+ /* Synchronize base register to allow using it for relative waiting */
+ if (sp->base)
+ synchronize_syncpt_base(job);
+
+ /* add a setclass for modules that require it */
+ if (job->class)
+ host1x_cdma_push(cdma,
+ host1x_opcode_setclass(job->class, 0, 0),
+ HOST1X_OPCODE_NOP);
+
+ job->syncpt_end = host1x_syncpt_incr_max(sp, job->syncpt_incrs);
+
+ submit_gathers(job, job->syncpt_end - job->syncpt_incrs);
+#endif
+}
+
static int channel_submit(struct host1x_job *job)
{
struct host1x_channel *ch = job->channel;
struct host1x_syncpt *sp = job->syncpt;
- u32 user_syncpt_incrs = job->syncpt_incrs;
u32 prev_max = 0;
u32 syncval;
int err;
@@ -212,6 +309,7 @@ static int channel_submit(struct host1x_job *job)
host1x_channel_set_streamid(ch);
host1x_enable_gather_filter(ch);
+ host1x_hw_syncpt_assign_to_channel(host, sp, ch);
/* begin a CDMA submit */
err = host1x_cdma_begin(&ch->cdma, job);
@@ -220,35 +318,8 @@ static int channel_submit(struct host1x_job *job)
goto error;
}
- if (job->serialize) {
- /*
- * Force serialization by inserting a host wait for the
- * previous job to finish before this one can commence.
- */
- host1x_cdma_push(&ch->cdma,
- host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
- host1x_uclass_wait_syncpt_r(), 1),
- host1x_class_host_wait_syncpt(job->syncpt->id,
- host1x_syncpt_read_max(sp)));
- }
-
- /* Synchronize base register to allow using it for relative waiting */
- if (sp->base)
- synchronize_syncpt_base(job);
-
- syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs);
-
- host1x_hw_syncpt_assign_to_channel(host, sp, ch);
-
- job->syncpt_end = syncval;
-
- /* add a setclass for modules that require it */
- if (job->class)
- host1x_cdma_push(&ch->cdma,
- host1x_opcode_setclass(job->class, 0, 0),
- HOST1X_OPCODE_NOP);
-
- submit_gathers(job, syncval - user_syncpt_incrs);
+ channel_program_cdma(job);
+ syncval = host1x_syncpt_read_max(sp);
/* end CDMA submit & stash pinned hMems into sync queue */
host1x_cdma_end(&ch->cdma, job);
diff --git a/drivers/gpu/host1x/hw/host1x01_hardware.h b/drivers/gpu/host1x/hw/host1x01_hardware.h
index fe59df1d3dc3..cb93d7c1808c 100644
--- a/drivers/gpu/host1x/hw/host1x01_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x01_hardware.h
@@ -15,118 +15,6 @@
#include "hw_host1x01_sync.h"
#include "hw_host1x01_uclass.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x02_hardware.h b/drivers/gpu/host1x/hw/host1x02_hardware.h
index af60d7fb016d..2d1282b9bc33 100644
--- a/drivers/gpu/host1x/hw/host1x02_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x02_hardware.h
@@ -15,117 +15,6 @@
#include "hw_host1x02_sync.h"
#include "hw_host1x02_uclass.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x04_hardware.h b/drivers/gpu/host1x/hw/host1x04_hardware.h
index 4f9bcddf27e3..84d244e8af30 100644
--- a/drivers/gpu/host1x/hw/host1x04_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x04_hardware.h
@@ -15,117 +15,6 @@
#include "hw_host1x04_sync.h"
#include "hw_host1x04_uclass.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x05_hardware.h b/drivers/gpu/host1x/hw/host1x05_hardware.h
index af3ab4b7f010..1dcde6ec7909 100644
--- a/drivers/gpu/host1x/hw/host1x05_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x05_hardware.h
@@ -15,117 +15,6 @@
#include "hw_host1x05_sync.h"
#include "hw_host1x05_uclass.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x06_hardware.h b/drivers/gpu/host1x/hw/host1x06_hardware.h
index 01a142a09800..c05cfa7e3090 100644
--- a/drivers/gpu/host1x/hw/host1x06_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x06_hardware.h
@@ -16,122 +16,6 @@
#include "hw_host1x06_vm.h"
#include "hw_host1x06_hypervisor.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-static inline u32 host1x_opcode_gather_wide(unsigned count)
-{
- return (12 << 28) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x07_hardware.h b/drivers/gpu/host1x/hw/host1x07_hardware.h
index e6582172ebfd..d67364e03956 100644
--- a/drivers/gpu/host1x/hw/host1x07_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x07_hardware.h
@@ -16,122 +16,6 @@
#include "hw_host1x07_vm.h"
#include "hw_host1x07_hypervisor.h"
-static inline u32 host1x_class_host_wait_syncpt(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_wait_syncpt_indx_f(indx)
- | host1x_uclass_wait_syncpt_thresh_f(threshold);
-}
-
-static inline u32 host1x_class_host_load_syncpt_base(
- unsigned indx, unsigned threshold)
-{
- return host1x_uclass_load_syncpt_base_base_indx_f(indx)
- | host1x_uclass_load_syncpt_base_value_f(threshold);
-}
-
-static inline u32 host1x_class_host_wait_syncpt_base(
- unsigned indx, unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_wait_syncpt_base_indx_f(indx)
- | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_wait_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt_base(
- unsigned base_indx, unsigned offset)
-{
- return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
- | host1x_uclass_incr_syncpt_base_offset_f(offset);
-}
-
-static inline u32 host1x_class_host_incr_syncpt(
- unsigned cond, unsigned indx)
-{
- return host1x_uclass_incr_syncpt_cond_f(cond)
- | host1x_uclass_incr_syncpt_indx_f(indx);
-}
-
-static inline u32 host1x_class_host_indoff_reg_write(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indbe_f(0xf)
- | host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset);
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-static inline u32 host1x_class_host_indoff_reg_read(
- unsigned mod_id, unsigned offset, bool auto_inc)
-{
- u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
- | host1x_uclass_indoff_indroffset_f(offset)
- | host1x_uclass_indoff_rwn_read_v();
- if (auto_inc)
- v |= host1x_uclass_indoff_autoinc_f(1);
- return v;
-}
-
-/* cdma opcodes */
-static inline u32 host1x_opcode_setclass(
- unsigned class_id, unsigned offset, unsigned mask)
-{
- return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
-}
-
-static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
-{
- return (1 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
-{
- return (2 << 28) | (offset << 16) | count;
-}
-
-static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
-{
- return (3 << 28) | (offset << 16) | mask;
-}
-
-static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
-{
- return (4 << 28) | (offset << 16) | value;
-}
-
-static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
-{
- return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
- host1x_class_host_incr_syncpt(cond, indx));
-}
-
-static inline u32 host1x_opcode_restart(unsigned address)
-{
- return (5 << 28) | (address >> 4);
-}
-
-static inline u32 host1x_opcode_gather(unsigned count)
-{
- return (6 << 28) | count;
-}
-
-static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | count;
-}
-
-static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
-{
- return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
-}
-
-static inline u32 host1x_opcode_gather_wide(unsigned count)
-{
- return (12 << 28) | count;
-}
-
-#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+#include "opcodes.h"
#endif
diff --git a/drivers/gpu/host1x/hw/host1x08.c b/drivers/gpu/host1x/hw/host1x08.c
new file mode 100644
index 000000000000..754890c34c74
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x08.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Host1x init for Tegra234 SoCs
+ *
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+/* include hw specification */
+#include "host1x08.h"
+#include "host1x08_hardware.h"
+
+/* include code */
+#define HOST1X_HW 8
+
+#include "cdma_hw.c"
+#include "channel_hw.c"
+#include "debug_hw.c"
+#include "intr_hw.c"
+#include "syncpt_hw.c"
+
+#include "../dev.h"
+
+int host1x08_init(struct host1x *host)
+{
+ host->channel_op = &host1x_channel_ops;
+ host->cdma_op = &host1x_cdma_ops;
+ host->cdma_pb_op = &host1x_pushbuffer_ops;
+ host->syncpt_op = &host1x_syncpt_ops;
+ host->intr_op = &host1x_intr_ops;
+ host->debug_op = &host1x_debug_ops;
+
+ return 0;
+}
diff --git a/drivers/gpu/host1x/hw/host1x08.h b/drivers/gpu/host1x/hw/host1x08.h
new file mode 100644
index 000000000000..a6bad56e44cf
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x08.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Host1x init for Tegra234 SoCs
+ *
+ * Copyright (c) 2018 NVIDIA Corporation.
+ */
+
+#ifndef HOST1X_HOST1X08_H
+#define HOST1X_HOST1X08_H
+
+struct host1x;
+
+int host1x08_init(struct host1x *host);
+
+#endif
diff --git a/drivers/gpu/host1x/hw/host1x08_hardware.h b/drivers/gpu/host1x/hw/host1x08_hardware.h
new file mode 100644
index 000000000000..936243060bff
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x08_hardware.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Tegra host1x Register Offsets for Tegra234
+ *
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#ifndef __HOST1X_HOST1X08_HARDWARE_H
+#define __HOST1X_HOST1X08_HARDWARE_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#include "hw_host1x08_uclass.h"
+#include "hw_host1x08_vm.h"
+#include "hw_host1x08_hypervisor.h"
+#include "hw_host1x08_common.h"
+
+#include "opcodes.h"
+
+#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x08_channel.h b/drivers/gpu/host1x/hw/hw_host1x08_channel.h
new file mode 100644
index 000000000000..c9272d2ab14a
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x08_channel.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#ifndef HOST1X_HW_HOST1X08_CHANNEL_H
+#define HOST1X_HW_HOST1X08_CHANNEL_H
+
+#define HOST1X_CHANNEL_SMMU_STREAMID 0x084
+
+#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x08_common.h b/drivers/gpu/host1x/hw/hw_host1x08_common.h
new file mode 100644
index 000000000000..8e0c99150ec2
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x08_common.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#define HOST1X_COMMON_OFA_MLOCK 0x4050
+#define HOST1X_COMMON_NVJPG1_MLOCK 0x4070
+#define HOST1X_COMMON_VIC_MLOCK 0x4078
+#define HOST1X_COMMON_NVENC_MLOCK 0x407c
+#define HOST1X_COMMON_NVDEC_MLOCK 0x4080
+#define HOST1X_COMMON_NVJPG_MLOCK 0x4084
diff --git a/drivers/gpu/host1x/hw/hw_host1x08_hypervisor.h b/drivers/gpu/host1x/hw/hw_host1x08_hypervisor.h
new file mode 100644
index 000000000000..22964324c914
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x08_hypervisor.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#define HOST1X_HV_SYNCPT_PROT_EN 0x1724
+#define HOST1X_HV_SYNCPT_PROT_EN_CH_EN BIT(1)
+#define HOST1X_HV_CH_MLOCK_EN(x) (0x1700 + (x * 4))
+#define HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(x) (0x1710 + (x * 4))
diff --git a/drivers/gpu/host1x/hw/hw_host1x08_uclass.h b/drivers/gpu/host1x/hw/hw_host1x08_uclass.h
new file mode 100644
index 000000000000..724cccd71aa1
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x08_uclass.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2018 NVIDIA Corporation.
+ */
+
+ /*
+ * Function naming determines intended use:
+ *
+ * <x>_r(void) : Returns the offset for register <x>.
+ *
+ * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
+ *
+ * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
+ *
+ * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
+ * and masked to place it at field <y> of register <x>. This value
+ * can be |'d with others to produce a full register value for
+ * register <x>.
+ *
+ * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
+ * value can be ~'d and then &'d to clear the value of field <y> for
+ * register <x>.
+ *
+ * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
+ * to place it at field <y> of register <x>. This value can be |'d
+ * with others to produce a full register value for <x>.
+ *
+ * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
+ * <x> value 'r' after being shifted to place its LSB at bit 0.
+ * This value is suitable for direct comparison with other unshifted
+ * values appropriate for use in field <y> of register <x>.
+ *
+ * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
+ * field <y> of register <x>. This value is suitable for direct
+ * comparison with unshifted values appropriate for use in field <y>
+ * of register <x>.
+ */
+
+#ifndef HOST1X_HW_HOST1X08_UCLASS_H
+#define HOST1X_HW_HOST1X08_UCLASS_H
+
+static inline u32 host1x_uclass_incr_syncpt_r(void)
+{
+ return 0x0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT \
+ host1x_uclass_incr_syncpt_r()
+static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
+{
+ return (v & 0xff) << 10;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
+ host1x_uclass_incr_syncpt_cond_f(v)
+static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
+{
+ return (v & 0xff) << 0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
+ host1x_uclass_incr_syncpt_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_r(void)
+{
+ return 0x8;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT \
+ host1x_uclass_wait_syncpt_r()
+static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
+{
+ return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
+ host1x_uclass_wait_syncpt_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
+{
+ return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
+ host1x_uclass_wait_syncpt_thresh_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_r(void)
+{
+ return 0x9;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
+ host1x_uclass_wait_syncpt_base_r()
+static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
+{
+ return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
+ host1x_uclass_wait_syncpt_base_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
+{
+ return (v & 0xff) << 16;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
+ host1x_uclass_wait_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
+{
+ return (v & 0xffff) << 0;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
+ host1x_uclass_wait_syncpt_base_offset_f(v)
+static inline u32 host1x_uclass_load_syncpt_base_r(void)
+{
+ return 0xb;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
+ host1x_uclass_load_syncpt_base_r()
+static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
+{
+ return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
+ host1x_uclass_load_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
+{
+ return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
+ host1x_uclass_load_syncpt_base_value_f(v)
+static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
+{
+ return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
+ host1x_uclass_incr_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
+{
+ return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
+ host1x_uclass_incr_syncpt_base_offset_f(v)
+static inline u32 host1x_uclass_indoff_r(void)
+{
+ return 0x2d;
+}
+#define HOST1X_UCLASS_INDOFF \
+ host1x_uclass_indoff_r()
+static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
+{
+ return (v & 0xf) << 28;
+}
+#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \
+ host1x_uclass_indoff_indbe_f(v)
+static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
+{
+ return (v & 0x1) << 27;
+}
+#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \
+ host1x_uclass_indoff_autoinc_f(v)
+static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
+{
+ return (v & 0xff) << 18;
+}
+#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \
+ host1x_uclass_indoff_indmodid_f(v)
+static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
+{
+ return (v & 0xffff) << 2;
+}
+#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
+ host1x_uclass_indoff_indroffset_f(v)
+static inline u32 host1x_uclass_indoff_rwn_read_v(void)
+{
+ return 1;
+}
+#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
+ host1x_uclass_indoff_indroffset_f(v)
+static inline u32 host1x_uclass_load_syncpt_payload_32_r(void)
+{
+ return 0x4e;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_PAYLOAD_32 \
+ host1x_uclass_load_syncpt_payload_32_r()
+static inline u32 host1x_uclass_wait_syncpt_32_r(void)
+{
+ return 0x50;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_32 \
+ host1x_uclass_wait_syncpt_32_r()
+
+#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x08_vm.h b/drivers/gpu/host1x/hw/hw_host1x08_vm.h
new file mode 100644
index 000000000000..1455a4670bf8
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x08_vm.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#define HOST1X_CHANNEL_DMASTART 0x0000
+#define HOST1X_CHANNEL_DMASTART_HI 0x0004
+#define HOST1X_CHANNEL_DMAPUT 0x0008
+#define HOST1X_CHANNEL_DMAPUT_HI 0x000c
+#define HOST1X_CHANNEL_DMAGET 0x0010
+#define HOST1X_CHANNEL_DMAGET_HI 0x0014
+#define HOST1X_CHANNEL_DMAEND 0x0018
+#define HOST1X_CHANNEL_DMAEND_HI 0x001c
+#define HOST1X_CHANNEL_DMACTRL 0x0020
+#define HOST1X_CHANNEL_DMACTRL_DMASTOP BIT(0)
+#define HOST1X_CHANNEL_DMACTRL_DMAGETRST BIT(1)
+#define HOST1X_CHANNEL_DMACTRL_DMAINITGET BIT(2)
+#define HOST1X_CHANNEL_CMDFIFO_STAT 0x0024
+#define HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY BIT(13)
+#define HOST1X_CHANNEL_CMDFIFO_RDATA 0x0028
+#define HOST1X_CHANNEL_CMDP_OFFSET 0x0030
+#define HOST1X_CHANNEL_CMDP_CLASS 0x0034
+#define HOST1X_CHANNEL_CHANNELSTAT 0x0038
+#define HOST1X_CHANNEL_CMDPROC_STOP 0x0048
+#define HOST1X_CHANNEL_TEARDOWN 0x004c
+#define HOST1X_CHANNEL_SMMU_STREAMID 0x0084
+
+#define HOST1X_SYNC_SYNCPT_CPU_INCR(x) (0x6400 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(x) (0x6600 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_INTR_DEST(x) (0x6684 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(x) (0x770c + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(x) (0x7790 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT(x) (0x8080 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_INT_THRESH(x) (0xa088 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_CH_APP(x) (0xb090 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_CH_APP_CH(v) (((v) & 0x3f) << 8)
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index f56375ee6e71..9acccdb139e6 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -76,6 +76,17 @@ static void intr_hw_init(struct host1x *host, u32 cpm)
/* update host clocks per usec */
host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK);
#endif
+#if HOST1X_HW >= 8
+ u32 id;
+
+ /*
+ * Program threshold interrupt destination among 8 lines per VM,
+ * per syncpoint. For now, just direct all to the first interrupt
+ * line.
+ */
+ for (id = 0; id < host->info->nb_pts; id++)
+ host1x_sync_writel(host, 0, HOST1X_SYNC_SYNCPT_INTR_DEST(id));
+#endif
}
static int
diff --git a/drivers/gpu/host1x/hw/opcodes.h b/drivers/gpu/host1x/hw/opcodes.h
new file mode 100644
index 000000000000..649614499b04
--- /dev/null
+++ b/drivers/gpu/host1x/hw/opcodes.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Tegra host1x opcodes
+ *
+ * Copyright (c) 2022 NVIDIA Corporation.
+ */
+
+#ifndef __HOST1X_OPCODES_H
+#define __HOST1X_OPCODES_H
+
+#include <linux/types.h>
+
+static inline u32 host1x_class_host_wait_syncpt(
+ unsigned indx, unsigned threshold)
+{
+ return host1x_uclass_wait_syncpt_indx_f(indx)
+ | host1x_uclass_wait_syncpt_thresh_f(threshold);
+}
+
+static inline u32 host1x_class_host_load_syncpt_base(
+ unsigned indx, unsigned threshold)
+{
+ return host1x_uclass_load_syncpt_base_base_indx_f(indx)
+ | host1x_uclass_load_syncpt_base_value_f(threshold);
+}
+
+static inline u32 host1x_class_host_wait_syncpt_base(
+ unsigned indx, unsigned base_indx, unsigned offset)
+{
+ return host1x_uclass_wait_syncpt_base_indx_f(indx)
+ | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
+ | host1x_uclass_wait_syncpt_base_offset_f(offset);
+}
+
+static inline u32 host1x_class_host_incr_syncpt_base(
+ unsigned base_indx, unsigned offset)
+{
+ return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
+ | host1x_uclass_incr_syncpt_base_offset_f(offset);
+}
+
+static inline u32 host1x_class_host_incr_syncpt(
+ unsigned cond, unsigned indx)
+{
+ return host1x_uclass_incr_syncpt_cond_f(cond)
+ | host1x_uclass_incr_syncpt_indx_f(indx);
+}
+
+static inline u32 host1x_class_host_indoff_reg_write(
+ unsigned mod_id, unsigned offset, bool auto_inc)
+{
+ u32 v = host1x_uclass_indoff_indbe_f(0xf)
+ | host1x_uclass_indoff_indmodid_f(mod_id)
+ | host1x_uclass_indoff_indroffset_f(offset);
+ if (auto_inc)
+ v |= host1x_uclass_indoff_autoinc_f(1);
+ return v;
+}
+
+static inline u32 host1x_class_host_indoff_reg_read(
+ unsigned mod_id, unsigned offset, bool auto_inc)
+{
+ u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
+ | host1x_uclass_indoff_indroffset_f(offset)
+ | host1x_uclass_indoff_rwn_read_v();
+ if (auto_inc)
+ v |= host1x_uclass_indoff_autoinc_f(1);
+ return v;
+}
+
+static inline u32 host1x_opcode_setclass(
+ unsigned class_id, unsigned offset, unsigned mask)
+{
+ return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
+}
+
+static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
+{
+ return (1 << 28) | (offset << 16) | count;
+}
+
+static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
+{
+ return (2 << 28) | (offset << 16) | count;
+}
+
+static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
+{
+ return (3 << 28) | (offset << 16) | mask;
+}
+
+static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
+{
+ return (4 << 28) | (offset << 16) | value;
+}
+
+static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
+{
+ return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
+ host1x_class_host_incr_syncpt(cond, indx));
+}
+
+static inline u32 host1x_opcode_restart(unsigned address)
+{
+ return (5 << 28) | (address >> 4);
+}
+
+static inline u32 host1x_opcode_gather(unsigned count)
+{
+ return (6 << 28) | count;
+}
+
+static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
+{
+ return (6 << 28) | (offset << 16) | BIT(15) | count;
+}
+
+static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
+{
+ return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
+}
+
+static inline u32 host1x_opcode_setstreamid(unsigned streamid)
+{
+ return (7 << 28) | streamid;
+}
+
+static inline u32 host1x_opcode_setpayload(unsigned payload)
+{
+ return (9 << 28) | payload;
+}
+
+static inline u32 host1x_opcode_gather_wide(unsigned count)
+{
+ return (12 << 28) | count;
+}
+
+static inline u32 host1x_opcode_acquire_mlock(unsigned mlock)
+{
+ return (14 << 28) | (0 << 24) | mlock;
+}
+
+static inline u32 host1x_opcode_release_mlock(unsigned mlock)
+{
+ return (14 << 28) | (1 << 24) | mlock;
+}
+
+#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
+
+#endif
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index c0bf4e581fe9..cb2100d9b0ff 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -327,6 +327,14 @@ struct host1x_job {
/* Whether host1x-side firewall should be ran for this job or not */
bool enable_firewall;
+
+ /* Options for configuring engine data stream ID */
+ /* Context device to use for job */
+ struct host1x_memory_context *memory_context;
+ /* Stream ID to use if context isolation is disabled (!memory_context) */
+ u32 engine_fallback_streamid;
+ /* Engine offset to program stream ID to */
+ u32 engine_streamid_offset;
};
struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
@@ -446,4 +454,38 @@ int tegra_mipi_disable(struct tegra_mipi_device *device);
int tegra_mipi_start_calibration(struct tegra_mipi_device *device);
int tegra_mipi_finish_calibration(struct tegra_mipi_device *device);
+/* host1x memory contexts */
+
+struct host1x_memory_context {
+ struct host1x *host;
+
+ refcount_t ref;
+ struct pid *owner;
+
+ struct device dev;
+ u64 dma_mask;
+ u32 stream_id;
+};
+
+#ifdef CONFIG_IOMMU_API
+struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+ struct pid *pid);
+void host1x_memory_context_get(struct host1x_memory_context *cd);
+void host1x_memory_context_put(struct host1x_memory_context *cd);
+#else
+static inline struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+ struct pid *pid)
+{
+ return NULL;
+}
+
+static inline void host1x_memory_context_get(struct host1x_memory_context *cd)
+{
+}
+
+static inline void host1x_memory_context_put(struct host1x_memory_context *cd)
+{
+}
+#endif
+
#endif