Commit e7d248f0 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'tegra-for-3.14-dmas-resets-rework' of...

Merge tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/cleanup

From Stephen Warren:
ARM: tegra: implement common DMA and resets DT bindings

This series converts the Tegra DTs and drivers to use the common/
standard DMA and reset bindings, rather than custom bindings. It also
adds complete documentation for the Tegra clock bindings without
actually changing any binding definitions.

This conversion relies on a few sets of patches in branches from outside
the Tegra tree:

1) A patch to add an DMA channel request API which allows deferred probe
   to be implemented.

2) A patch to implement a common part of the of_xlate function for DMA
   controllers.

3) Some ASoC patches (which in turn rely on (1) above), which support
   deferred probe during DMA channel allocation.

4) The Tegra clock driver changes for 3.14.

Consequently, this branch is based on a merge of all of those external
branches.

In turn, this branch is or will be pulled into a few places that either
rely on features introduced here, or would otherwise conflict with the
patches:

a) Tegra's own for-3.14/powergate and for-4.14/dt branches, to avoid
   conflicts.

b) The DRM tree, which introduces new code that relies on the reset
   controller framework introduced in this branch, and to avoid
   conflicts.

* tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: (30 commits)
  spi: tegra: checking for ERR_PTR instead of NULL
  ASoC: tegra: update module reset list for Tegra124
  clk: tegra: remove bogus PCIE_XCLK
  clk: tegra: remove legacy reset APIs
  ARM: tegra: remove legacy DMA entries from DT
  ARM: tegra: remove legacy clock entries from DT
  USB: EHCI: tegra: use reset framework
  Input: tegra-kbc - use reset framework
  serial: tegra: convert to standard DMA DT bindings
  serial: tegra: use reset framework
  spi: tegra: convert to standard DMA DT bindings
  spi: tegra: use reset framework
  staging: nvec: use reset framework
  i2c: tegra: use reset framework
  ASoC: tegra: convert to standard DMA DT bindings
  ASoC: tegra: allocate AHUB FIFO during probe() not startup()
  ASoC: tegra: call pm_runtime APIs around register accesses
  ASoC: tegra: use reset framework
  dma: tegra: register as an OF DMA controller
  dma: tegra: use reset framework
  ...
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 1c7af42f 8a0a1af3
...@@ -9,6 +9,7 @@ Required properties: ...@@ -9,6 +9,7 @@ Required properties:
- compatible : Should contain "nvidia,tegra<chip>-pmc". - compatible : Should contain "nvidia,tegra<chip>-pmc".
- reg : Offset and length of the register set for the device - reg : Offset and length of the register set for the device
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pclk" (The Tegra clock of that name), "pclk" (The Tegra clock of that name),
"clk32k_in" (The 32KHz clock input to Tegra). "clk32k_in" (The 32KHz clock input to Tegra).
......
...@@ -15,6 +15,9 @@ Required properties : ...@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file CAR. The assignments may be found in header file
<dt-bindings/clock/tegra114-car.h>. <dt-bindings/clock/tegra114-car.h>.
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
Example SoC include file: Example SoC include file:
...@@ -23,6 +26,7 @@ Example SoC include file: ...@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra114-car"; compatible = "nvidia,tegra114-car";
reg = <0x60006000 0x1000>; reg = <0x60006000 0x1000>;
#clock-cells = <1>; #clock-cells = <1>;
#reset-cells = <1>;
}; };
usb@c5004000 { usb@c5004000 {
......
...@@ -15,6 +15,9 @@ Required properties : ...@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file CAR. The assignments may be found in header file
<dt-bindings/clock/tegra124-car.h>. <dt-bindings/clock/tegra124-car.h>.
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
Example SoC include file: Example SoC include file:
...@@ -23,6 +26,7 @@ Example SoC include file: ...@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra124-car"; compatible = "nvidia,tegra124-car";
reg = <0x60006000 0x1000>; reg = <0x60006000 0x1000>;
#clock-cells = <1>; #clock-cells = <1>;
#reset-cells = <1>;
}; };
usb@c5004000 { usb@c5004000 {
......
...@@ -15,6 +15,9 @@ Required properties : ...@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file CAR. The assignments may be found in header file
<dt-bindings/clock/tegra20-car.h>. <dt-bindings/clock/tegra20-car.h>.
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
Example SoC include file: Example SoC include file:
...@@ -23,6 +26,7 @@ Example SoC include file: ...@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra20-car"; compatible = "nvidia,tegra20-car";
reg = <0x60006000 0x1000>; reg = <0x60006000 0x1000>;
#clock-cells = <1>; #clock-cells = <1>;
#reset-cells = <1>;
}; };
usb@c5004000 { usb@c5004000 {
......
...@@ -15,6 +15,9 @@ Required properties : ...@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file CAR. The assignments may be found in header file
<dt-bindings/clock/tegra30-car.h>. <dt-bindings/clock/tegra30-car.h>.
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
Example SoC include file: Example SoC include file:
...@@ -23,6 +26,7 @@ Example SoC include file: ...@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra30-car"; compatible = "nvidia,tegra30-car";
reg = <0x60006000 0x1000>; reg = <0x60006000 0x1000>;
#clock-cells = <1>; #clock-cells = <1>;
#reset-cells = <1>;
}; };
usb@c5004000 { usb@c5004000 {
......
...@@ -5,6 +5,16 @@ Required properties: ...@@ -5,6 +5,16 @@ Required properties:
- reg: Should contain DMA registers location and length. This shuld include - reg: Should contain DMA registers location and length. This shuld include
all of the per-channel registers. all of the per-channel registers.
- interrupts: Should contain all of the per-channel DMA interrupts. - interrupts: Should contain all of the per-channel DMA interrupts.
- 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:
- dma
- #dma-cells : Must be <1>. This dictates the length of DMA specifiers in
client nodes' dmas properties. The specifier represents the DMA request
select value for the peripheral. For more details, consult the Tegra TRM's
documentation of the APB DMA channel control register REQ_SEL field.
Examples: Examples:
...@@ -27,4 +37,8 @@ apbdma: dma@6000a000 { ...@@ -27,4 +37,8 @@ apbdma: dma@6000a000 {
0 149 0x04 0 149 0x04
0 150 0x04 0 150 0x04
0 151 0x04 >; 0 151 0x04 >;
clocks = <&tegra_car 34>;
resets = <&tegra_car 34>;
reset-names = "dma";
#dma-cells = <1>;
}; };
...@@ -9,6 +9,12 @@ Required properties: ...@@ -9,6 +9,12 @@ Required properties:
- #size-cells: The number of cells used to represent the size of an address - #size-cells: The number of cells used to represent the size of an address
range in the host1x address space. Should be 1. range in the host1x address space. Should be 1.
- ranges: The mapping of the host1x address space to the CPU address space. - 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
The host1x top-level node defines a number of children, each representing one The host1x top-level node defines a number of children, each representing one
of the following host1x client modules: of the following host1x client modules:
...@@ -19,6 +25,12 @@ of the following host1x client modules: ...@@ -19,6 +25,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-mpe" - compatible: "nvidia,tegra<chip>-mpe"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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
- vi: video input - vi: video input
...@@ -26,6 +38,12 @@ of the following host1x client modules: ...@@ -26,6 +38,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-vi" - compatible: "nvidia,tegra<chip>-vi"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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:
- vi
- epp: encoder pre-processor - epp: encoder pre-processor
...@@ -33,6 +51,12 @@ of the following host1x client modules: ...@@ -33,6 +51,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-epp" - compatible: "nvidia,tegra<chip>-epp"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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
- isp: image signal processor - isp: image signal processor
...@@ -40,6 +64,12 @@ of the following host1x client modules: ...@@ -40,6 +64,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-isp" - compatible: "nvidia,tegra<chip>-isp"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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
- gr2d: 2D graphics engine - gr2d: 2D graphics engine
...@@ -47,12 +77,30 @@ of the following host1x client modules: ...@@ -47,12 +77,30 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-gr2d" - compatible: "nvidia,tegra<chip>-gr2d"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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
- gr3d: 3D graphics engine - gr3d: 3D graphics engine
Required properties: Required properties:
- compatible: "nvidia,tegra<chip>-gr3d" - compatible: "nvidia,tegra<chip>-gr3d"
- reg: Physical base address and length of the controller's registers. - 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)
- dc: display controller - dc: display controller
...@@ -60,6 +108,16 @@ of the following host1x client modules: ...@@ -60,6 +108,16 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-dc" - compatible: "nvidia,tegra<chip>-dc"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - 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
Each display controller node has a child node, named "rgb", that represents Each display controller node has a child node, named "rgb", that represents
the RGB output associated with the controller. It can take the following the RGB output associated with the controller. It can take the following
...@@ -76,6 +134,16 @@ of the following host1x client modules: ...@@ -76,6 +134,16 @@ of the following host1x client modules:
- interrupts: The interrupt outputs from the controller. - interrupts: The interrupt outputs from the controller.
- vdd-supply: regulator for supply voltage - vdd-supply: regulator for supply voltage
- pll-supply: regulator for PLL - 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: Optional properties:
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
...@@ -88,12 +156,24 @@ of the following host1x client modules: ...@@ -88,12 +156,24 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-tvo" - compatible: "nvidia,tegra<chip>-tvo"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- dsi: display serial interface - dsi: display serial interface
Required properties: Required properties:
- compatible: "nvidia,tegra<chip>-dsi" - compatible: "nvidia,tegra<chip>-dsi"
- reg: Physical base address and length of the controller's registers. - 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.
- 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
Example: Example:
...@@ -105,6 +185,9 @@ Example: ...@@ -105,6 +185,9 @@ Example:
reg = <0x50000000 0x00024000>; reg = <0x50000000 0x00024000>;
interrupts = <0 65 0x04 /* mpcore syncpt */ interrupts = <0 65 0x04 /* mpcore syncpt */
0 67 0x04>; /* mpcore general */ 0 67 0x04>; /* mpcore general */
clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
resets = <&tegra_car 28>;
reset-names = "host1x";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
...@@ -115,41 +198,64 @@ Example: ...@@ -115,41 +198,64 @@ Example:
compatible = "nvidia,tegra20-mpe"; compatible = "nvidia,tegra20-mpe";
reg = <0x54040000 0x00040000>; reg = <0x54040000 0x00040000>;
interrupts = <0 68 0x04>; interrupts = <0 68 0x04>;
clocks = <&tegra_car TEGRA20_CLK_MPE>;
resets = <&tegra_car 60>;
reset-names = "mpe";
}; };
vi { vi {
compatible = "nvidia,tegra20-vi"; compatible = "nvidia,tegra20-vi";
reg = <0x54080000 0x00040000>; reg = <0x54080000 0x00040000>;
interrupts = <0 69 0x04>; interrupts = <0 69 0x04>;
clocks = <&tegra_car TEGRA20_CLK_VI>;
resets = <&tegra_car 100>;
reset-names = "vi";
}; };
epp { epp {
compatible = "nvidia,tegra20-epp"; compatible = "nvidia,tegra20-epp";
reg = <0x540c0000 0x00040000>; reg = <0x540c0000 0x00040000>;
interrupts = <0 70 0x04>; interrupts = <0 70 0x04>;
clocks = <&tegra_car TEGRA20_CLK_EPP>;
resets = <&tegra_car 19>;
reset-names = "epp";
}; };
isp { isp {
compatible = "nvidia,tegra20-isp"; compatible = "nvidia,tegra20-isp";
reg = <0x54100000 0x00040000>; reg = <0x54100000 0x00040000>;
interrupts = <0 71 0x04>; interrupts = <0 71 0x04>;
clocks = <&tegra_car TEGRA20_CLK_ISP>;
resets = <&tegra_car 23>;
reset-names = "isp";
}; };
gr2d { gr2d {
compatible = "nvidia,tegra20-gr2d"; compatible = "nvidia,tegra20-gr2d";
reg = <0x54140000 0x00040000>; reg = <0x54140000 0x00040000>;
interrupts = <0 72 0x04>; interrupts = <0 72 0x04>;
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
resets = <&tegra_car 21>;
reset-names = "2d";
}; };
gr3d { gr3d {
compatible = "nvidia,tegra20-gr3d"; compatible = "nvidia,tegra20-gr3d";
reg = <0x54180000 0x00040000>; reg = <0x54180000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
resets = <&tegra_car 24>;
reset-names = "3d";
}; };
dc@54200000 { dc@54200000 {
compatible = "nvidia,tegra20-dc"; compatible = "nvidia,tegra20-dc";
reg = <0x54200000 0x00040000>; reg = <0x54200000 0x00040000>;
interrupts = <0 73 0x04>; interrupts = <0 73 0x04>;
clocks = <&tegra_car TEGRA20_CLK_DISP1>,
<&tegra_car TEGRA20_CLK_PLL_P>;
clock-names = "disp1", "parent";
resets = <&tegra_car 27>;
reset-names = "dc";
rgb { rgb {
status = "disabled"; status = "disabled";
...@@ -160,6 +266,11 @@ Example: ...@@ -160,6 +266,11 @@ Example:
compatible = "nvidia,tegra20-dc"; compatible = "nvidia,tegra20-dc";
reg = <0x54240000 0x00040000>; reg = <0x54240000 0x00040000>;
interrupts = <0 74 0x04>; interrupts = <0 74 0x04>;
clocks = <&tegra_car TEGRA20_CLK_DISP2>,
<&tegra_car TEGRA20_CLK_PLL_P>;
clock-names = "disp2", "parent";
resets = <&tegra_car 26>;
reset-names = "dc";
rgb { rgb {
status = "disabled"; status = "disabled";
...@@ -170,6 +281,11 @@ Example: ...@@ -170,6 +281,11 @@ Example:
compatible = "nvidia,tegra20-hdmi"; compatible = "nvidia,tegra20-hdmi";
reg = <0x54280000 0x00040000>; reg = <0x54280000 0x00040000>;
interrupts = <0 75 0x04>; 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"; status = "disabled";
}; };
...@@ -177,12 +293,18 @@ Example: ...@@ -177,12 +293,18 @@ Example:
compatible = "nvidia,tegra20-tvo"; compatible = "nvidia,tegra20-tvo";
reg = <0x542c0000 0x00040000>; reg = <0x542c0000 0x00040000>;
interrupts = <0 76 0x04>; interrupts = <0 76 0x04>;
clocks = <&tegra_car TEGRA20_CLK_TVO>;
status = "disabled"; status = "disabled";
}; };
dsi { dsi {
compatible = "nvidia,tegra20-dsi"; compatible = "nvidia,tegra20-dsi";
reg = <0x54300000 0x00040000>; 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"; status = "disabled";
}; };
}; };
......
...@@ -39,12 +39,23 @@ Required properties: ...@@ -39,12 +39,23 @@ Required properties:
- interrupts: Should contain I2C controller interrupts. - interrupts: Should contain I2C controller interrupts.
- address-cells: Address cells for I2C device address. - address-cells: Address cells for I2C device address.
- size-cells: Size of the I2C device address. - size-cells: Size of the I2C device address.
- clocks: Clock ID as per - clocks: Must contain an entry for each entry in clock-names.
Documentation/devicetree/bindings/clock/tegra<chip-id>.txt See ../clocks/clock-bindings.txt for details.
for I2C controller. - clock-names: Must include the following entries:
- clock-names: Name of the clock: Tegra20/Tegra30:
Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk". - div-clk
Tegra114 I2C controller: "div-clk". - fast-clk
Tegra114:
- div-clk
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- i2c
- dmas: Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names: Must include the following entries:
- rx
- tx
Example: Example:
...@@ -56,5 +67,9 @@ Example: ...@@ -56,5 +67,9 @@ Example:
#size-cells = <0>; #size-cells = <0>;
clocks = <&tegra_car 12>, <&tegra_car 124>; clocks = <&tegra_car 12>, <&tegra_car 124>;
clock-names = "div-clk", "fast-clk"; clock-names = "div-clk", "fast-clk";
resets = <&tegra_car 12>;
reset-names = "i2c";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
status = "disabled"; status = "disabled";
}; };
...@@ -13,6 +13,12 @@ Required properties: ...@@ -13,6 +13,12 @@ Required properties:
array of pin numbers which is used as column. array of pin numbers which is used as column.
- linux,keymap: The keymap for keys as described in the binding document - linux,keymap: The keymap for keys as described in the binding document
devicetree/bindings/input/matrix-keymap.txt. devicetree/bindings/input/matrix-keymap.txt.
- 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:
- kbc
Optional properties, in addition to those specified by the shared Optional properties, in addition to those specified by the shared
matrix-keyboard bindings: matrix-keyboard bindings:
...@@ -31,6 +37,9 @@ keyboard: keyboard { ...@@ -31,6 +37,9 @@ keyboard: keyboard {
compatible = "nvidia,tegra20-kbc"; compatible = "nvidia,tegra20-kbc";
reg = <0x7000e200 0x100>; reg = <0x7000e200 0x100>;
interrupts = <0 85 0x04>; interrupts = <0 85 0x04>;
clocks = <&tegra_car 36>;
resets = <&tegra_car 36>;
reset-names = "kbc";
nvidia,ghost-filter; nvidia,ghost-filter;
nvidia,debounce-delay-ms = <640>; nvidia,debounce-delay-ms = <640>;
nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */ nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */
......
...@@ -8,6 +8,12 @@ by mmc.txt and the properties used by the sdhci-tegra driver. ...@@ -8,6 +8,12 @@ by mmc.txt and the properties used by the sdhci-tegra driver.
Required properties: Required properties:
- compatible : Should be "nvidia,<chip>-sdhci" - compatible : Should be "nvidia,<chip>-sdhci"
- 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:
- sdhci
Optional properties: Optional properties:
- power-gpios : Specify GPIOs for power control - power-gpios : Specify GPIOs for power control
...@@ -18,6 +24,9 @@ sdhci@c8000200 { ...@@ -18,6 +24,9 @@ sdhci@c8000200 {
compatible = "nvidia,tegra20-sdhci"; compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000200 0x200>; reg = <0xc8000200 0x200>;
interrupts = <47>; interrupts = <47>;
clocks = <&tegra_car 14>;
resets = <&tegra_car 14>;
reset-names = "sdhci";
cd-gpios = <&gpio 69 0>; /* gpio PI5 */ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */ power-gpios = <&gpio 155 0>; /* gpio PT3 */
......
...@@ -7,3 +7,15 @@ Required properties: ...@@ -7,3 +7,15 @@ Required properties:
- clock-frequency : the frequency of the i2c bus - clock-frequency : the frequency of the i2c bus
- gpios : the gpio used for ec request - gpios : the gpio used for ec request
- slave-addr: the i2c address of the slave controller - slave-addr: the i2c address of the slave 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:
Tegra20/Tegra30:
- div-clk
- fast-clk
Tegra114:
- div-clk
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- i2c
...@@ -42,14 +42,19 @@ Required properties: ...@@ -42,14 +42,19 @@ Required properties:
- 0xc2000000: prefetchable memory region - 0xc2000000: prefetchable memory region
Please refer to the standard PCI bus binding document for a more detailed Please refer to the standard PCI bus binding document for a more detailed
explanation. explanation.
- clocks: List of clock inputs of the controller. Must contain an entry for - clocks: Must contain an entry for each entry in clock-names.
each entry in the clock-names property. See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries: - clock-names: Must include the following entries:
"pex": The Tegra clock of that name - pex
"afi": The Tegra clock of that name - afi
"pcie_xclk": The Tegra clock of that name - pll_e
"pll_e": The Tegra clock of that name - cml (not required for Tegra20)
"cml": The Tegra clock of that name (not required for Tegra20) - resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- pex
- afi
- pcie_x
Root ports are defined as subnodes of the PCIe controller node. Root ports are defined as subnodes of the PCIe controller node.
...@@ -91,9 +96,10 @@ SoC DTSI: ...@@ -91,9 +96,10 @@ SoC DTSI:
0x82000000 0 0xa0000000 0xa0000000 0 0x10000000 /* non-prefetchable memory */ 0x82000000 0 0xa0000000 0xa0000000 0 0x10000000 /* non-prefetchable memory */
0xc2000000 0 0xb0000000 0xb0000000 0 0x10000000>; /* prefetchable memory */ 0xc2000000 0 0xb0000000 0xb0000000 0 0x10000000>; /* prefetchable memory */
clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>, clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 118>;
<&tegra_car 118>; clock-names = "pex", "afi", "pll_e";
clock-names = "pex", "afi", "pcie_xclk", "pll_e"; resets = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled"; status = "disabled";
pci@1,0 { pci@1,0 {
......
...@@ -7,6 +7,12 @@ Required properties: ...@@ -7,6 +7,12 @@ Required properties:
- reg: physical base address and length of the controller's registers - reg: physical base address and length of the controller's registers
- #pwm-cells: should be 2. See pwm.txt in this directory for a description of - #pwm-cells: should be 2. See pwm.txt in this directory for a description of
the cells format. the cells format.
- 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:
- pwm
Example: Example:
...@@ -14,4 +20,7 @@ Example: ...@@ -14,4 +20,7 @@ Example:
compatible = "nvidia,tegra20-pwm"; compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>; reg = <0x7000a000 0x100>;
#pwm-cells = <2>; #pwm-cells = <2>;
clocks = <&tegra_car 17>;
resets = <&tegra_car 17>;
reset-names = "pwm";
}; };
...@@ -9,6 +9,8 @@ Required properties: ...@@ -9,6 +9,8 @@ Required properties:
- compatible : should be "nvidia,tegra20-rtc". - compatible : should be "nvidia,tegra20-rtc".
- reg : Specifies base physical address and size of the registers. - reg : Specifies base physical address and size of the registers.
- interrupts : A single interrupt specifier. - interrupts : A single interrupt specifier.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
Example: Example:
...@@ -16,4 +18,5 @@ timer { ...@@ -16,4 +18,5 @@ timer {
compatible = "nvidia,tegra20-rtc"; compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>; reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>; interrupts = <0 2 0x04>;
clocks = <&tegra_car 4>;
}; };
...@@ -4,8 +4,17 @@ Required properties: ...@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart". - compatible : should be "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart".
- reg: Should contain UART controller registers location and length. - reg: Should contain UART controller registers location and length.
- interrupts: Should contain UART controller interrupts. - interrupts: Should contain UART controller interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - clocks: Must contain one entry, for the module clock.
request selector for this UART controller. 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:
- serial
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
Optional properties: Optional properties:
- nvidia,enable-modem-interrupt: Enable modem interrupts. Should be enable - nvidia,enable-modem-interrupt: Enable modem interrupts. Should be enable
...@@ -18,7 +27,11 @@ serial@70006000 { ...@@ -18,7 +27,11 @@ serial@70006000 {
reg = <0x70006000 0x40>; reg = <0x70006000 0x40>;
reg-shift = <2>; reg-shift = <2>;
interrupts = <0 36 0x04>; interrupts = <0 36 0x04>;
nvidia,dma-request-selector = <&apbdma 8>;
nvidia,enable-modem-interrupt; nvidia,enable-modem-interrupt;
clocks = <&tegra_car 6>;
resets = <&tegra_car 6>;
reset-names = "serial";
dmas = <&apbdma 8>, <&apbdma 8>;
dma-names = "rx", "tx";
status = "disabled"; status = "disabled";
}; };
...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex ...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties: Required properties:
- compatible : "nvidia,tegra-audio-alc5632" - compatible : "nvidia,tegra-audio-alc5632"
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pll_a" (The Tegra clock of that name), - pll_a
"pll_a_out0" (The Tegra clock of that name), - pll_a_out0
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex. - nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components. - nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, Each entry is a pair of strings, the first being the connection's sink,
......
...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex, with RT5640 CODEC ...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex, with RT5640 CODEC
Required properties: Required properties:
- compatible : "nvidia,tegra-audio-rt5640" - compatible : "nvidia,tegra-audio-rt5640"
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pll_a" (The Tegra clock of that name), - pll_a
"pll_a_out0" (The Tegra clock of that name), - pll_a_out0
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex. - nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components. - nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, Each entry is a pair of strings, the first being the connection's sink,
......
...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex ...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties: Required properties:
- compatible : "nvidia,tegra-audio-wm8753" - compatible : "nvidia,tegra-audio-wm8753"
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pll_a" (The Tegra clock of that name), - pll_a
"pll_a_out0" (The Tegra clock of that name), - pll_a_out0
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex. - nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components. - nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, Each entry is a pair of strings, the first being the connection's sink,
......
...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex ...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties: Required properties:
- compatible : "nvidia,tegra-audio-wm8903" - compatible : "nvidia,tegra-audio-wm8903"
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pll_a" (The Tegra clock of that name), - pll_a
"pll_a_out0" (The Tegra clock of that name), - pll_a_out0
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex. - nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components. - nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, Each entry is a pair of strings, the first being the connection's sink,
......
...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex ...@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties: Required properties:
- compatible : "nvidia,tegra-audio-wm9712" - compatible : "nvidia,tegra-audio-wm9712"
- clocks : Must contain an entry for each entry in clock-names. - 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: - clock-names : Must include the following entries:
"pll_a" (The Tegra clock of that name), - pll_a
"pll_a_out0" (The Tegra clock of that name), - pll_a_out0
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex. - nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components. - nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, Each entry is a pair of strings, the first being the connection's sink,
......
...@@ -4,19 +4,33 @@ Required properties: ...@@ -4,19 +4,33 @@ Required properties:
- compatible : "nvidia,tegra20-ac97" - compatible : "nvidia,tegra20-ac97"
- reg : Should contain AC97 controller registers location and length - reg : Should contain AC97 controller registers location and length
- interrupts : Should contain AC97 interrupt - interrupts : Should contain AC97 interrupt
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - resets : Must contain an entry for each entry in reset-names.
request selector for the AC97 controller See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- ac97
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- nvidia,codec-reset-gpio : The Tegra GPIO controller's phandle and the number - nvidia,codec-reset-gpio : The Tegra GPIO controller's phandle and the number
of the GPIO used to reset the external AC97 codec of the GPIO used to reset the external AC97 codec
- nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number - nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number
of the GPIO corresponding with the AC97 DAP _FS line of the GPIO corresponding with the AC97 DAP _FS line
Example: Example:
ac97@70002000 { ac97@70002000 {
compatible = "nvidia,tegra20-ac97"; compatible = "nvidia,tegra20-ac97";
reg = <0x70002000 0x200>; reg = <0x70002000 0x200>;
interrupts = <0 81 0x04>; interrupts = <0 81 0x04>;
nvidia,dma-request-selector = <&apbdma 12>;
nvidia,codec-reset-gpio = <&gpio 170 0>; nvidia,codec-reset-gpio = <&gpio 170 0>;
nvidia,codec-sync-gpio = <&gpio 120 0>; nvidia,codec-sync-gpio = <&gpio 120 0>;
clocks = <&tegra_car 3>;
resets = <&tegra_car 3>;
reset-names = "ac97";
dmas = <&apbdma 12>, <&apbdma 12>;
dma-names = "rx", "tx";
}; };
...@@ -4,8 +4,17 @@ Required properties: ...@@ -4,8 +4,17 @@ Required properties:
- compatible : "nvidia,tegra20-i2s" - compatible : "nvidia,tegra20-i2s"
- reg : Should contain I2S registers location and length - reg : Should contain I2S registers location and length
- interrupts : Should contain I2S interrupt - interrupts : Should contain I2S interrupt
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - resets : Must contain an entry for each entry in reset-names.
request selector for this I2S controller See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- i2s
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
Example: Example:
...@@ -13,5 +22,9 @@ i2s@70002800 { ...@@ -13,5 +22,9 @@ i2s@70002800 {
compatible = "nvidia,tegra20-i2s"; compatible = "nvidia,tegra20-i2s";
reg = <0x70002800 0x200>; reg = <0x70002800 0x200>;
interrupts = < 45 >; interrupts = < 45 >;
nvidia,dma-request-selector = < &apbdma 2 >; clocks = <&tegra_car 11>;
resets = <&tegra_car 11>;
reset-names = "i2s";
dmas = <&apbdma 21>, <&apbdma 21>;
dma-names = "rx", "tx";
}; };
...@@ -7,18 +7,48 @@ Required properties: ...@@ -7,18 +7,48 @@ Required properties:
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks. - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
- Tegra114 requires an additional entry, for the APBIF2 register block. - Tegra114 requires an additional entry, for the APBIF2 register block.
- interrupts : Should contain AHUB interrupt - interrupts : Should contain AHUB interrupt
- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each - clocks : Must contain an entry for each entry in clock-names.
entry contains the Tegra DMA controller's phandle and request selector. See ../clocks/clock-bindings.txt for details.
If a single entry is present, the request selectors for the channels are
assumed to be contiguous, and increment from this value.
If multiple values are given, one value must be given per channel.
- clocks : Must contain an entry for each required entry in clock-names.
- clock-names : Must include the following entries: - clock-names : Must include the following entries:
- Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0, - d_audio
dam1, dam2, spdif_in. - apbif
- Tegra114: Additionally requires amx, adx. - resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
Tegra30 and later:
- d_audio
- apbif
- i2s0
- i2s1
- i2s2
- i2s3
- i2s4
- dam0
- dam1
- dam2
- spdif
Tegra114 and later additionally require:
- amx
- adx
Tegra124 and later additionally require:
- amx1
- adx1
- afc0
- afc1
- afc2
- afc3
- afc4
- afc5
- ranges : The bus address mapping for the configlink register bus. - ranges : The bus address mapping for the configlink register bus.
Can be empty since the mapping is 1:1. Can be empty since the mapping is 1:1.
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx0 .. rx<n>
- tx0 .. tx<n>
... where n is:
Tegra30: 3
Tegra114, Tegra124: 9
- #address-cells : For the configlink bus. Should be <1>; - #address-cells : For the configlink bus. Should be <1>;
- #size-cells : For the configlink bus. Should be <1>. - #size-cells : For the configlink bus. Should be <1>.
...@@ -35,13 +65,20 @@ ahub@70080000 { ...@@ -35,13 +65,20 @@ ahub@70080000 {
reg = <0x70080000 0x200 0x70080200 0x100>; reg = <0x70080000 0x200 0x70080200 0x100>;
interrupts = < 0 103 0x04 >; interrupts = < 0 103 0x04 >;
nvidia,dma-request-selector = <&apbdma 1>; nvidia,dma-request-selector = <&apbdma 1>;
clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, clocks = <&tegra_car 106>, <&tegra_car 107>;
clock-names = "d_audio", "apbif";
resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>, <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>, <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
<&tegra_car 110>, <&tegra_car 162>; <&tegra_car 110>, <&tegra_car 10>;
clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
"i2s3", "i2s4", "dam0", "dam1", "dam2", "i2s3", "i2s4", "dam0", "dam1", "dam2",
"spdif_in"; "spdif";
dmas = <&apbdma 1>, <&apbdma 1>;
<&apbdma 2>, <&apbdma 2>;
<&apbdma 3>, <&apbdma 3>;
<&apbdma 4>, <&apbdma 4>;
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3";
ranges; ranges;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
......
...@@ -3,13 +3,22 @@ NVIDIA Tegra30 I2S controller ...@@ -3,13 +3,22 @@ NVIDIA Tegra30 I2S controller
Required properties: Required properties:
- compatible : "nvidia,tegra30-i2s" - compatible : "nvidia,tegra30-i2s"
- reg : Should contain I2S registers location and length - reg : Should contain I2S registers location and length
- 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:
- i2s
- nvidia,ahub-cif-ids : The list of AHUB CIF IDs for this port, rx (playback) - nvidia,ahub-cif-ids : The list of AHUB CIF IDs for this port, rx (playback)
first, tx (capture) second. See nvidia,tegra30-ahub.txt for values. first, tx (capture) second. See nvidia,tegra30-ahub.txt for values.
Example: Example:
i2s@70002800 { i2s@70080300 {
compatible = "nvidia,tegra30-i2s"; compatible = "nvidia,tegra30-i2s";
reg = <0x70080300 0x100>; reg = <0x70080300 0x100>;
nvidia,ahub-cif-ids = <4 4>; nvidia,ahub-cif-ids = <4 4>;
clocks = <&tegra_car 11>;
resets = <&tegra_car 11>;
reset-names = "i2s";
}; };
...@@ -4,10 +4,19 @@ Required properties: ...@@ -4,10 +4,19 @@ Required properties:
- compatible : should be "nvidia,tegra114-spi". - compatible : should be "nvidia,tegra114-spi".
- reg: Should contain SPI registers location and length. - reg: Should contain SPI registers location and length.
- interrupts: Should contain SPI interrupts. - interrupts: Should contain SPI interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - clock-names : Must include the following entries:
request selector for this SPI controller. - spi
- This is also require clock named "spi" as per binding document - resets : Must contain an entry for each entry in reset-names.
Documentation/devicetree/bindings/clock/clock-bindings.txt See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
Recommended properties: Recommended properties:
- spi-max-frequency: Definition as per - spi-max-frequency: Definition as per
...@@ -18,9 +27,14 @@ spi@7000d600 { ...@@ -18,9 +27,14 @@ spi@7000d600 {
compatible = "nvidia,tegra114-spi"; compatible = "nvidia,tegra114-spi";
reg = <0x7000d600 0x200>; reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>; interrupts = <0 82 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>; spi-max-frequency = <25000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&tegra_car 44>;
clock-names = "spi";
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
status = "disabled"; status = "disabled";
}; };
...@@ -4,8 +4,17 @@ Required properties: ...@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra20-sflash". - compatible : should be "nvidia,tegra20-sflash".
- reg: Should contain SFLASH registers location and length. - reg: Should contain SFLASH registers location and length.
- interrupts: Should contain SFLASH interrupts. - interrupts: Should contain SFLASH interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - clocks : Must contain one entry, for the module clock.
request selector for this SFLASH controller. 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:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
Recommended properties: Recommended properties:
- spi-max-frequency: Definition as per - spi-max-frequency: Definition as per
...@@ -17,10 +26,13 @@ spi@7000c380 { ...@@ -17,10 +26,13 @@ spi@7000c380 {
compatible = "nvidia,tegra20-sflash"; compatible = "nvidia,tegra20-sflash";
reg = <0x7000c380 0x80>; reg = <0x7000c380 0x80>;
interrupts = <0 39 0x04>; interrupts = <0 39 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>; spi-max-frequency = <25000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&tegra_car 43>;
resets = <&tegra_car 43>;
reset-names = "spi";
dmas = <&apbdma 11>, <&apbdma 11>;
dma-names = "rx", "tx";
status = "disabled"; status = "disabled";
}; };
...@@ -4,8 +4,17 @@ Required properties: ...@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra20-slink", "nvidia,tegra30-slink". - compatible : should be "nvidia,tegra20-slink", "nvidia,tegra30-slink".
- reg: Should contain SLINK registers location and length. - reg: Should contain SLINK registers location and length.
- interrupts: Should contain SLINK interrupts. - interrupts: Should contain SLINK interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - clocks : Must contain one entry, for the module clock.
request selector for this SLINK controller. 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:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
Recommended properties: Recommended properties:
- spi-max-frequency: Definition as per - spi-max-frequency: Definition as per
...@@ -17,10 +26,13 @@ spi@7000d600 { ...@@ -17,10 +26,13 @@ spi@7000d600 {
compatible = "nvidia,tegra20-slink"; compatible = "nvidia,tegra20-slink";
reg = <0x7000d600 0x200>; reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>; interrupts = <0 82 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>; spi-max-frequency = <25000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&tegra_car 44>;
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
status = "disabled"; status = "disabled";
}; };
...@@ -8,6 +8,8 @@ Required properties: ...@@ -8,6 +8,8 @@ Required properties:
- compatible : should be "nvidia,tegra20-timer". - compatible : should be "nvidia,tegra20-timer".
- reg : Specifies base physical address and size of the registers. - reg : Specifies base physical address and size of the registers.
- interrupts : A list of 4 interrupts; one per timer channel. - interrupts : A list of 4 interrupts; one per timer channel.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
Example: Example:
...@@ -18,4 +20,5 @@ timer { ...@@ -18,4 +20,5 @@ timer {
0 1 0x04 0 1 0x04
0 41 0x04 0 41 0x04
0 42 0x04>; 0 42 0x04>;
clocks = <&tegra_car 132>;
}; };
...@@ -10,6 +10,8 @@ Required properties: ...@@ -10,6 +10,8 @@ Required properties:
- reg : Specifies base physical address and size of the registers. - reg : Specifies base physical address and size of the registers.
- interrupts : A list of 6 interrupts; one per each of timer channels 1 - interrupts : A list of 6 interrupts; one per each of timer channels 1
through 5, and one for the shared interrupt for the remaining channels. through 5, and one for the shared interrupt for the remaining channels.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
timer { timer {
compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
...@@ -20,4 +22,5 @@ timer { ...@@ -20,4 +22,5 @@ timer {
0 42 0x04 0 42 0x04
0 121 0x04 0 121 0x04
0 122 0x04>; 0 122 0x04>;
clocks = <&tegra_car 214>;
}; };
...@@ -8,7 +8,12 @@ and additions : ...@@ -8,7 +8,12 @@ and additions :
Required properties : Required properties :
- compatible : Should be "nvidia,tegra20-ehci". - compatible : Should be "nvidia,tegra20-ehci".
- nvidia,phy : phandle of the PHY that the controller is connected to. - nvidia,phy : phandle of the PHY that the controller is connected to.
- clocks : Contains a single entry which defines the USB controller's clock. - 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:
- usb
Optional properties: Optional properties:
- nvidia,needs-double-reset : boolean is to be set for some of the Tegra20 - nvidia,needs-double-reset : boolean is to be set for some of the Tegra20
......
This diff is collapsed.
...@@ -280,6 +280,8 @@ nvec { ...@@ -280,6 +280,8 @@ nvec {
clocks = <&tegra_car TEGRA20_CLK_I2C3>, clocks = <&tegra_car TEGRA20_CLK_I2C3>,
<&tegra_car TEGRA20_CLK_PLL_P_OUT3>; <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
clock-names = "div-clk", "fast-clk"; clock-names = "div-clk", "fast-clk";
resets = <&tegra_car 67>;
reset-names = "i2c";
}; };
i2c@7000d000 { i2c@7000d000 {
......
This diff is collapsed.
This diff is collapsed.
...@@ -14,6 +14,8 @@ config ARCH_TEGRA ...@@ -14,6 +14,8 @@ config ARCH_TEGRA
select MIGHT_HAVE_CACHE_L2X0 select MIGHT_HAVE_CACHE_L2X0
select MIGHT_HAVE_PCI select MIGHT_HAVE_PCI
select PINCTRL select PINCTRL
select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER
select SOC_BUS select SOC_BUS
select SPARSE_IRQ select SPARSE_IRQ
select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ARCH_HAS_EHCI if USB_SUPPORT
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/reset.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/clk/tegra.h> #include <linux/clk/tegra.h>
...@@ -144,11 +145,12 @@ int tegra_powergate_remove_clamping(int id) ...@@ -144,11 +145,12 @@ int tegra_powergate_remove_clamping(int id)
} }
/* Must be called with clk disabled, and returns with clk enabled */ /* Must be called with clk disabled, and returns with clk enabled */
int tegra_powergate_sequence_power_up(int id, struct clk *clk) int tegra_powergate_sequence_power_up(int id, struct clk *clk,
struct reset_control *rst)
{ {
int ret; int ret;
tegra_periph_reset_assert(clk); reset_control_assert(rst);
ret = tegra_powergate_power_on(id); ret = tegra_powergate_power_on(id);
if (ret) if (ret)
...@@ -165,7 +167,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk) ...@@ -165,7 +167,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk)
goto err_clamp; goto err_clamp;
udelay(10); udelay(10);
tegra_periph_reset_deassert(clk); reset_control_deassert(rst);
return 0; return 0;
......
...@@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock); ...@@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock);
#define read_rst(gate) \ #define read_rst(gate) \
readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) readl_relaxed(gate->clk_base + (gate->regs->rst_reg))
#define write_rst_set(val, gate) \
writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg))
#define write_rst_clr(val, gate) \ #define write_rst_clr(val, gate) \
writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
...@@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw) ...@@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw)
spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags);
} }
void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert)
{
if (gate->flags & TEGRA_PERIPH_NO_RESET)
return;
if (assert) {
/*
* If peripheral is in the APB bus then read the APB bus to
* flush the write operation in apb bus. This will avoid the
* peripheral access after disabling clock
*/
if (gate->flags & TEGRA_PERIPH_ON_APB)
tegra_read_chipid();
write_rst_set(periph_clk_to_bit(gate), gate);
} else {
write_rst_clr(periph_clk_to_bit(gate), gate);
}
}
const struct clk_ops tegra_clk_periph_gate_ops = { const struct clk_ops tegra_clk_periph_gate_ops = {
.is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable, .enable = clk_periph_enable,
......
...@@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw) ...@@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw); gate_ops->disable(gate_hw);
} }
void tegra_periph_reset_deassert(struct clk *c)
{
struct clk_hw *hw = __clk_get_hw(c);
struct tegra_clk_periph *periph = to_clk_periph(hw);
struct tegra_clk_periph_gate *gate;
if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
gate = to_clk_periph_gate(hw);
if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
WARN_ON(1);
return;
}
} else {
gate = &periph->gate;
}
tegra_periph_reset(gate, 0);
}
EXPORT_SYMBOL(tegra_periph_reset_deassert);
void tegra_periph_reset_assert(struct clk *c)
{
struct clk_hw *hw = __clk_get_hw(c);
struct tegra_clk_periph *periph = to_clk_periph(hw);
struct tegra_clk_periph_gate *gate;
if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
gate = to_clk_periph_gate(hw);
if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
WARN_ON(1);
return;
}
} else {
gate = &periph->gate;
}
tegra_periph_reset(gate, 1);
}
EXPORT_SYMBOL(tegra_periph_reset_assert);
const struct clk_ops tegra_clk_periph_ops = { const struct clk_ops tegra_clk_periph_ops = {
.get_parent = clk_periph_get_parent, .get_parent = clk_periph_get_parent,
.set_parent = clk_periph_set_parent, .set_parent = clk_periph_set_parent,
......
...@@ -1460,7 +1460,8 @@ static void __init tegra114_clock_init(struct device_node *np) ...@@ -1460,7 +1460,8 @@ static void __init tegra114_clock_init(struct device_node *np)
return; return;
} }
clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS); clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX,
TEGRA114_CLK_PERIPH_BANKS);
if (!clks) if (!clks)
return; return;
......
...@@ -1398,7 +1398,7 @@ static void __init tegra124_clock_init(struct device_node *np) ...@@ -1398,7 +1398,7 @@ static void __init tegra124_clock_init(struct device_node *np)
return; return;
} }
clks = tegra_clk_init(TEGRA124_CLK_CLK_MAX, 6); clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6);
if (!clks) if (!clks)
return; return;
......
...@@ -468,7 +468,6 @@ static struct tegra_devclk devclks[] __initdata = { ...@@ -468,7 +468,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP }, { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP },
{ .con_id = "pex", .dt_id = TEGRA20_CLK_PEX }, { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX },
{ .con_id = "afi", .dt_id = TEGRA20_CLK_AFI }, { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI },
{ .con_id = "pcie_xclk", .dt_id = TEGRA20_CLK_PCIE_XCLK },
{ .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 },
{ .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 },
{ .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K },
...@@ -834,11 +833,6 @@ static void __init tegra20_periph_clk_init(void) ...@@ -834,11 +833,6 @@ static void __init tegra20_periph_clk_init(void)
periph_clk_enb_refcnt); periph_clk_enb_refcnt);
clks[TEGRA20_CLK_PEX] = clk; clks[TEGRA20_CLK_PEX] = clk;
/* pcie_xclk */
clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base,
0, 74, periph_clk_enb_refcnt);
clks[TEGRA20_CLK_PCIE_XCLK] = clk;
/* cdev1 */ /* cdev1 */
clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT,
26000000); 26000000);
...@@ -1109,7 +1103,8 @@ static void __init tegra20_clock_init(struct device_node *np) ...@@ -1109,7 +1103,8 @@ static void __init tegra20_clock_init(struct device_node *np)
BUG(); BUG();
} }
clks = tegra_clk_init(TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_PERIPH_BANKS); clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX,
TEGRA20_CLK_PERIPH_BANKS);
if (!clks) if (!clks)
return; return;
......
...@@ -649,7 +649,6 @@ static struct tegra_devclk devclks[] __initdata = { ...@@ -649,7 +649,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP }, { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP },
{ .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE },
{ .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI },
{ .con_id = "pciex", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIEX },
{ .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE }, { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE },
{ .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN },
{ .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF },
...@@ -1150,11 +1149,6 @@ static void __init tegra30_periph_clk_init(void) ...@@ -1150,11 +1149,6 @@ static void __init tegra30_periph_clk_init(void)
periph_clk_enb_refcnt); periph_clk_enb_refcnt);
clks[TEGRA30_CLK_AFI] = clk; clks[TEGRA30_CLK_AFI] = clk;
/* pciex */
clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0,
74, periph_clk_enb_refcnt);
clks[TEGRA30_CLK_PCIEX] = clk;
/* emc */ /* emc */
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
ARRAY_SIZE(mux_pllmcp_clkm), ARRAY_SIZE(mux_pllmcp_clkm),
...@@ -1395,7 +1389,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { ...@@ -1395,7 +1389,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"),
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL),
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"),
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_PCIEX, "tegra_pcie", "pciex"),
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"), TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"),
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */
}; };
...@@ -1427,7 +1420,8 @@ static void __init tegra30_clock_init(struct device_node *np) ...@@ -1427,7 +1420,8 @@ static void __init tegra30_clock_init(struct device_node *np)
BUG(); BUG();
} }
clks = tegra_clk_init(TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_PERIPH_BANKS); clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX,
TEGRA30_CLK_PERIPH_BANKS);
if (!clks) if (!clks)
return; return;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/clk/tegra.h> #include <linux/clk/tegra.h>
#include <linux/reset-controller.h>
#include <linux/tegra-soc.h>
#include "clk.h" #include "clk.h"
...@@ -121,6 +123,35 @@ static struct tegra_clk_periph_regs periph_regs[] = { ...@@ -121,6 +123,35 @@ static struct tegra_clk_periph_regs periph_regs[] = {
}, },
}; };
static void __iomem *clk_base;
static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
/*
* If peripheral is on the APB bus then we must read the APB bus to
* flush the write operation in apb bus. This will avoid peripheral
* access after disabling clock. Since the reset driver has no
* knowledge of which reset IDs represent which devices, simply do
* this all the time.
*/
tegra_read_chipid();
writel_relaxed(BIT(id % 32),
clk_base + periph_regs[id / 32].rst_set_reg);
return 0;
}
static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
writel_relaxed(BIT(id % 32),
clk_base + periph_regs[id / 32].rst_clr_reg);
return 0;
}
struct tegra_clk_periph_regs *get_reg_bank(int clkid) struct tegra_clk_periph_regs *get_reg_bank(int clkid)
{ {
int reg_bank = clkid / 32; int reg_bank = clkid / 32;
...@@ -133,8 +164,10 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid) ...@@ -133,8 +164,10 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid)
} }
} }
struct clk ** __init tegra_clk_init(int num, int banks) struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
{ {
clk_base = regs;
if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) if (WARN_ON(banks > ARRAY_SIZE(periph_regs)))
return NULL; return NULL;
...@@ -203,6 +236,17 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, ...@@ -203,6 +236,17 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
} }
} }
static struct reset_control_ops rst_ops = {
.assert = tegra_clk_rst_assert,
.deassert = tegra_clk_rst_deassert,
};
static struct reset_controller_dev rst_ctlr = {
.ops = &rst_ops,
.owner = THIS_MODULE,
.of_reset_n_cells = 1,
};
void __init tegra_add_of_provider(struct device_node *np) void __init tegra_add_of_provider(struct device_node *np)
{ {
int i; int i;
...@@ -220,6 +264,10 @@ void __init tegra_add_of_provider(struct device_node *np) ...@@ -220,6 +264,10 @@ void __init tegra_add_of_provider(struct device_node *np)
clk_data.clks = clks; clk_data.clks = clks;
clk_data.clk_num = clk_num; clk_data.clk_num = clk_num;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
rst_ctlr.of_node = np;
rst_ctlr.nr_resets = clk_num * 32;
reset_controller_register(&rst_ctlr);
} }
void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
......
...@@ -393,7 +393,6 @@ struct tegra_clk_periph_gate { ...@@ -393,7 +393,6 @@ struct tegra_clk_periph_gate {
#define TEGRA_PERIPH_NO_DIV BIT(4) #define TEGRA_PERIPH_NO_DIV BIT(4)
#define TEGRA_PERIPH_NO_GATE BIT(5) #define TEGRA_PERIPH_NO_GATE BIT(5)
void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
extern const struct clk_ops tegra_clk_periph_gate_ops; extern const struct clk_ops tegra_clk_periph_gate_ops;
struct clk *tegra_clk_register_periph_gate(const char *name, struct clk *tegra_clk_register_periph_gate(const char *name,
const char *parent_name, u8 gate_flags, void __iomem *clk_base, const char *parent_name, u8 gate_flags, void __iomem *clk_base,
...@@ -597,7 +596,7 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, ...@@ -597,7 +596,7 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
struct clk *clks[], int clk_max); struct clk *clks[], int clk_max);
struct tegra_clk_periph_regs *get_reg_bank(int clkid); struct tegra_clk_periph_regs *get_reg_bank(int clkid);
struct clk **tegra_clk_init(int num, int periph_banks); struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
......
/* /*
* DMA driver for Nvidia's Tegra20 APB DMA controller. * DMA driver for Nvidia's Tegra20 APB DMA controller.
* *
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -29,11 +29,12 @@ ...@@ -29,11 +29,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clk/tegra.h>
#include "dmaengine.h" #include "dmaengine.h"
...@@ -199,6 +200,7 @@ struct tegra_dma_channel { ...@@ -199,6 +200,7 @@ struct tegra_dma_channel {
void *callback_param; void *callback_param;
/* Channel-slave specific configuration */ /* Channel-slave specific configuration */
unsigned int slave_id;
struct dma_slave_config dma_sconfig; struct dma_slave_config dma_sconfig;
struct tegra_dma_channel_regs channel_reg; struct tegra_dma_channel_regs channel_reg;
}; };
...@@ -208,6 +210,7 @@ struct tegra_dma { ...@@ -208,6 +210,7 @@ struct tegra_dma {
struct dma_device dma_dev; struct dma_device dma_dev;
struct device *dev; struct device *dev;
struct clk *dma_clk; struct clk *dma_clk;
struct reset_control *rst;
spinlock_t global_lock; spinlock_t global_lock;
void __iomem *base_addr; void __iomem *base_addr;
const struct tegra_dma_chip_data *chip_data; const struct tegra_dma_chip_data *chip_data;
...@@ -339,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc, ...@@ -339,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc,
} }
memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
if (!tdc->slave_id)
tdc->slave_id = sconfig->slave_id;
tdc->config_init = true; tdc->config_init = true;
return 0; return 0;
} }
...@@ -941,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( ...@@ -941,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW;
csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
if (flags & DMA_PREP_INTERRUPT) if (flags & DMA_PREP_INTERRUPT)
csr |= TEGRA_APBDMA_CSR_IE_EOC; csr |= TEGRA_APBDMA_CSR_IE_EOC;
...@@ -1085,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( ...@@ -1085,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
csr |= TEGRA_APBDMA_CSR_FLOW; csr |= TEGRA_APBDMA_CSR_FLOW;
if (flags & DMA_PREP_INTERRUPT) if (flags & DMA_PREP_INTERRUPT)
csr |= TEGRA_APBDMA_CSR_IE_EOC; csr |= TEGRA_APBDMA_CSR_IE_EOC;
csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
...@@ -1205,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) ...@@ -1205,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
kfree(sg_req); kfree(sg_req);
} }
clk_disable_unprepare(tdma->dma_clk); clk_disable_unprepare(tdma->dma_clk);
tdc->slave_id = 0;
}
static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
struct tegra_dma *tdma = ofdma->of_dma_data;
struct dma_chan *chan;
struct tegra_dma_channel *tdc;
chan = dma_get_any_slave_channel(&tdma->dma_dev);
if (!chan)
return NULL;
tdc = to_tegra_dma_chan(chan);
tdc->slave_id = dma_spec->args[0];
return chan;
} }
/* Tegra20 specific DMA controller information */ /* Tegra20 specific DMA controller information */
...@@ -1282,6 +1306,12 @@ static int tegra_dma_probe(struct platform_device *pdev) ...@@ -1282,6 +1306,12 @@ static int tegra_dma_probe(struct platform_device *pdev)
return PTR_ERR(tdma->dma_clk); return PTR_ERR(tdma->dma_clk);
} }
tdma->rst = devm_reset_control_get(&pdev->dev, "dma");
if (IS_ERR(tdma->rst)) {
dev_err(&pdev->dev, "Error: Missing reset\n");
return PTR_ERR(tdma->rst);
}
spin_lock_init(&tdma->global_lock); spin_lock_init(&tdma->global_lock);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
...@@ -1302,9 +1332,9 @@ static int tegra_dma_probe(struct platform_device *pdev) ...@@ -1302,9 +1332,9 @@ static int tegra_dma_probe(struct platform_device *pdev)
} }
/* Reset DMA controller */ /* Reset DMA controller */
tegra_periph_reset_assert(tdma->dma_clk); reset_control_assert(tdma->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tdma->dma_clk); reset_control_deassert(tdma->rst);
/* Enable global DMA registers */ /* Enable global DMA registers */
tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE);
...@@ -1376,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev) ...@@ -1376,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev)
goto err_irq; goto err_irq;
} }
ret = of_dma_controller_register(pdev->dev.of_node,
tegra_dma_of_xlate, tdma);
if (ret < 0) {
dev_err(&pdev->dev,
"Tegra20 APB DMA OF registration failed %d\n", ret);
goto err_unregister_dma_dev;
}
dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n",
cdata->nr_channels); cdata->nr_channels);
return 0; return 0;
err_unregister_dma_dev:
dma_async_device_unregister(&tdma->dma_dev);
err_irq: err_irq:
while (--i >= 0) { while (--i >= 0) {
struct tegra_dma_channel *tdc = &tdma->channels[i]; struct tegra_dma_channel *tdc = &tdma->channels[i];
......
...@@ -2,6 +2,7 @@ config DRM_TEGRA ...@@ -2,6 +2,7 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM" bool "NVIDIA Tegra DRM"
depends on ARCH_TEGRA || ARCH_MULTIPLATFORM depends on ARCH_TEGRA || ARCH_MULTIPLATFORM
depends on DRM depends on DRM
depends on RESET_CONTROLLER
select TEGRA_HOST1X select TEGRA_HOST1X
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER select DRM_KMS_FB_HELPER
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/reset.h>
#include "dc.h" #include "dc.h"
#include "drm.h" #include "drm.h"
...@@ -712,7 +712,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) ...@@ -712,7 +712,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
unsigned long value; unsigned long value;
/* hardware initialization */ /* hardware initialization */
tegra_periph_reset_deassert(dc->clk); reset_control_deassert(dc->rst);
usleep_range(10000, 20000); usleep_range(10000, 20000);
if (dc->pipe) if (dc->pipe)
...@@ -1187,6 +1187,12 @@ static int tegra_dc_probe(struct platform_device *pdev) ...@@ -1187,6 +1187,12 @@ static int tegra_dc_probe(struct platform_device *pdev)
return PTR_ERR(dc->clk); return PTR_ERR(dc->clk);
} }
dc->rst = devm_reset_control_get(&pdev->dev, "dc");
if (IS_ERR(dc->rst)) {
dev_err(&pdev->dev, "failed to get reset\n");
return PTR_ERR(dc->rst);
}
err = clk_prepare_enable(dc->clk); err = clk_prepare_enable(dc->clk);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_fixed.h> #include <drm/drm_fixed.h>
struct reset_control;
struct tegra_fb { struct tegra_fb {
struct drm_framebuffer base; struct drm_framebuffer base;
struct tegra_bo **planes; struct tegra_bo **planes;
...@@ -93,6 +95,7 @@ struct tegra_dc { ...@@ -93,6 +95,7 @@ struct tegra_dc {
int pipe; int pipe;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
void __iomem *regs; void __iomem *regs;
int irq; int irq;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/host1x.h> #include <linux/host1x.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/tegra-powergate.h> #include <linux/tegra-powergate.h>
#include "drm.h" #include "drm.h"
...@@ -22,6 +23,8 @@ struct gr3d { ...@@ -22,6 +23,8 @@ struct gr3d {
struct host1x_channel *channel; struct host1x_channel *channel;
struct clk *clk_secondary; struct clk *clk_secondary;
struct clk *clk; struct clk *clk;
struct reset_control *rst_secondary;
struct reset_control *rst;
DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
}; };
...@@ -255,15 +258,29 @@ static int gr3d_probe(struct platform_device *pdev) ...@@ -255,15 +258,29 @@ static int gr3d_probe(struct platform_device *pdev)
return PTR_ERR(gr3d->clk); return PTR_ERR(gr3d->clk);
} }
gr3d->rst = devm_reset_control_get(&pdev->dev, "3d");
if (IS_ERR(gr3d->rst)) {
dev_err(&pdev->dev, "cannot get reset\n");
return PTR_ERR(gr3d->rst);
}
if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) {
gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2");
if (IS_ERR(gr3d->clk)) { if (IS_ERR(gr3d->clk)) {
dev_err(&pdev->dev, "cannot get secondary clock\n"); dev_err(&pdev->dev, "cannot get secondary clock\n");
return PTR_ERR(gr3d->clk); return PTR_ERR(gr3d->clk);
} }
gr3d->rst_secondary = devm_reset_control_get(&pdev->dev,
"3d2");
if (IS_ERR(gr3d->rst_secondary)) {
dev_err(&pdev->dev, "cannot get secondary reset\n");
return PTR_ERR(gr3d->rst_secondary);
}
} }
err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk); err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk,
gr3d->rst);
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, "failed to power up 3D unit\n"); dev_err(&pdev->dev, "failed to power up 3D unit\n");
return err; return err;
...@@ -271,7 +288,8 @@ static int gr3d_probe(struct platform_device *pdev) ...@@ -271,7 +288,8 @@ static int gr3d_probe(struct platform_device *pdev)
if (gr3d->clk_secondary) { if (gr3d->clk_secondary) {
err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1, err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1,
gr3d->clk_secondary); gr3d->clk_secondary,
gr3d->rst_secondary);
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"failed to power up secondary 3D unit\n"); "failed to power up secondary 3D unit\n");
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/hdmi.h> #include <linux/hdmi.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include "hdmi.h" #include "hdmi.h"
#include "drm.h" #include "drm.h"
...@@ -49,6 +49,7 @@ struct tegra_hdmi { ...@@ -49,6 +49,7 @@ struct tegra_hdmi {
struct clk *clk_parent; struct clk *clk_parent;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
const struct tegra_hdmi_config *config; const struct tegra_hdmi_config *config;
...@@ -731,9 +732,9 @@ static int tegra_output_hdmi_enable(struct tegra_output *output) ...@@ -731,9 +732,9 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
return err; return err;
} }
tegra_periph_reset_assert(hdmi->clk); reset_control_assert(hdmi->rst);
usleep_range(1000, 2000); usleep_range(1000, 2000);
tegra_periph_reset_deassert(hdmi->clk); reset_control_deassert(hdmi->rst);
tegra_dc_writel(dc, VSYNC_H_POSITION(1), tegra_dc_writel(dc, VSYNC_H_POSITION(1),
DC_DISP_DISP_TIMING_OPTIONS); DC_DISP_DISP_TIMING_OPTIONS);
...@@ -912,7 +913,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output) ...@@ -912,7 +913,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output)
{ {
struct tegra_hdmi *hdmi = to_hdmi(output); struct tegra_hdmi *hdmi = to_hdmi(output);
tegra_periph_reset_assert(hdmi->clk); reset_control_assert(hdmi->rst);
clk_disable(hdmi->clk); clk_disable(hdmi->clk);
regulator_disable(hdmi->pll); regulator_disable(hdmi->pll);
...@@ -1338,6 +1339,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev) ...@@ -1338,6 +1339,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
return PTR_ERR(hdmi->clk); return PTR_ERR(hdmi->clk);
} }
hdmi->rst = devm_reset_control_get(&pdev->dev, "hdmi");
if (IS_ERR(hdmi->rst)) {
dev_err(&pdev->dev, "failed to get reset\n");
return PTR_ERR(hdmi->rst);
}
err = clk_prepare(hdmi->clk); err = clk_prepare(hdmi->clk);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/clk/tegra.h> #include <linux/reset.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -160,6 +160,7 @@ struct tegra_i2c_dev { ...@@ -160,6 +160,7 @@ struct tegra_i2c_dev {
struct i2c_adapter adapter; struct i2c_adapter adapter;
struct clk *div_clk; struct clk *div_clk;
struct clk *fast_clk; struct clk *fast_clk;
struct reset_control *rst;
void __iomem *base; void __iomem *base;
int cont_id; int cont_id;
int irq; int irq;
...@@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) ...@@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
return err; return err;
} }
tegra_periph_reset_assert(i2c_dev->div_clk); reset_control_assert(i2c_dev->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(i2c_dev->div_clk); reset_control_deassert(i2c_dev->rst);
if (i2c_dev->is_dvc) if (i2c_dev->is_dvc)
tegra_dvc_init(i2c_dev); tegra_dvc_init(i2c_dev);
...@@ -743,6 +744,12 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -743,6 +744,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->cont_id = pdev->id; i2c_dev->cont_id = pdev->id;
i2c_dev->dev = &pdev->dev; i2c_dev->dev = &pdev->dev;
i2c_dev->rst = devm_reset_control_get(&pdev->dev, "i2c");
if (IS_ERR(i2c_dev->rst)) {
dev_err(&pdev->dev, "missing controller reset");
return PTR_ERR(i2c_dev->rst);
}
ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency", ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency",
&i2c_dev->bus_clk_rate); &i2c_dev->bus_clk_rate);
if (ret) if (ret)
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input/matrix_keypad.h> #include <linux/input/matrix_keypad.h>
#include <linux/clk/tegra.h> #include <linux/reset.h>
#include <linux/err.h> #include <linux/err.h>
#define KBC_MAX_KPENT 8 #define KBC_MAX_KPENT 8
...@@ -116,6 +116,7 @@ struct tegra_kbc { ...@@ -116,6 +116,7 @@ struct tegra_kbc {
u32 wakeup_key; u32 wakeup_key;
struct timer_list timer; struct timer_list timer;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
const struct tegra_kbc_hw_support *hw_support; const struct tegra_kbc_hw_support *hw_support;
int max_keys; int max_keys;
int num_rows_and_columns; int num_rows_and_columns;
...@@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) ...@@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
clk_prepare_enable(kbc->clk); clk_prepare_enable(kbc->clk);
/* Reset the KBC controller to clear all previous status.*/ /* Reset the KBC controller to clear all previous status.*/
tegra_periph_reset_assert(kbc->clk); reset_control_assert(kbc->rst);
udelay(100); udelay(100);
tegra_periph_reset_deassert(kbc->clk); reset_control_assert(kbc->rst);
udelay(100); udelay(100);
tegra_kbc_config_pins(kbc); tegra_kbc_config_pins(kbc);
...@@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) ...@@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev)
return PTR_ERR(kbc->clk); return PTR_ERR(kbc->clk);
} }
kbc->rst = devm_reset_control_get(&pdev->dev, "kbc");
if (IS_ERR(kbc->rst)) {
dev_err(&pdev->dev, "failed to get keyboard reset\n");
return PTR_ERR(kbc->rst);
}
/* /*
* The time delay between two consecutive reads of the FIFO is * The time delay between two consecutive reads of the FIFO is
* the sum of the repeat time and the time taken for scanning * the sum of the repeat time and the time taken for scanning
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -39,6 +38,7 @@ ...@@ -39,6 +38,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/tegra-cpuidle.h> #include <linux/tegra-cpuidle.h>
...@@ -259,10 +259,13 @@ struct tegra_pcie { ...@@ -259,10 +259,13 @@ struct tegra_pcie {
struct clk *pex_clk; struct clk *pex_clk;
struct clk *afi_clk; struct clk *afi_clk;
struct clk *pcie_xclk;
struct clk *pll_e; struct clk *pll_e;
struct clk *cml_clk; struct clk *cml_clk;
struct reset_control *pex_rst;
struct reset_control *afi_rst;
struct reset_control *pcie_xrst;
struct tegra_msi msi; struct tegra_msi msi;
struct list_head ports; struct list_head ports;
...@@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) ...@@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
pads_writel(pcie, value, PADS_CTL); pads_writel(pcie, value, PADS_CTL);
/* take the PCIe interface module out of reset */ /* take the PCIe interface module out of reset */
tegra_periph_reset_deassert(pcie->pcie_xclk); reset_control_deassert(pcie->pcie_xrst);
/* finally enable PCIe */ /* finally enable PCIe */
value = afi_readl(pcie, AFI_CONFIGURATION); value = afi_readl(pcie, AFI_CONFIGURATION);
...@@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) ...@@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
/* TODO: disable and unprepare clocks? */ /* TODO: disable and unprepare clocks? */
tegra_periph_reset_assert(pcie->pcie_xclk); reset_control_assert(pcie->pcie_xrst);
tegra_periph_reset_assert(pcie->afi_clk); reset_control_assert(pcie->afi_rst);
tegra_periph_reset_assert(pcie->pex_clk); reset_control_assert(pcie->pex_rst);
tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
...@@ -921,9 +924,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) ...@@ -921,9 +924,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
const struct tegra_pcie_soc_data *soc = pcie->soc_data; const struct tegra_pcie_soc_data *soc = pcie->soc_data;
int err; int err;
tegra_periph_reset_assert(pcie->pcie_xclk); reset_control_assert(pcie->pcie_xrst);
tegra_periph_reset_assert(pcie->afi_clk); reset_control_assert(pcie->afi_rst);
tegra_periph_reset_assert(pcie->pex_clk); reset_control_assert(pcie->pex_rst);
tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
...@@ -952,13 +955,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) ...@@ -952,13 +955,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
} }
err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
pcie->pex_clk); pcie->pex_clk,
pcie->pex_rst);
if (err) { if (err) {
dev_err(pcie->dev, "powerup sequence failed: %d\n", err); dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
return err; return err;
} }
tegra_periph_reset_deassert(pcie->afi_clk); reset_control_deassert(pcie->afi_rst);
err = clk_prepare_enable(pcie->afi_clk); err = clk_prepare_enable(pcie->afi_clk);
if (err < 0) { if (err < 0) {
...@@ -996,10 +1000,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) ...@@ -996,10 +1000,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
if (IS_ERR(pcie->afi_clk)) if (IS_ERR(pcie->afi_clk))
return PTR_ERR(pcie->afi_clk); return PTR_ERR(pcie->afi_clk);
pcie->pcie_xclk = devm_clk_get(pcie->dev, "pcie_xclk");
if (IS_ERR(pcie->pcie_xclk))
return PTR_ERR(pcie->pcie_xclk);
pcie->pll_e = devm_clk_get(pcie->dev, "pll_e"); pcie->pll_e = devm_clk_get(pcie->dev, "pll_e");
if (IS_ERR(pcie->pll_e)) if (IS_ERR(pcie->pll_e))
return PTR_ERR(pcie->pll_e); return PTR_ERR(pcie->pll_e);
...@@ -1013,6 +1013,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) ...@@ -1013,6 +1013,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
return 0; return 0;
} }
static int tegra_pcie_resets_get(struct tegra_pcie *pcie)
{
pcie->pex_rst = devm_reset_control_get(pcie->dev, "pex");
if (IS_ERR(pcie->pex_rst))
return PTR_ERR(pcie->pex_rst);
pcie->afi_rst = devm_reset_control_get(pcie->dev, "afi");
if (IS_ERR(pcie->afi_rst))
return PTR_ERR(pcie->afi_rst);
pcie->pcie_xrst = devm_reset_control_get(pcie->dev, "pcie_x");
if (IS_ERR(pcie->pcie_xrst))
return PTR_ERR(pcie->pcie_xrst);
return 0;
}
static int tegra_pcie_get_resources(struct tegra_pcie *pcie) static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
{ {
struct platform_device *pdev = to_platform_device(pcie->dev); struct platform_device *pdev = to_platform_device(pcie->dev);
...@@ -1025,6 +1042,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) ...@@ -1025,6 +1042,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
return err; return err;
} }
err = tegra_pcie_resets_get(pcie);
if (err) {
dev_err(&pdev->dev, "failed to get resets: %d\n", err);
return err;
}
err = tegra_pcie_power_on(pcie); err = tegra_pcie_power_on(pcie);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to power up: %d\n", err); dev_err(&pdev->dev, "failed to power up: %d\n", err);
......
...@@ -448,6 +448,7 @@ config SPI_MXS ...@@ -448,6 +448,7 @@ config SPI_MXS
config SPI_TEGRA114 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller" tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on RESET_CONTROLLER
help help
SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
is different than the older SoCs SPI controller and also register interface is different than the older SoCs SPI controller and also register interface
...@@ -456,6 +457,7 @@ config SPI_TEGRA114 ...@@ -456,6 +457,7 @@ config SPI_TEGRA114
config SPI_TEGRA20_SFLASH config SPI_TEGRA20_SFLASH
tristate "Nvidia Tegra20 Serial flash Controller" tristate "Nvidia Tegra20 Serial flash Controller"
depends on ARCH_TEGRA || COMPILE_TEST depends on ARCH_TEGRA || COMPILE_TEST
depends on RESET_CONTROLLER
help help
SPI driver for Nvidia Tegra20 Serial flash Controller interface. SPI driver for Nvidia Tegra20 Serial flash Controller interface.
The main usecase of this controller is to use spi flash as boot The main usecase of this controller is to use spi flash as boot
...@@ -464,6 +466,7 @@ config SPI_TEGRA20_SFLASH ...@@ -464,6 +466,7 @@ config SPI_TEGRA20_SFLASH
config SPI_TEGRA20_SLINK config SPI_TEGRA20_SLINK
tristate "Nvidia Tegra20/Tegra30 SLINK Controller" tristate "Nvidia Tegra20/Tegra30 SLINK Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on RESET_CONTROLLER
help help
SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
...@@ -34,6 +33,7 @@ ...@@ -34,6 +33,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#define SPI_COMMAND1 0x000 #define SPI_COMMAND1 0x000
...@@ -174,10 +174,10 @@ struct tegra_spi_data { ...@@ -174,10 +174,10 @@ struct tegra_spi_data {
spinlock_t lock; spinlock_t lock;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
void __iomem *base; void __iomem *base;
phys_addr_t phys; phys_addr_t phys;
unsigned irq; unsigned irq;
int dma_req_sel;
u32 spi_max_frequency; u32 spi_max_frequency;
u32 cur_speed; u32 cur_speed;
...@@ -600,15 +600,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, ...@@ -600,15 +600,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
dma_addr_t dma_phys; dma_addr_t dma_phys;
int ret; int ret;
struct dma_slave_config dma_sconfig; struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask); dma_chan = dma_request_slave_channel_reason(tspi->dev,
dma_cap_set(DMA_SLAVE, mask); dma_to_memory ? "rx" : "tx");
dma_chan = dma_request_channel(mask, NULL, NULL); if (IS_ERR(dma_chan)) {
if (!dma_chan) { ret = PTR_ERR(dma_chan);
dev_err(tspi->dev, if (ret != -EPROBE_DEFER)
"Dma channel is not available, will try later\n"); dev_err(tspi->dev,
return -EPROBE_DEFER; "Dma channel is not available: %d\n", ret);
return ret;
} }
dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size,
...@@ -619,7 +619,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, ...@@ -619,7 +619,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
return -ENOMEM; return -ENOMEM;
} }
dma_sconfig.slave_id = tspi->dma_req_sel;
if (dma_to_memory) { if (dma_to_memory) {
dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO; dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
...@@ -918,9 +917,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi) ...@@ -918,9 +917,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)
tspi->status_reg); tspi->status_reg);
dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n", dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n",
tspi->command1_reg, tspi->dma_control_reg); tspi->command1_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk); reset_control_assert(tspi->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tspi->clk); reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion); complete(&tspi->xfer_completion);
goto exit; goto exit;
} }
...@@ -990,9 +989,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi) ...@@ -990,9 +989,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)
tspi->status_reg); tspi->status_reg);
dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n", dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n",
tspi->command1_reg, tspi->dma_control_reg); tspi->command1_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk); reset_control_assert(tspi->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tspi->clk); reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion); complete(&tspi->xfer_completion);
spin_unlock_irqrestore(&tspi->lock, flags); spin_unlock_irqrestore(&tspi->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -1054,11 +1053,6 @@ static void tegra_spi_parse_dt(struct platform_device *pdev, ...@@ -1054,11 +1053,6 @@ static void tegra_spi_parse_dt(struct platform_device *pdev,
struct tegra_spi_data *tspi) struct tegra_spi_data *tspi)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 of_dma[2];
if (of_property_read_u32_array(np, "nvidia,dma-request-selector",
of_dma, 2) >= 0)
tspi->dma_req_sel = of_dma[1];
if (of_property_read_u32(np, "spi-max-frequency", if (of_property_read_u32(np, "spi-max-frequency",
&tspi->spi_max_frequency)) &tspi->spi_max_frequency))
...@@ -1127,25 +1121,25 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1127,25 +1121,25 @@ static int tegra_spi_probe(struct platform_device *pdev)
goto exit_free_irq; goto exit_free_irq;
} }
tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
goto exit_free_irq;
}
tspi->max_buf_size = SPI_FIFO_DEPTH << 2; tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
if (tspi->dma_req_sel) { ret = tegra_spi_init_dma_param(tspi, true);
ret = tegra_spi_init_dma_param(tspi, true); if (ret < 0)
if (ret < 0) { goto exit_free_irq;
dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); ret = tegra_spi_init_dma_param(tspi, false);
goto exit_free_irq; if (ret < 0)
} goto exit_rx_dma_free;
tspi->max_buf_size = tspi->dma_buf_size;
ret = tegra_spi_init_dma_param(tspi, false); init_completion(&tspi->tx_dma_complete);
if (ret < 0) { init_completion(&tspi->rx_dma_complete);
dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret);
goto exit_rx_dma_free;
}
tspi->max_buf_size = tspi->dma_buf_size;
init_completion(&tspi->tx_dma_complete);
init_completion(&tspi->rx_dma_complete);
}
init_completion(&tspi->xfer_completion); init_completion(&tspi->xfer_completion);
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/clk/tegra.h>
#define SPI_COMMAND 0x000 #define SPI_COMMAND 0x000
#define SPI_GO BIT(30) #define SPI_GO BIT(30)
...@@ -118,6 +118,7 @@ struct tegra_sflash_data { ...@@ -118,6 +118,7 @@ struct tegra_sflash_data {
spinlock_t lock; spinlock_t lock;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
void __iomem *base; void __iomem *base;
unsigned irq; unsigned irq;
u32 spi_max_frequency; u32 spi_max_frequency;
...@@ -389,9 +390,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd) ...@@ -389,9 +390,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd)
dev_err(tsd->dev, dev_err(tsd->dev,
"CpuXfer 0x%08x:0x%08x\n", tsd->command_reg, "CpuXfer 0x%08x:0x%08x\n", tsd->command_reg,
tsd->dma_control_reg); tsd->dma_control_reg);
tegra_periph_reset_assert(tsd->clk); reset_control_assert(tsd->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tsd->clk); reset_control_deassert(tsd->rst);
complete(&tsd->xfer_completion); complete(&tsd->xfer_completion);
goto exit; goto exit;
} }
...@@ -505,6 +506,13 @@ static int tegra_sflash_probe(struct platform_device *pdev) ...@@ -505,6 +506,13 @@ static int tegra_sflash_probe(struct platform_device *pdev)
goto exit_free_irq; goto exit_free_irq;
} }
tsd->rst = devm_reset_control_get(&pdev->dev, "spi");
if (IS_ERR(tsd->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tsd->rst);
goto exit_free_irq;
}
init_completion(&tsd->xfer_completion); init_completion(&tsd->xfer_completion);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) { if (!pm_runtime_enabled(&pdev->dev)) {
...@@ -520,9 +528,9 @@ static int tegra_sflash_probe(struct platform_device *pdev) ...@@ -520,9 +528,9 @@ static int tegra_sflash_probe(struct platform_device *pdev)
} }
/* Reset controller */ /* Reset controller */
tegra_periph_reset_assert(tsd->clk); reset_control_assert(tsd->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tsd->clk); reset_control_deassert(tsd->rst);
tsd->def_command_reg = SPI_M_S | SPI_CS_SW; tsd->def_command_reg = SPI_M_S | SPI_CS_SW;
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);
......
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/clk/tegra.h>
#define SLINK_COMMAND 0x000 #define SLINK_COMMAND 0x000
#define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0)
...@@ -167,10 +167,10 @@ struct tegra_slink_data { ...@@ -167,10 +167,10 @@ struct tegra_slink_data {
spinlock_t lock; spinlock_t lock;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
void __iomem *base; void __iomem *base;
phys_addr_t phys; phys_addr_t phys;
unsigned irq; unsigned irq;
int dma_req_sel;
u32 spi_max_frequency; u32 spi_max_frequency;
u32 cur_speed; u32 cur_speed;
...@@ -629,15 +629,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, ...@@ -629,15 +629,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
dma_addr_t dma_phys; dma_addr_t dma_phys;
int ret; int ret;
struct dma_slave_config dma_sconfig; struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask); dma_chan = dma_request_slave_channel_reason(tspi->dev,
dma_cap_set(DMA_SLAVE, mask); dma_to_memory ? "rx" : "tx");
dma_chan = dma_request_channel(mask, NULL, NULL); if (IS_ERR(dma_chan)) {
if (!dma_chan) { ret = PTR_ERR(dma_chan);
dev_err(tspi->dev, if (ret != -EPROBE_DEFER)
"Dma channel is not available, will try later\n"); dev_err(tspi->dev,
return -EPROBE_DEFER; "Dma channel is not available: %d\n", ret);
return ret;
} }
dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size,
...@@ -648,7 +648,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, ...@@ -648,7 +648,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
return -ENOMEM; return -ENOMEM;
} }
dma_sconfig.slave_id = tspi->dma_req_sel;
if (dma_to_memory) { if (dma_to_memory) {
dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
...@@ -884,9 +883,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) ...@@ -884,9 +883,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
dev_err(tspi->dev, dev_err(tspi->dev,
"CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
tspi->command2_reg, tspi->dma_control_reg); tspi->command2_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk); reset_control_assert(tspi->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tspi->clk); reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion); complete(&tspi->xfer_completion);
goto exit; goto exit;
} }
...@@ -957,9 +956,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi) ...@@ -957,9 +956,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi)
dev_err(tspi->dev, dev_err(tspi->dev,
"DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
tspi->command2_reg, tspi->dma_control_reg); tspi->command2_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk); reset_control_assert(tspi->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(tspi->clk); reset_control_assert(tspi->rst);
complete(&tspi->xfer_completion); complete(&tspi->xfer_completion);
spin_unlock_irqrestore(&tspi->lock, flags); spin_unlock_irqrestore(&tspi->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -1020,11 +1019,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data) ...@@ -1020,11 +1019,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data)
static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) static void tegra_slink_parse_dt(struct tegra_slink_data *tspi)
{ {
struct device_node *np = tspi->dev->of_node; struct device_node *np = tspi->dev->of_node;
u32 of_dma[2];
if (of_property_read_u32_array(np, "nvidia,dma-request-selector",
of_dma, 2) >= 0)
tspi->dma_req_sel = of_dma[1];
if (of_property_read_u32(np, "spi-max-frequency", if (of_property_read_u32(np, "spi-max-frequency",
&tspi->spi_max_frequency)) &tspi->spi_max_frequency))
...@@ -1118,25 +1112,25 @@ static int tegra_slink_probe(struct platform_device *pdev) ...@@ -1118,25 +1112,25 @@ static int tegra_slink_probe(struct platform_device *pdev)
goto exit_free_irq; goto exit_free_irq;
} }
tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
goto exit_free_irq;
}
tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; tspi->max_buf_size = SLINK_FIFO_DEPTH << 2;
tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
if (tspi->dma_req_sel) { ret = tegra_slink_init_dma_param(tspi, true);
ret = tegra_slink_init_dma_param(tspi, true); if (ret < 0)
if (ret < 0) { goto exit_free_irq;
dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); ret = tegra_slink_init_dma_param(tspi, false);
goto exit_free_irq; if (ret < 0)
} goto exit_rx_dma_free;
tspi->max_buf_size = tspi->dma_buf_size;
ret = tegra_slink_init_dma_param(tspi, false); init_completion(&tspi->tx_dma_complete);
if (ret < 0) { init_completion(&tspi->rx_dma_complete);
dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret);
goto exit_rx_dma_free;
}
tspi->max_buf_size = tspi->dma_buf_size;
init_completion(&tspi->tx_dma_complete);
init_completion(&tspi->rx_dma_complete);
}
init_completion(&tspi->xfer_completion); init_completion(&tspi->xfer_completion);
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/clk/tegra.h>
#include "nvec.h" #include "nvec.h"
...@@ -734,9 +733,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) ...@@ -734,9 +733,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec)
clk_prepare_enable(nvec->i2c_clk); clk_prepare_enable(nvec->i2c_clk);
tegra_periph_reset_assert(nvec->i2c_clk); reset_control_assert(nvec->rst);
udelay(2); udelay(2);
tegra_periph_reset_deassert(nvec->i2c_clk); reset_control_deassert(nvec->rst);
val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
...@@ -837,6 +836,12 @@ static int tegra_nvec_probe(struct platform_device *pdev) ...@@ -837,6 +836,12 @@ static int tegra_nvec_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
nvec->rst = devm_reset_control_get(&pdev->dev, "i2c");
if (IS_ERR(nvec->rst)) {
dev_err(nvec->dev, "failed to get controller reset\n");
return PTR_ERR(nvec->rst);
}
nvec->base = base; nvec->base = base;
nvec->irq = res->start; nvec->irq = res->start;
nvec->i2c_clk = i2c_clk; nvec->i2c_clk = i2c_clk;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/reset.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -109,7 +110,8 @@ struct nvec_msg { ...@@ -109,7 +110,8 @@ struct nvec_msg {
* @irq: The IRQ of the I2C device * @irq: The IRQ of the I2C device
* @i2c_addr: The address of the I2C slave * @i2c_addr: The address of the I2C slave
* @base: The base of the memory mapped region of the I2C device * @base: The base of the memory mapped region of the I2C device
* @clk: The clock of the I2C device * @i2c_clk: The clock of the I2C device
* @rst: The reset of the I2C device
* @notifier_list: Notifiers to be called on received messages, see * @notifier_list: Notifiers to be called on received messages, see
* nvec_register_notifier() * nvec_register_notifier()
* @rx_data: Received messages that have to be processed * @rx_data: Received messages that have to be processed
...@@ -139,6 +141,7 @@ struct nvec_chip { ...@@ -139,6 +141,7 @@ struct nvec_chip {
int i2c_addr; int i2c_addr;
void __iomem *base; void __iomem *base;
struct clk *i2c_clk; struct clk *i2c_clk;
struct reset_control *rst;
struct atomic_notifier_head notifier_list; struct atomic_notifier_head notifier_list;
struct list_head rx_data, tx_data; struct list_head rx_data, tx_data;
struct notifier_block nvec_status_notifier; struct notifier_block nvec_status_notifier;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
...@@ -44,8 +45,6 @@ ...@@ -44,8 +45,6 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#include <linux/clk/tegra.h>
#define TEGRA_UART_TYPE "TEGRA_UART" #define TEGRA_UART_TYPE "TEGRA_UART"
#define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE)
#define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3)
...@@ -103,6 +102,7 @@ struct tegra_uart_port { ...@@ -103,6 +102,7 @@ struct tegra_uart_port {
const struct tegra_uart_chip_data *cdata; const struct tegra_uart_chip_data *cdata;
struct clk *uart_clk; struct clk *uart_clk;
struct reset_control *rst;
unsigned int current_baud; unsigned int current_baud;
/* Register shadow */ /* Register shadow */
...@@ -120,7 +120,6 @@ struct tegra_uart_port { ...@@ -120,7 +120,6 @@ struct tegra_uart_port {
bool rx_timeout; bool rx_timeout;
int rx_in_progress; int rx_in_progress;
int symb_bit; int symb_bit;
int dma_req_sel;
struct dma_chan *rx_dma_chan; struct dma_chan *rx_dma_chan;
struct dma_chan *tx_dma_chan; struct dma_chan *tx_dma_chan;
...@@ -832,9 +831,9 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) ...@@ -832,9 +831,9 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
clk_prepare_enable(tup->uart_clk); clk_prepare_enable(tup->uart_clk);
/* Reset the UART controller to clear all previous status.*/ /* Reset the UART controller to clear all previous status.*/
tegra_periph_reset_assert(tup->uart_clk); reset_control_assert(tup->rst);
udelay(10); udelay(10);
tegra_periph_reset_deassert(tup->uart_clk); reset_control_deassert(tup->rst);
tup->rx_in_progress = 0; tup->rx_in_progress = 0;
tup->tx_in_progress = 0; tup->tx_in_progress = 0;
...@@ -910,15 +909,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, ...@@ -910,15 +909,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
dma_addr_t dma_phys; dma_addr_t dma_phys;
int ret; int ret;
struct dma_slave_config dma_sconfig; struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask); dma_chan = dma_request_slave_channel_reason(tup->uport.dev,
dma_cap_set(DMA_SLAVE, mask); dma_to_memory ? "rx" : "tx");
dma_chan = dma_request_channel(mask, NULL, NULL); if (IS_ERR(dma_chan)) {
if (!dma_chan) { ret = PTR_ERR(dma_chan);
dev_err(tup->uport.dev, dev_err(tup->uport.dev,
"Dma channel is not available, will try later\n"); "DMA channel alloc failed: %d\n", ret);
return -EPROBE_DEFER; return ret;
} }
if (dma_to_memory) { if (dma_to_memory) {
...@@ -938,7 +936,6 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, ...@@ -938,7 +936,6 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
dma_buf = tup->uport.state->xmit.buf; dma_buf = tup->uport.state->xmit.buf;
} }
dma_sconfig.slave_id = tup->dma_req_sel;
if (dma_to_memory) { if (dma_to_memory) {
dma_sconfig.src_addr = tup->uport.mapbase; dma_sconfig.src_addr = tup->uport.mapbase;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
...@@ -1222,17 +1219,8 @@ static int tegra_uart_parse_dt(struct platform_device *pdev, ...@@ -1222,17 +1219,8 @@ static int tegra_uart_parse_dt(struct platform_device *pdev,
struct tegra_uart_port *tup) struct tegra_uart_port *tup)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 of_dma[2];
int port; int port;
if (of_property_read_u32_array(np, "nvidia,dma-request-selector",
of_dma, 2) >= 0) {
tup->dma_req_sel = of_dma[1];
} else {
dev_err(&pdev->dev, "missing dma requestor in device tree\n");
return -EINVAL;
}
port = of_alias_get_id(np, "serial"); port = of_alias_get_id(np, "serial");
if (port < 0) { if (port < 0) {
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port);
...@@ -1320,6 +1308,12 @@ static int tegra_uart_probe(struct platform_device *pdev) ...@@ -1320,6 +1308,12 @@ static int tegra_uart_probe(struct platform_device *pdev)
return PTR_ERR(tup->uart_clk); return PTR_ERR(tup->uart_clk);
} }
tup->rst = devm_reset_control_get(&pdev->dev, "serial");
if (IS_ERR(tup->rst)) {
dev_err(&pdev->dev, "Couldn't get the reset\n");
return PTR_ERR(tup->rst);
}
u->iotype = UPIO_MEM32; u->iotype = UPIO_MEM32;
u->irq = platform_get_irq(pdev, 0); u->irq = platform_get_irq(pdev, 0);
u->regshift = 2; u->regshift = 2;
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -29,6 +28,7 @@ ...@@ -29,6 +28,7 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/usb/ehci_def.h> #include <linux/usb/ehci_def.h>
#include <linux/usb/tegra_usb_phy.h> #include <linux/usb/tegra_usb_phy.h>
...@@ -62,6 +62,7 @@ static int (*orig_hub_control)(struct usb_hcd *hcd, ...@@ -62,6 +62,7 @@ static int (*orig_hub_control)(struct usb_hcd *hcd,
struct tegra_ehci_hcd { struct tegra_ehci_hcd {
struct tegra_usb_phy *phy; struct tegra_usb_phy *phy;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
int port_resuming; int port_resuming;
bool needs_double_reset; bool needs_double_reset;
enum tegra_usb_phy_port_speed port_speed; enum tegra_usb_phy_port_speed port_speed;
...@@ -385,13 +386,20 @@ static int tegra_ehci_probe(struct platform_device *pdev) ...@@ -385,13 +386,20 @@ static int tegra_ehci_probe(struct platform_device *pdev)
goto cleanup_hcd_create; goto cleanup_hcd_create;
} }
tegra->rst = devm_reset_control_get(&pdev->dev, "usb");
if (IS_ERR(tegra->rst)) {
dev_err(&pdev->dev, "Can't get ehci reset\n");
err = PTR_ERR(tegra->rst);
goto cleanup_hcd_create;
}
err = clk_prepare_enable(tegra->clk); err = clk_prepare_enable(tegra->clk);
if (err) if (err)
goto cleanup_hcd_create; goto cleanup_hcd_create;
tegra_periph_reset_assert(tegra->clk); reset_control_assert(tegra->rst);
udelay(1); udelay(1);
tegra_periph_reset_deassert(tegra->clk); reset_control_deassert(tegra->rst);
u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);
if (IS_ERR(u_phy)) { if (IS_ERR(u_phy)) {
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
#define TEGRA20_CLK_OWR 71 #define TEGRA20_CLK_OWR 71
#define TEGRA20_CLK_AFI 72 #define TEGRA20_CLK_AFI 72
#define TEGRA20_CLK_CSITE 73 #define TEGRA20_CLK_CSITE 73
#define TEGRA20_CLK_PCIE_XCLK 74 /* 74 */
#define TEGRA20_CLK_AVPUCQ 75 #define TEGRA20_CLK_AVPUCQ 75
#define TEGRA20_CLK_LA 76 #define TEGRA20_CLK_LA 76
/* 77 */ /* 77 */
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
#define TEGRA30_CLK_OWR 71 #define TEGRA30_CLK_OWR 71
#define TEGRA30_CLK_AFI 72 #define TEGRA30_CLK_AFI 72
#define TEGRA30_CLK_CSITE 73 #define TEGRA30_CLK_CSITE 73
#define TEGRA30_CLK_PCIEX 74 /* 74 */
#define TEGRA30_CLK_AVPUCQ 75 #define TEGRA30_CLK_AVPUCQ 75
#define TEGRA30_CLK_LA 76 #define TEGRA30_CLK_LA 76
/* 77 */ /* 77 */
......
...@@ -120,13 +120,6 @@ static inline void tegra_cpu_clock_resume(void) ...@@ -120,13 +120,6 @@ static inline void tegra_cpu_clock_resume(void)
} }
#endif #endif
#ifdef CONFIG_ARCH_TEGRA
void tegra_periph_reset_deassert(struct clk *c);
void tegra_periph_reset_assert(struct clk *c);
#else
static inline void tegra_periph_reset_deassert(struct clk *c) {}
static inline void tegra_periph_reset_assert(struct clk *c) {}
#endif
void tegra_clocks_apply_init_table(void); void tegra_clocks_apply_init_table(void);
#endif /* __LINUX_CLK_TEGRA_H_ */ #endif /* __LINUX_CLK_TEGRA_H_ */
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define _MACH_TEGRA_POWERGATE_H_ #define _MACH_TEGRA_POWERGATE_H_
struct clk; struct clk;
struct reset_control;
#define TEGRA_POWERGATE_CPU 0 #define TEGRA_POWERGATE_CPU 0
#define TEGRA_POWERGATE_3D 1 #define TEGRA_POWERGATE_3D 1
...@@ -52,7 +53,8 @@ int tegra_powergate_power_off(int id); ...@@ -52,7 +53,8 @@ int tegra_powergate_power_off(int id);
int tegra_powergate_remove_clamping(int id); int tegra_powergate_remove_clamping(int id);
/* Must be called with clk disabled, and returns with clk enabled */ /* Must be called with clk disabled, and returns with clk enabled */
int tegra_powergate_sequence_power_up(int id, struct clk *clk); int tegra_powergate_sequence_power_up(int id, struct clk *clk,
struct reset_control *rst);
#else #else
static inline int tegra_powergate_is_powered(int id) static inline int tegra_powergate_is_powered(int id)
{ {
...@@ -74,7 +76,8 @@ static inline int tegra_powergate_remove_clamping(int id) ...@@ -74,7 +76,8 @@ static inline int tegra_powergate_remove_clamping(int id)
return -ENOSYS; return -ENOSYS;
} }
static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk) static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk,
struct reset_control *rst);
{ {
return -ENOSYS; return -ENOSYS;
} }
......
config SND_SOC_TEGRA config SND_SOC_TEGRA
tristate "SoC Audio for the Tegra System-on-Chip" tristate "SoC Audio for the Tegra System-on-Chip"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on COMMON_CLK
depends on RESET_CONTROLLER
select REGMAP_MMIO select REGMAP_MMIO
select SND_SOC_GENERIC_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM
help help
......
...@@ -313,7 +313,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ...@@ -313,7 +313,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
{ {
struct tegra20_ac97 *ac97; struct tegra20_ac97 *ac97;
struct resource *mem; struct resource *mem;
u32 of_dma[2];
void __iomem *regs; void __iomem *regs;
int ret = 0; int ret = 0;
...@@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ...@@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
goto err_clk_put; goto err_clk_put;
} }
if (of_property_read_u32_array(pdev->dev.of_node,
"nvidia,dma-request-selector",
of_dma, 2) < 0) {
dev_err(&pdev->dev, "No DMA resource\n");
ret = -ENODEV;
goto err_clk_put;
}
ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node, ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
"nvidia,codec-reset-gpio", 0); "nvidia,codec-reset-gpio", 0);
if (gpio_is_valid(ac97->reset_gpio)) { if (gpio_is_valid(ac97->reset_gpio)) {
...@@ -380,12 +371,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ...@@ -380,12 +371,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ac97->capture_dma_data.maxburst = 4; ac97->capture_dma_data.maxburst = 4;
ac97->capture_dma_data.slave_id = of_dma[1];
ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ac97->playback_dma_data.maxburst = 4; ac97->playback_dma_data.maxburst = 4;
ac97->playback_dma_data.slave_id = of_dma[1];
ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
if (ret) if (ret)
......
...@@ -339,9 +339,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = { ...@@ -339,9 +339,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = {
static int tegra20_i2s_platform_probe(struct platform_device *pdev) static int tegra20_i2s_platform_probe(struct platform_device *pdev)
{ {
struct tegra20_i2s *i2s; struct tegra20_i2s *i2s;
struct resource *mem, *memregion, *dmareq; struct resource *mem, *memregion;
u32 of_dma[2];
u32 dma_ch;
void __iomem *regs; void __iomem *regs;
int ret; int ret;
...@@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) ...@@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
goto err_clk_put; goto err_clk_put;
} }
dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmareq) {
if (of_property_read_u32_array(pdev->dev.of_node,
"nvidia,dma-request-selector",
of_dma, 2) < 0) {
dev_err(&pdev->dev, "No DMA resource\n");
ret = -ENODEV;
goto err_clk_put;
}
dma_ch = of_dma[1];
} else {
dma_ch = dmareq->start;
}
memregion = devm_request_mem_region(&pdev->dev, mem->start, memregion = devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem), DRV_NAME); resource_size(mem), DRV_NAME);
if (!memregion) { if (!memregion) {
...@@ -410,12 +394,10 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) ...@@ -410,12 +394,10 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->capture_dma_data.maxburst = 4; i2s->capture_dma_data.maxburst = 4;
i2s->capture_dma_data.slave_id = dma_ch;
i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4; i2s->playback_dma_data.maxburst = 4;
i2s->playback_dma_data.slave_id = dma_ch;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) { if (!pm_runtime_enabled(&pdev->dev)) {
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clk/tegra.h>
#include <sound/soc.h> #include <sound/soc.h>
#include "tegra30_ahub.h" #include "tegra30_ahub.h"
...@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev) ...@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
} }
int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
dma_addr_t *fiforeg, char *dmachan, int dmachan_len,
unsigned int *reqsel) dma_addr_t *fiforeg)
{ {
int channel; int channel;
u32 reg, val; u32 reg, val;
...@@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, ...@@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
__set_bit(channel, ahub->rx_usage); __set_bit(channel, ahub->rx_usage);
*rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel; *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
snprintf(dmachan, dmachan_len, "rx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO + *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
*reqsel = ahub->dma_sel + channel;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
...@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, ...@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
(channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
...@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif) ...@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val; int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg); val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val); tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
...@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif) ...@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val; int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg); val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val); tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
...@@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif) ...@@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
dma_addr_t *fiforeg, char *dmachan, int dmachan_len,
unsigned int *reqsel) dma_addr_t *fiforeg)
{ {
int channel; int channel;
u32 reg, val; u32 reg, val;
...@@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, ...@@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
__set_bit(channel, ahub->tx_usage); __set_bit(channel, ahub->tx_usage);
*txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel; *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
snprintf(dmachan, dmachan_len, "tx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO + *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
*reqsel = ahub->dma_sel + channel;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
...@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, ...@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
(channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
...@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif) ...@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val; int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg); val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val); tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
...@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif) ...@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val; int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL + reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg); val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val); tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo); EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
...@@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, ...@@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg; int reg;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_AUDIO_RX + reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 1 << txcif); tegra30_audio_write(reg, 1 << txcif);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source); EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
...@@ -293,35 +321,51 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) ...@@ -293,35 +321,51 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg; int reg;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_AUDIO_RX + reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 0); tegra30_audio_write(reg, 0);
pm_runtime_put(ahub->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
#define CLK_LIST_MASK_TEGRA30 BIT(0) #define MOD_LIST_MASK_TEGRA30 BIT(0)
#define CLK_LIST_MASK_TEGRA114 BIT(1) #define MOD_LIST_MASK_TEGRA114 BIT(1)
#define MOD_LIST_MASK_TEGRA124 BIT(2)
#define CLK_LIST_MASK_TEGRA30_OR_LATER \ #define MOD_LIST_MASK_TEGRA30_OR_LATER \
(CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114) (MOD_LIST_MASK_TEGRA30 | MOD_LIST_MASK_TEGRA114 | \
MOD_LIST_MASK_TEGRA124)
#define MOD_LIST_MASK_TEGRA114_OR_LATER \
(MOD_LIST_MASK_TEGRA114 | MOD_LIST_MASK_TEGRA124)
static const struct { static const struct {
const char *clk_name; const char *rst_name;
u32 clk_list_mask; u32 mod_list_mask;
} configlink_clocks[] = { } configlink_mods[] = {
{ "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER }, { "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "amx", CLK_LIST_MASK_TEGRA114 }, { "amx", MOD_LIST_MASK_TEGRA114_OR_LATER },
{ "adx", CLK_LIST_MASK_TEGRA114 }, { "adx", MOD_LIST_MASK_TEGRA114_OR_LATER },
{ "amx1", MOD_LIST_MASK_TEGRA124 },
{ "adx1", MOD_LIST_MASK_TEGRA124 },
{ "afc0", MOD_LIST_MASK_TEGRA124 },
{ "afc1", MOD_LIST_MASK_TEGRA124 },
{ "afc2", MOD_LIST_MASK_TEGRA124 },
{ "afc3", MOD_LIST_MASK_TEGRA124 },
{ "afc4", MOD_LIST_MASK_TEGRA124 },
{ "afc5", MOD_LIST_MASK_TEGRA124 },
}; };
#define LAST_REG(name) \ #define LAST_REG(name) \
...@@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { ...@@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
}; };
static struct tegra30_ahub_soc_data soc_data_tegra30 = { static struct tegra30_ahub_soc_data soc_data_tegra30 = {
.clk_list_mask = CLK_LIST_MASK_TEGRA30, .mod_list_mask = MOD_LIST_MASK_TEGRA30,
.set_audio_cif = tegra30_ahub_set_cif, .set_audio_cif = tegra30_ahub_set_cif,
}; };
static struct tegra30_ahub_soc_data soc_data_tegra114 = { static struct tegra30_ahub_soc_data soc_data_tegra114 = {
.clk_list_mask = CLK_LIST_MASK_TEGRA114, .mod_list_mask = MOD_LIST_MASK_TEGRA114,
.set_audio_cif = tegra30_ahub_set_cif, .set_audio_cif = tegra30_ahub_set_cif,
}; };
static struct tegra30_ahub_soc_data soc_data_tegra124 = { static struct tegra30_ahub_soc_data soc_data_tegra124 = {
.clk_list_mask = CLK_LIST_MASK_TEGRA114, .mod_list_mask = MOD_LIST_MASK_TEGRA124,
.set_audio_cif = tegra124_ahub_set_cif, .set_audio_cif = tegra124_ahub_set_cif,
}; };
...@@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev) ...@@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
{ {
const struct of_device_id *match; const struct of_device_id *match;
const struct tegra30_ahub_soc_data *soc_data; const struct tegra30_ahub_soc_data *soc_data;
struct clk *clk; struct reset_control *rst;
int i; int i;
struct resource *res0, *res1, *region; struct resource *res0, *res1, *region;
u32 of_dma[2];
void __iomem *regs_apbif, *regs_ahub; void __iomem *regs_apbif, *regs_ahub;
int ret = 0; int ret = 0;
...@@ -495,19 +538,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev) ...@@ -495,19 +538,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
* operate correctly, all devices on this bus must be out of reset. * operate correctly, all devices on this bus must be out of reset.
* Ensure that here. * Ensure that here.
*/ */
for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) {
if (!(configlink_clocks[i].clk_list_mask & if (!(configlink_mods[i].mod_list_mask &
soc_data->clk_list_mask)) soc_data->mod_list_mask))
continue; continue;
clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name);
if (IS_ERR(clk)) { rst = reset_control_get(&pdev->dev,
dev_err(&pdev->dev, "Can't get clock %s\n", configlink_mods[i].rst_name);
configlink_clocks[i].clk_name); if (IS_ERR(rst)) {
ret = PTR_ERR(clk); dev_err(&pdev->dev, "Can't get reset %s\n",
configlink_mods[i].rst_name);
ret = PTR_ERR(rst);
goto err; goto err;
} }
tegra_periph_reset_deassert(clk);
clk_put(clk); ret = reset_control_deassert(rst);
reset_control_put(rst);
if (ret)
goto err;
} }
ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
...@@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev) ...@@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
goto err_clk_put_d_audio; goto err_clk_put_d_audio;
} }
if (of_property_read_u32_array(pdev->dev.of_node,
"nvidia,dma-request-selector",
of_dma, 2) < 0) {
dev_err(&pdev->dev,
"Missing property nvidia,dma-request-selector\n");
ret = -ENODEV;
goto err_clk_put_d_audio;
}
ahub->dma_sel = of_dma[1];
res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res0) { if (!res0) {
dev_err(&pdev->dev, "No apbif memory resource\n"); dev_err(&pdev->dev, "No apbif memory resource\n");
......
...@@ -465,15 +465,15 @@ enum tegra30_ahub_rxcif { ...@@ -465,15 +465,15 @@ enum tegra30_ahub_rxcif {
}; };
extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
dma_addr_t *fiforeg, char *dmachan, int dmachan_len,
unsigned int *reqsel); dma_addr_t *fiforeg);
extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
dma_addr_t *fiforeg, char *dmachan, int dmachan_len,
unsigned int *reqsel); dma_addr_t *fiforeg);
extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
...@@ -502,7 +502,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg, ...@@ -502,7 +502,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg,
struct tegra30_ahub_cif_conf *conf); struct tegra30_ahub_cif_conf *conf);
struct tegra30_ahub_soc_data { struct tegra30_ahub_soc_data {
u32 clk_list_mask; u32 mod_list_mask;
void (*set_audio_cif)(struct regmap *regmap, void (*set_audio_cif)(struct regmap *regmap,
unsigned int reg, unsigned int reg,
struct tegra30_ahub_cif_conf *conf); struct tegra30_ahub_cif_conf *conf);
...@@ -524,7 +524,6 @@ struct tegra30_ahub { ...@@ -524,7 +524,6 @@ struct tegra30_ahub {
struct device *dev; struct device *dev;
struct clk *clk_d_audio; struct clk *clk_d_audio;
struct clk *clk_apbif; struct clk *clk_apbif;
int dma_sel;
resource_size_t apbif_addr; resource_size_t apbif_addr;
struct regmap *regmap_apbif; struct regmap *regmap_apbif;
struct regmap *regmap_ahub; struct regmap *regmap_ahub;
......
...@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev) ...@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
return 0; return 0;
} }
static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
int ret;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
&i2s->playback_dma_data.addr,
&i2s->playback_dma_data.slave_id);
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4;
tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
i2s->playback_fifo_cif);
} else {
ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
&i2s->capture_dma_data.addr,
&i2s->capture_dma_data.slave_id);
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->capture_dma_data.maxburst = 4;
tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
i2s->capture_i2s_cif);
}
return ret;
}
static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
} else {
tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
}
}
static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt) unsigned int fmt)
{ {
...@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) ...@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
} }
static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
.startup = tegra30_i2s_startup,
.shutdown = tegra30_i2s_shutdown,
.set_fmt = tegra30_i2s_set_fmt, .set_fmt = tegra30_i2s_set_fmt,
.hw_params = tegra30_i2s_hw_params, .hw_params = tegra30_i2s_hw_params,
.trigger = tegra30_i2s_trigger, .trigger = tegra30_i2s_trigger,
...@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) ...@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
goto err_pm_disable; goto err_pm_disable;
} }
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4;
ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
i2s->playback_dma_chan,
sizeof(i2s->playback_dma_chan),
&i2s->playback_dma_data.addr);
if (ret) {
dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
goto err_suspend;
}
ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
i2s->playback_fifo_cif);
if (ret) {
dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
goto err_free_tx_fifo;
}
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->capture_dma_data.maxburst = 4;
ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
i2s->capture_dma_chan,
sizeof(i2s->capture_dma_chan),
&i2s->capture_dma_data.addr);
if (ret) {
dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
goto err_unroute_tx_fifo;
}
ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
i2s->capture_i2s_cif);
if (ret) {
dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
goto err_free_rx_fifo;
}
ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
&i2s->dai, 1); &i2s->dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
ret = -ENOMEM; ret = -ENOMEM;
goto err_suspend; goto err_unroute_rx_fifo;
} }
ret = tegra_pcm_platform_register(&pdev->dev); ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
&i2s->dma_config, i2s->playback_dma_chan,
i2s->capture_dma_chan);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
goto err_unregister_component; goto err_unregister_component;
...@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) ...@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
err_unregister_component: err_unregister_component:
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
err_unroute_rx_fifo:
tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
err_free_rx_fifo:
tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
err_unroute_tx_fifo:
tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
err_free_tx_fifo:
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
err_suspend: err_suspend:
if (!pm_runtime_status_suspended(&pdev->dev)) if (!pm_runtime_status_suspended(&pdev->dev))
tegra30_i2s_runtime_suspend(&pdev->dev); tegra30_i2s_runtime_suspend(&pdev->dev);
...@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) ...@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
tegra_pcm_platform_unregister(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
clk_put(i2s->clk_i2s); clk_put(i2s->clk_i2s);
return 0; return 0;
......
...@@ -238,11 +238,14 @@ struct tegra30_i2s { ...@@ -238,11 +238,14 @@ struct tegra30_i2s {
struct clk *clk_i2s; struct clk *clk_i2s;
enum tegra30_ahub_txcif capture_i2s_cif; enum tegra30_ahub_txcif capture_i2s_cif;
enum tegra30_ahub_rxcif capture_fifo_cif; enum tegra30_ahub_rxcif capture_fifo_cif;
char capture_dma_chan[8];
struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data;
enum tegra30_ahub_rxcif playback_i2s_cif; enum tegra30_ahub_rxcif playback_i2s_cif;
enum tegra30_ahub_txcif playback_fifo_cif; enum tegra30_ahub_txcif playback_fifo_cif;
char playback_dma_chan[8];
struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data;
struct regmap *regmap; struct regmap *regmap;
struct snd_dmaengine_pcm_config dma_config;
}; };
#endif #endif
...@@ -61,12 +61,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = { ...@@ -61,12 +61,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = {
int tegra_pcm_platform_register(struct device *dev) int tegra_pcm_platform_register(struct device *dev)
{ {
return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0);
SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_COMPAT);
} }
EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
int tegra_pcm_platform_register_with_chan_names(struct device *dev,
struct snd_dmaengine_pcm_config *config,
char *txdmachan, char *rxdmachan)
{
*config = tegra_dmaengine_pcm_config;
config->dma_dev = dev->parent;
config->chan_names[0] = txdmachan;
config->chan_names[1] = rxdmachan;
return snd_dmaengine_pcm_register(dev, config, 0);
}
EXPORT_SYMBOL_GPL(tegra_pcm_platform_register_with_chan_names);
void tegra_pcm_platform_unregister(struct device *dev) void tegra_pcm_platform_unregister(struct device *dev)
{ {
return snd_dmaengine_pcm_unregister(dev); return snd_dmaengine_pcm_unregister(dev);
......
...@@ -31,7 +31,12 @@ ...@@ -31,7 +31,12 @@
#ifndef __TEGRA_PCM_H__ #ifndef __TEGRA_PCM_H__
#define __TEGRA_PCM_H__ #define __TEGRA_PCM_H__
struct snd_dmaengine_pcm_config;
int tegra_pcm_platform_register(struct device *dev); int tegra_pcm_platform_register(struct device *dev);
int tegra_pcm_platform_register_with_chan_names(struct device *dev,
struct snd_dmaengine_pcm_config *config,
char *txdmachan, char *rxdmachan);
void tegra_pcm_platform_unregister(struct device *dev); void tegra_pcm_platform_unregister(struct device *dev);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment