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:
- compatible : Should contain "nvidia,tegra<chip>-pmc".
- reg : Offset and length of the register set for the device
- 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:
"pclk" (The Tegra clock of that name),
"clk32k_in" (The 32KHz clock input to Tegra).
......
......@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<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:
......@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra114-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
usb@c5004000 {
......
......@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<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:
......@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra124-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
usb@c5004000 {
......
......@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<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:
......@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra20-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
usb@c5004000 {
......
......@@ -15,6 +15,9 @@ Required properties :
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<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:
......@@ -23,6 +26,7 @@ Example SoC include file:
compatible = "nvidia,tegra30-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
usb@c5004000 {
......
......@@ -5,6 +5,16 @@ Required properties:
- reg: Should contain DMA registers location and length. This shuld include
all of the per-channel registers.
- 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:
......@@ -27,4 +37,8 @@ apbdma: dma@6000a000 {
0 149 0x04
0 150 0x04
0 151 0x04 >;
clocks = <&tegra_car 34>;
resets = <&tegra_car 34>;
reset-names = "dma";
#dma-cells = <1>;
};
......@@ -9,6 +9,12 @@ Required properties:
- #size-cells: The number of cells used to represent the size of an address
range in the host1x address space. Should be 1.
- ranges: The mapping of the host1x address space to the CPU address space.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- host1x
The host1x top-level node defines a number of children, each representing one
of the following host1x client modules:
......@@ -19,6 +25,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-mpe"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- mpe
- vi: video input
......@@ -26,6 +38,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-vi"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- vi
- epp: encoder pre-processor
......@@ -33,6 +51,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-epp"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- epp
- isp: image signal processor
......@@ -40,6 +64,12 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-isp"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- isp
- gr2d: 2D graphics engine
......@@ -47,12 +77,30 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-gr2d"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- 2d
- gr3d: 3D graphics engine
Required properties:
- compatible: "nvidia,tegra<chip>-gr3d"
- reg: Physical base address and length of the controller's registers.
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
(This property may be omitted if the only clock in the list is "3d")
- 3d
This MUST be the first entry.
- 3d2 (Only required on SoCs with two 3D clocks)
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- 3d
- 3d2 (Only required on SoCs with two 3D clocks)
- dc: display controller
......@@ -60,6 +108,16 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-dc"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- dc
This MUST be the first entry.
- parent
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- dc
Each display controller node has a child node, named "rgb", that represents
the RGB output associated with the controller. It can take the following
......@@ -76,6 +134,16 @@ of the following host1x client modules:
- interrupts: The interrupt outputs from the controller.
- vdd-supply: regulator for supply voltage
- pll-supply: regulator for PLL
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- hdmi
This MUST be the first entry.
- parent
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
- hdmi
Optional properties:
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
......@@ -88,12 +156,24 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-tvo"
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- dsi: display serial interface
Required properties:
- compatible: "nvidia,tegra<chip>-dsi"
- reg: Physical base address and length of the controller's registers.
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- dsi
This MUST be the first entry.
- 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:
......@@ -105,6 +185,9 @@ Example:
reg = <0x50000000 0x00024000>;
interrupts = <0 65 0x04 /* mpcore syncpt */
0 67 0x04>; /* mpcore general */
clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
resets = <&tegra_car 28>;
reset-names = "host1x";
#address-cells = <1>;
#size-cells = <1>;
......@@ -115,41 +198,64 @@ Example:
compatible = "nvidia,tegra20-mpe";
reg = <0x54040000 0x00040000>;
interrupts = <0 68 0x04>;
clocks = <&tegra_car TEGRA20_CLK_MPE>;
resets = <&tegra_car 60>;
reset-names = "mpe";
};
vi {
compatible = "nvidia,tegra20-vi";
reg = <0x54080000 0x00040000>;
interrupts = <0 69 0x04>;
clocks = <&tegra_car TEGRA20_CLK_VI>;
resets = <&tegra_car 100>;
reset-names = "vi";
};
epp {
compatible = "nvidia,tegra20-epp";
reg = <0x540c0000 0x00040000>;
interrupts = <0 70 0x04>;
clocks = <&tegra_car TEGRA20_CLK_EPP>;
resets = <&tegra_car 19>;
reset-names = "epp";
};
isp {
compatible = "nvidia,tegra20-isp";
reg = <0x54100000 0x00040000>;
interrupts = <0 71 0x04>;
clocks = <&tegra_car TEGRA20_CLK_ISP>;
resets = <&tegra_car 23>;
reset-names = "isp";
};
gr2d {
compatible = "nvidia,tegra20-gr2d";
reg = <0x54140000 0x00040000>;
interrupts = <0 72 0x04>;
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
resets = <&tegra_car 21>;
reset-names = "2d";
};
gr3d {
compatible = "nvidia,tegra20-gr3d";
reg = <0x54180000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
resets = <&tegra_car 24>;
reset-names = "3d";
};
dc@54200000 {
compatible = "nvidia,tegra20-dc";
reg = <0x54200000 0x00040000>;
interrupts = <0 73 0x04>;
clocks = <&tegra_car TEGRA20_CLK_DISP1>,
<&tegra_car TEGRA20_CLK_PLL_P>;
clock-names = "disp1", "parent";
resets = <&tegra_car 27>;
reset-names = "dc";
rgb {
status = "disabled";
......@@ -160,6 +266,11 @@ Example:
compatible = "nvidia,tegra20-dc";
reg = <0x54240000 0x00040000>;
interrupts = <0 74 0x04>;
clocks = <&tegra_car TEGRA20_CLK_DISP2>,
<&tegra_car TEGRA20_CLK_PLL_P>;
clock-names = "disp2", "parent";
resets = <&tegra_car 26>;
reset-names = "dc";
rgb {
status = "disabled";
......@@ -170,6 +281,11 @@ Example:
compatible = "nvidia,tegra20-hdmi";
reg = <0x54280000 0x00040000>;
interrupts = <0 75 0x04>;
clocks = <&tegra_car TEGRA20_CLK_HDMI>,
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
clock-names = "hdmi", "parent";
resets = <&tegra_car 51>;
reset-names = "hdmi";
status = "disabled";
};
......@@ -177,12 +293,18 @@ Example:
compatible = "nvidia,tegra20-tvo";
reg = <0x542c0000 0x00040000>;
interrupts = <0 76 0x04>;
clocks = <&tegra_car TEGRA20_CLK_TVO>;
status = "disabled";
};
dsi {
compatible = "nvidia,tegra20-dsi";
reg = <0x54300000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_DSI>,
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
clock-names = "dsi", "parent";
resets = <&tegra_car 48>;
reset-names = "dsi";
status = "disabled";
};
};
......
......@@ -39,12 +39,23 @@ Required properties:
- interrupts: Should contain I2C controller interrupts.
- address-cells: Address cells for I2C device address.
- size-cells: Size of the I2C device address.
- clocks: Clock ID as per
Documentation/devicetree/bindings/clock/tegra<chip-id>.txt
for I2C controller.
- clock-names: Name of the clock:
Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk".
Tegra114 I2C controller: "div-clk".
- 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
- 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:
......@@ -56,5 +67,9 @@ Example:
#size-cells = <0>;
clocks = <&tegra_car 12>, <&tegra_car 124>;
clock-names = "div-clk", "fast-clk";
resets = <&tegra_car 12>;
reset-names = "i2c";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
status = "disabled";
};
......@@ -13,6 +13,12 @@ Required properties:
array of pin numbers which is used as column.
- linux,keymap: The keymap for keys as described in the binding document
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
matrix-keyboard bindings:
......@@ -31,6 +37,9 @@ keyboard: keyboard {
compatible = "nvidia,tegra20-kbc";
reg = <0x7000e200 0x100>;
interrupts = <0 85 0x04>;
clocks = <&tegra_car 36>;
resets = <&tegra_car 36>;
reset-names = "kbc";
nvidia,ghost-filter;
nvidia,debounce-delay-ms = <640>;
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.
Required properties:
- 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:
- power-gpios : Specify GPIOs for power control
......@@ -18,6 +24,9 @@ sdhci@c8000200 {
compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000200 0x200>;
interrupts = <47>;
clocks = <&tegra_car 14>;
resets = <&tegra_car 14>;
reset-names = "sdhci";
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */
......
......@@ -7,3 +7,15 @@ Required properties:
- clock-frequency : the frequency of the i2c bus
- gpios : the gpio used for ec request
- 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:
- 0xc2000000: prefetchable memory region
Please refer to the standard PCI bus binding document for a more detailed
explanation.
- clocks: List of clock inputs of the controller. Must contain an entry for
each entry in the clock-names property.
- 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:
"pex": The Tegra clock of that name
"afi": The Tegra clock of that name
"pcie_xclk": The Tegra clock of that name
"pll_e": The Tegra clock of that name
"cml": The Tegra clock of that name (not required for Tegra20)
- pex
- afi
- pll_e
- cml (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.
......@@ -91,9 +96,10 @@ SoC DTSI:
0x82000000 0 0xa0000000 0xa0000000 0 0x10000000 /* non-prefetchable memory */
0xc2000000 0 0xb0000000 0xb0000000 0 0x10000000>; /* prefetchable memory */
clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>,
<&tegra_car 118>;
clock-names = "pex", "afi", "pcie_xclk", "pll_e";
clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 118>;
clock-names = "pex", "afi", "pll_e";
resets = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled";
pci@1,0 {
......
......@@ -7,6 +7,12 @@ Required properties:
- 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
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:
......@@ -14,4 +20,7 @@ Example:
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car 17>;
resets = <&tegra_car 17>;
reset-names = "pwm";
};
......@@ -9,6 +9,8 @@ Required properties:
- compatible : should be "nvidia,tegra20-rtc".
- reg : Specifies base physical address and size of the registers.
- interrupts : A single interrupt specifier.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
Example:
......@@ -16,4 +18,5 @@ timer {
compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
clocks = <&tegra_car 4>;
};
......@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart".
- reg: Should contain UART controller registers location and length.
- interrupts: Should contain UART controller interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for this UART 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:
- 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:
- nvidia,enable-modem-interrupt: Enable modem interrupts. Should be enable
......@@ -18,7 +27,11 @@ serial@70006000 {
reg = <0x70006000 0x40>;
reg-shift = <2>;
interrupts = <0 36 0x04>;
nvidia,dma-request-selector = <&apbdma 8>;
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";
};
......@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties:
- compatible : "nvidia,tegra-audio-alc5632"
- 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:
"pll_a" (The Tegra clock of that name),
"pll_a_out0" (The Tegra clock of that name),
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- 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,
......
......@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex, with RT5640 CODEC
Required properties:
- compatible : "nvidia,tegra-audio-rt5640"
- 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:
"pll_a" (The Tegra clock of that name),
"pll_a_out0" (The Tegra clock of that name),
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- 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,
......
......@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties:
- compatible : "nvidia,tegra-audio-wm8753"
- 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:
"pll_a" (The Tegra clock of that name),
"pll_a_out0" (The Tegra clock of that name),
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- 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,
......
......@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties:
- compatible : "nvidia,tegra-audio-wm8903"
- 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:
"pll_a" (The Tegra clock of that name),
"pll_a_out0" (The Tegra clock of that name),
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- 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,
......
......@@ -3,10 +3,11 @@ NVIDIA Tegra audio complex
Required properties:
- compatible : "nvidia,tegra-audio-wm9712"
- 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:
"pll_a" (The Tegra clock of that name),
"pll_a_out0" (The Tegra clock of that name),
"mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- pll_a
- pll_a_out0
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- 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,
......
......@@ -4,19 +4,33 @@ Required properties:
- compatible : "nvidia,tegra20-ac97"
- reg : Should contain AC97 controller registers location and length
- interrupts : Should contain AC97 interrupt
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for the AC97 controller
- resets : Must contain an entry for each entry in reset-names.
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
of the GPIO used to reset the external AC97 codec
- nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number
of the GPIO corresponding with the AC97 DAP _FS line
Example:
ac97@70002000 {
compatible = "nvidia,tegra20-ac97";
reg = <0x70002000 0x200>;
interrupts = <0 81 0x04>;
nvidia,dma-request-selector = <&apbdma 12>;
nvidia,codec-reset-gpio = <&gpio 170 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:
- compatible : "nvidia,tegra20-i2s"
- reg : Should contain I2S registers location and length
- interrupts : Should contain I2S interrupt
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for this I2S controller
- 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
- 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:
......@@ -13,5 +22,9 @@ i2s@70002800 {
compatible = "nvidia,tegra20-i2s";
reg = <0x70002800 0x200>;
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:
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
- Tegra114 requires an additional entry, for the APBIF2 register block.
- interrupts : Should contain AHUB interrupt
- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each
entry contains the Tegra DMA controller's phandle and request selector.
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.
- 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:
- Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0,
dam1, dam2, spdif_in.
- Tegra114: Additionally requires amx, adx.
- d_audio
- apbif
- 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.
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>;
- #size-cells : For the configlink bus. Should be <1>.
......@@ -35,13 +65,20 @@ ahub@70080000 {
reg = <0x70080000 0x200 0x70080200 0x100>;
interrupts = < 0 103 0x04 >;
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 102>, <&tegra_car 108>, <&tegra_car 109>,
<&tegra_car 110>, <&tegra_car 162>;
clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
<&tegra_car 110>, <&tegra_car 10>;
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
"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;
#address-cells = <1>;
#size-cells = <1>;
......
......@@ -3,13 +3,22 @@ NVIDIA Tegra30 I2S controller
Required properties:
- compatible : "nvidia,tegra30-i2s"
- 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)
first, tx (capture) second. See nvidia,tegra30-ahub.txt for values.
Example:
i2s@70002800 {
i2s@70080300 {
compatible = "nvidia,tegra30-i2s";
reg = <0x70080300 0x100>;
nvidia,ahub-cif-ids = <4 4>;
clocks = <&tegra_car 11>;
resets = <&tegra_car 11>;
reset-names = "i2s";
};
......@@ -4,10 +4,19 @@ Required properties:
- compatible : should be "nvidia,tegra114-spi".
- reg: Should contain SPI registers location and length.
- interrupts: Should contain SPI interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for this SPI controller.
- This is also require clock named "spi" as per binding document
Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names : Must include the following entries:
- spi
- 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
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
Recommended properties:
- spi-max-frequency: Definition as per
......@@ -18,9 +27,14 @@ spi@7000d600 {
compatible = "nvidia,tegra114-spi";
reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#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";
};
......@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra20-sflash".
- reg: Should contain SFLASH registers location and length.
- interrupts: Should contain SFLASH interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for this SFLASH 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:
- 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:
- spi-max-frequency: Definition as per
......@@ -17,10 +26,13 @@ spi@7000c380 {
compatible = "nvidia,tegra20-sflash";
reg = <0x7000c380 0x80>;
interrupts = <0 39 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#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";
};
......@@ -4,8 +4,17 @@ Required properties:
- compatible : should be "nvidia,tegra20-slink", "nvidia,tegra30-slink".
- reg: Should contain SLINK registers location and length.
- interrupts: Should contain SLINK interrupts.
- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
request selector for this SLINK 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:
- 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:
- spi-max-frequency: Definition as per
......@@ -17,10 +26,13 @@ spi@7000d600 {
compatible = "nvidia,tegra20-slink";
reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>;
nvidia,dma-request-selector = <&apbdma 16>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#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";
};
......@@ -8,6 +8,8 @@ Required properties:
- compatible : should be "nvidia,tegra20-timer".
- reg : Specifies base physical address and size of the registers.
- 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:
......@@ -18,4 +20,5 @@ timer {
0 1 0x04
0 41 0x04
0 42 0x04>;
clocks = <&tegra_car 132>;
};
......@@ -10,6 +10,8 @@ Required properties:
- reg : Specifies base physical address and size of the registers.
- 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.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
timer {
compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
......@@ -20,4 +22,5 @@ timer {
0 42 0x04
0 121 0x04
0 122 0x04>;
clocks = <&tegra_car 214>;
};
......@@ -8,7 +8,12 @@ and additions :
Required properties :
- compatible : Should be "nvidia,tegra20-ehci".
- 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:
- nvidia,needs-double-reset : boolean is to be set for some of the Tegra20
......
This diff is collapsed.
......@@ -280,6 +280,8 @@ nvec {
clocks = <&tegra_car TEGRA20_CLK_I2C3>,
<&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
clock-names = "div-clk", "fast-clk";
resets = <&tegra_car 67>;
reset-names = "i2c";
};
i2c@7000d000 {
......
This diff is collapsed.
This diff is collapsed.
......@@ -14,6 +14,8 @@ config ARCH_TEGRA
select MIGHT_HAVE_CACHE_L2X0
select MIGHT_HAVE_PCI
select PINCTRL
select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER
select SOC_BUS
select SPARSE_IRQ
select USB_ARCH_HAS_EHCI if USB_SUPPORT
......
......@@ -25,6 +25,7 @@
#include <linux/export.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/reset.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/clk/tegra.h>
......@@ -144,11 +145,12 @@ int tegra_powergate_remove_clamping(int id)
}
/* 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;
tegra_periph_reset_assert(clk);
reset_control_assert(rst);
ret = tegra_powergate_power_on(id);
if (ret)
......@@ -165,7 +167,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk)
goto err_clamp;
udelay(10);
tegra_periph_reset_deassert(clk);
reset_control_deassert(rst);
return 0;
......
......@@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock);
#define read_rst(gate) \
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) \
writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
......@@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw)
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 = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
......
......@@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *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 = {
.get_parent = clk_periph_get_parent,
.set_parent = clk_periph_set_parent,
......
......@@ -1460,7 +1460,8 @@ static void __init tegra114_clock_init(struct device_node *np)
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)
return;
......
......@@ -1398,7 +1398,7 @@ static void __init tegra124_clock_init(struct device_node *np)
return;
}
clks = tegra_clk_init(TEGRA124_CLK_CLK_MAX, 6);
clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6);
if (!clks)
return;
......
......@@ -468,7 +468,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP },
{ .con_id = "pex", .dt_id = TEGRA20_CLK_PEX },
{ .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 = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 },
{ .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K },
......@@ -834,11 +833,6 @@ static void __init tegra20_periph_clk_init(void)
periph_clk_enb_refcnt);
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 */
clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT,
26000000);
......@@ -1109,7 +1103,8 @@ static void __init tegra20_clock_init(struct device_node *np)
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)
return;
......
......@@ -649,7 +649,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .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 = "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_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN },
{ .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF },
......@@ -1150,11 +1149,6 @@ static void __init tegra30_periph_clk_init(void)
periph_clk_enb_refcnt);
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 */
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
ARRAY_SIZE(mux_pllmcp_clkm),
......@@ -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_CML1, "tegra_sata_cml", NULL),
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_CLK_MAX, NULL, NULL), /* MUST be the last entry */
};
......@@ -1427,7 +1420,8 @@ static void __init tegra30_clock_init(struct device_node *np)
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)
return;
......
......@@ -18,6 +18,8 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/clk/tegra.h>
#include <linux/reset-controller.h>
#include <linux/tegra-soc.h>
#include "clk.h"
......@@ -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)
{
int reg_bank = clkid / 32;
......@@ -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)))
return NULL;
......@@ -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)
{
int i;
......@@ -220,6 +264,10 @@ void __init tegra_add_of_provider(struct device_node *np)
clk_data.clks = clks;
clk_data.clk_num = clk_num;
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)
......
......@@ -393,7 +393,6 @@ struct tegra_clk_periph_gate {
#define TEGRA_PERIPH_NO_DIV BIT(4)
#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;
struct clk *tegra_clk_register_periph_gate(const char *name,
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,
struct clk *clks[], int clk_max);
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);
......
/*
* 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
* under the terms and conditions of the GNU General Public License,
......@@ -29,11 +29,12 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/clk/tegra.h>
#include "dmaengine.h"
......@@ -199,6 +200,7 @@ struct tegra_dma_channel {
void *callback_param;
/* Channel-slave specific configuration */
unsigned int slave_id;
struct dma_slave_config dma_sconfig;
struct tegra_dma_channel_regs channel_reg;
};
......@@ -208,6 +210,7 @@ struct tegra_dma {
struct dma_device dma_dev;
struct device *dev;
struct clk *dma_clk;
struct reset_control *rst;
spinlock_t global_lock;
void __iomem *base_addr;
const struct tegra_dma_chip_data *chip_data;
......@@ -339,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc,
}
memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
if (!tdc->slave_id)
tdc->slave_id = sconfig->slave_id;
tdc->config_init = true;
return 0;
}
......@@ -941,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
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)
csr |= TEGRA_APBDMA_CSR_IE_EOC;
......@@ -1085,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
csr |= TEGRA_APBDMA_CSR_FLOW;
if (flags & DMA_PREP_INTERRUPT)
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;
......@@ -1205,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
kfree(sg_req);
}
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 */
......@@ -1282,6 +1306,12 @@ static int tegra_dma_probe(struct platform_device *pdev)
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);
pm_runtime_enable(&pdev->dev);
......@@ -1302,9 +1332,9 @@ static int tegra_dma_probe(struct platform_device *pdev)
}
/* Reset DMA controller */
tegra_periph_reset_assert(tdma->dma_clk);
reset_control_assert(tdma->rst);
udelay(2);
tegra_periph_reset_deassert(tdma->dma_clk);
reset_control_deassert(tdma->rst);
/* Enable global DMA registers */
tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE);
......@@ -1376,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev)
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",
cdata->nr_channels);
return 0;
err_unregister_dma_dev:
dma_async_device_unregister(&tdma->dma_dev);
err_irq:
while (--i >= 0) {
struct tegra_dma_channel *tdc = &tdma->channels[i];
......
......@@ -2,6 +2,7 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on ARCH_TEGRA || ARCH_MULTIPLATFORM
depends on DRM
depends on RESET_CONTROLLER
select TEGRA_HOST1X
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
......
......@@ -8,8 +8,8 @@
*/
#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
#include <linux/reset.h>
#include "dc.h"
#include "drm.h"
......@@ -712,7 +712,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
unsigned long value;
/* hardware initialization */
tegra_periph_reset_deassert(dc->clk);
reset_control_deassert(dc->rst);
usleep_range(10000, 20000);
if (dc->pipe)
......@@ -1187,6 +1187,12 @@ static int tegra_dc_probe(struct platform_device *pdev)
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);
if (err < 0)
return err;
......
......@@ -19,6 +19,8 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_fixed.h>
struct reset_control;
struct tegra_fb {
struct drm_framebuffer base;
struct tegra_bo **planes;
......@@ -93,6 +95,7 @@ struct tegra_dc {
int pipe;
struct clk *clk;
struct reset_control *rst;
void __iomem *regs;
int irq;
......
......@@ -11,6 +11,7 @@
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/tegra-powergate.h>
#include "drm.h"
......@@ -22,6 +23,8 @@ struct gr3d {
struct host1x_channel *channel;
struct clk *clk_secondary;
struct clk *clk;
struct reset_control *rst_secondary;
struct reset_control *rst;
DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
};
......@@ -255,15 +258,29 @@ static int gr3d_probe(struct platform_device *pdev)
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")) {
gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2");
if (IS_ERR(gr3d->clk)) {
dev_err(&pdev->dev, "cannot get secondary clock\n");
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) {
dev_err(&pdev->dev, "failed to power up 3D unit\n");
return err;
......@@ -271,7 +288,8 @@ static int gr3d_probe(struct platform_device *pdev)
if (gr3d->clk_secondary) {
err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1,
gr3d->clk_secondary);
gr3d->clk_secondary,
gr3d->rst_secondary);
if (err < 0) {
dev_err(&pdev->dev,
"failed to power up secondary 3D unit\n");
......
......@@ -8,10 +8,10 @@
*/
#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
#include <linux/hdmi.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include "hdmi.h"
#include "drm.h"
......@@ -49,6 +49,7 @@ struct tegra_hdmi {
struct clk *clk_parent;
struct clk *clk;
struct reset_control *rst;
const struct tegra_hdmi_config *config;
......@@ -731,9 +732,9 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
return err;
}
tegra_periph_reset_assert(hdmi->clk);
reset_control_assert(hdmi->rst);
usleep_range(1000, 2000);
tegra_periph_reset_deassert(hdmi->clk);
reset_control_deassert(hdmi->rst);
tegra_dc_writel(dc, VSYNC_H_POSITION(1),
DC_DISP_DISP_TIMING_OPTIONS);
......@@ -912,7 +913,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output)
{
struct tegra_hdmi *hdmi = to_hdmi(output);
tegra_periph_reset_assert(hdmi->clk);
reset_control_assert(hdmi->rst);
clk_disable(hdmi->clk);
regulator_disable(hdmi->pll);
......@@ -1338,6 +1339,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
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);
if (err < 0)
return err;
......
......@@ -27,7 +27,7 @@
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/clk/tegra.h>
#include <linux/reset.h>
#include <asm/unaligned.h>
......@@ -160,6 +160,7 @@ struct tegra_i2c_dev {
struct i2c_adapter adapter;
struct clk *div_clk;
struct clk *fast_clk;
struct reset_control *rst;
void __iomem *base;
int cont_id;
int irq;
......@@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
return err;
}
tegra_periph_reset_assert(i2c_dev->div_clk);
reset_control_assert(i2c_dev->rst);
udelay(2);
tegra_periph_reset_deassert(i2c_dev->div_clk);
reset_control_deassert(i2c_dev->rst);
if (i2c_dev->is_dvc)
tegra_dvc_init(i2c_dev);
......@@ -743,6 +744,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->cont_id = pdev->id;
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",
&i2c_dev->bus_clk_rate);
if (ret)
......
......@@ -31,7 +31,7 @@
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/input/matrix_keypad.h>
#include <linux/clk/tegra.h>
#include <linux/reset.h>
#include <linux/err.h>
#define KBC_MAX_KPENT 8
......@@ -116,6 +116,7 @@ struct tegra_kbc {
u32 wakeup_key;
struct timer_list timer;
struct clk *clk;
struct reset_control *rst;
const struct tegra_kbc_hw_support *hw_support;
int max_keys;
int num_rows_and_columns;
......@@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
clk_prepare_enable(kbc->clk);
/* Reset the KBC controller to clear all previous status.*/
tegra_periph_reset_assert(kbc->clk);
reset_control_assert(kbc->rst);
udelay(100);
tegra_periph_reset_deassert(kbc->clk);
reset_control_assert(kbc->rst);
udelay(100);
tegra_kbc_config_pins(kbc);
......@@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev)
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 sum of the repeat time and the time taken for scanning
......
......@@ -25,7 +25,6 @@
*/
#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/interrupt.h>
......@@ -39,6 +38,7 @@
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/tegra-cpuidle.h>
......@@ -259,10 +259,13 @@ struct tegra_pcie {
struct clk *pex_clk;
struct clk *afi_clk;
struct clk *pcie_xclk;
struct clk *pll_e;
struct clk *cml_clk;
struct reset_control *pex_rst;
struct reset_control *afi_rst;
struct reset_control *pcie_xrst;
struct tegra_msi msi;
struct list_head ports;
......@@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
pads_writel(pcie, value, PADS_CTL);
/* take the PCIe interface module out of reset */
tegra_periph_reset_deassert(pcie->pcie_xclk);
reset_control_deassert(pcie->pcie_xrst);
/* finally enable PCIe */
value = afi_readl(pcie, AFI_CONFIGURATION);
......@@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
/* TODO: disable and unprepare clocks? */
tegra_periph_reset_assert(pcie->pcie_xclk);
tegra_periph_reset_assert(pcie->afi_clk);
tegra_periph_reset_assert(pcie->pex_clk);
reset_control_assert(pcie->pcie_xrst);
reset_control_assert(pcie->afi_rst);
reset_control_assert(pcie->pex_rst);
tegra_powergate_power_off(TEGRA_POWERGATE_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;
int err;
tegra_periph_reset_assert(pcie->pcie_xclk);
tegra_periph_reset_assert(pcie->afi_clk);
tegra_periph_reset_assert(pcie->pex_clk);
reset_control_assert(pcie->pcie_xrst);
reset_control_assert(pcie->afi_rst);
reset_control_assert(pcie->pex_rst);
tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
......@@ -952,13 +955,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
}
err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
pcie->pex_clk);
pcie->pex_clk,
pcie->pex_rst);
if (err) {
dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
return err;
}
tegra_periph_reset_deassert(pcie->afi_clk);
reset_control_deassert(pcie->afi_rst);
err = clk_prepare_enable(pcie->afi_clk);
if (err < 0) {
......@@ -996,10 +1000,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
if (IS_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");
if (IS_ERR(pcie->pll_e))
return PTR_ERR(pcie->pll_e);
......@@ -1013,6 +1013,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
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)
{
struct platform_device *pdev = to_platform_device(pcie->dev);
......@@ -1025,6 +1042,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
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);
if (err) {
dev_err(&pdev->dev, "failed to power up: %d\n", err);
......
......@@ -448,6 +448,7 @@ config SPI_MXS
config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on RESET_CONTROLLER
help
SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
is different than the older SoCs SPI controller and also register interface
......@@ -456,6 +457,7 @@ config SPI_TEGRA114
config SPI_TEGRA20_SFLASH
tristate "Nvidia Tegra20 Serial flash Controller"
depends on ARCH_TEGRA || COMPILE_TEST
depends on RESET_CONTROLLER
help
SPI driver for Nvidia Tegra20 Serial flash Controller interface.
The main usecase of this controller is to use spi flash as boot
......@@ -464,6 +466,7 @@ config SPI_TEGRA20_SFLASH
config SPI_TEGRA20_SLINK
tristate "Nvidia Tegra20/Tegra30 SLINK Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on RESET_CONTROLLER
help
SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
......
......@@ -17,7 +17,6 @@
*/
#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
......@@ -34,6 +33,7 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
#define SPI_COMMAND1 0x000
......@@ -174,10 +174,10 @@ struct tegra_spi_data {
spinlock_t lock;
struct clk *clk;
struct reset_control *rst;
void __iomem *base;
phys_addr_t phys;
unsigned irq;
int dma_req_sel;
u32 spi_max_frequency;
u32 cur_speed;
......@@ -600,15 +600,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
dma_addr_t dma_phys;
int ret;
struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_chan = dma_request_channel(mask, NULL, NULL);
if (!dma_chan) {
dev_err(tspi->dev,
"Dma channel is not available, will try later\n");
return -EPROBE_DEFER;
dma_chan = dma_request_slave_channel_reason(tspi->dev,
dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
if (ret != -EPROBE_DEFER)
dev_err(tspi->dev,
"Dma channel is not available: %d\n", ret);
return ret;
}
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,
return -ENOMEM;
}
dma_sconfig.slave_id = tspi->dma_req_sel;
if (dma_to_memory) {
dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO;
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)
tspi->status_reg);
dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n",
tspi->command1_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk);
reset_control_assert(tspi->rst);
udelay(2);
tegra_periph_reset_deassert(tspi->clk);
reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion);
goto exit;
}
......@@ -990,9 +989,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)
tspi->status_reg);
dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n",
tspi->command1_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk);
reset_control_assert(tspi->rst);
udelay(2);
tegra_periph_reset_deassert(tspi->clk);
reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion);
spin_unlock_irqrestore(&tspi->lock, flags);
return IRQ_HANDLED;
......@@ -1054,11 +1053,6 @@ static void tegra_spi_parse_dt(struct platform_device *pdev,
struct tegra_spi_data *tspi)
{
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",
&tspi->spi_max_frequency))
......@@ -1127,25 +1121,25 @@ static int tegra_spi_probe(struct platform_device *pdev)
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->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
if (tspi->dma_req_sel) {
ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0) {
dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret);
goto exit_free_irq;
}
ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0) {
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);
}
ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0)
goto exit_free_irq;
ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0)
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);
......
......@@ -32,8 +32,8 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
#include <linux/clk/tegra.h>
#define SPI_COMMAND 0x000
#define SPI_GO BIT(30)
......@@ -118,6 +118,7 @@ struct tegra_sflash_data {
spinlock_t lock;
struct clk *clk;
struct reset_control *rst;
void __iomem *base;
unsigned irq;
u32 spi_max_frequency;
......@@ -389,9 +390,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd)
dev_err(tsd->dev,
"CpuXfer 0x%08x:0x%08x\n", tsd->command_reg,
tsd->dma_control_reg);
tegra_periph_reset_assert(tsd->clk);
reset_control_assert(tsd->rst);
udelay(2);
tegra_periph_reset_deassert(tsd->clk);
reset_control_deassert(tsd->rst);
complete(&tsd->xfer_completion);
goto exit;
}
......@@ -505,6 +506,13 @@ static int tegra_sflash_probe(struct platform_device *pdev)
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);
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
......@@ -520,9 +528,9 @@ static int tegra_sflash_probe(struct platform_device *pdev)
}
/* Reset controller */
tegra_periph_reset_assert(tsd->clk);
reset_control_assert(tsd->rst);
udelay(2);
tegra_periph_reset_deassert(tsd->clk);
reset_control_deassert(tsd->rst);
tsd->def_command_reg = SPI_M_S | SPI_CS_SW;
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);
......
......@@ -33,8 +33,8 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
#include <linux/clk/tegra.h>
#define SLINK_COMMAND 0x000
#define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0)
......@@ -167,10 +167,10 @@ struct tegra_slink_data {
spinlock_t lock;
struct clk *clk;
struct reset_control *rst;
void __iomem *base;
phys_addr_t phys;
unsigned irq;
int dma_req_sel;
u32 spi_max_frequency;
u32 cur_speed;
......@@ -629,15 +629,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
dma_addr_t dma_phys;
int ret;
struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_chan = dma_request_channel(mask, NULL, NULL);
if (!dma_chan) {
dev_err(tspi->dev,
"Dma channel is not available, will try later\n");
return -EPROBE_DEFER;
dma_chan = dma_request_slave_channel_reason(tspi->dev,
dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
if (ret != -EPROBE_DEFER)
dev_err(tspi->dev,
"Dma channel is not available: %d\n", ret);
return ret;
}
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,
return -ENOMEM;
}
dma_sconfig.slave_id = tspi->dma_req_sel;
if (dma_to_memory) {
dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO;
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)
dev_err(tspi->dev,
"CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
tspi->command2_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk);
reset_control_assert(tspi->rst);
udelay(2);
tegra_periph_reset_deassert(tspi->clk);
reset_control_deassert(tspi->rst);
complete(&tspi->xfer_completion);
goto exit;
}
......@@ -957,9 +956,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi)
dev_err(tspi->dev,
"DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
tspi->command2_reg, tspi->dma_control_reg);
tegra_periph_reset_assert(tspi->clk);
reset_control_assert(tspi->rst);
udelay(2);
tegra_periph_reset_deassert(tspi->clk);
reset_control_assert(tspi->rst);
complete(&tspi->xfer_completion);
spin_unlock_irqrestore(&tspi->lock, flags);
return IRQ_HANDLED;
......@@ -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)
{
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",
&tspi->spi_max_frequency))
......@@ -1118,25 +1112,25 @@ static int tegra_slink_probe(struct platform_device *pdev)
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->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
if (tspi->dma_req_sel) {
ret = tegra_slink_init_dma_param(tspi, true);
if (ret < 0) {
dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret);
goto exit_free_irq;
}
ret = tegra_slink_init_dma_param(tspi, false);
if (ret < 0) {
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);
}
ret = tegra_slink_init_dma_param(tspi, true);
if (ret < 0)
goto exit_free_irq;
ret = tegra_slink_init_dma_param(tspi, false);
if (ret < 0)
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);
......
......@@ -36,7 +36,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/clk/tegra.h>
#include "nvec.h"
......@@ -734,9 +733,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec)
clk_prepare_enable(nvec->i2c_clk);
tegra_periph_reset_assert(nvec->i2c_clk);
reset_control_assert(nvec->rst);
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 |
(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
......@@ -837,6 +836,12 @@ static int tegra_nvec_probe(struct platform_device *pdev)
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->irq = res->start;
nvec->i2c_clk = i2c_clk;
......
......@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
......@@ -109,7 +110,8 @@ struct nvec_msg {
* @irq: The IRQ of the I2C device
* @i2c_addr: The address of the I2C slave
* @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
* nvec_register_notifier()
* @rx_data: Received messages that have to be processed
......@@ -139,6 +141,7 @@ struct nvec_chip {
int i2c_addr;
void __iomem *base;
struct clk *i2c_clk;
struct reset_control *rst;
struct atomic_notifier_head notifier_list;
struct list_head rx_data, tx_data;
struct notifier_block nvec_status_notifier;
......
......@@ -34,6 +34,7 @@
#include <linux/of_device.h>
#include <linux/pagemap.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
......@@ -44,8 +45,6 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/clk/tegra.h>
#define TEGRA_UART_TYPE "TEGRA_UART"
#define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE)
#define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3)
......@@ -103,6 +102,7 @@ struct tegra_uart_port {
const struct tegra_uart_chip_data *cdata;
struct clk *uart_clk;
struct reset_control *rst;
unsigned int current_baud;
/* Register shadow */
......@@ -120,7 +120,6 @@ struct tegra_uart_port {
bool rx_timeout;
int rx_in_progress;
int symb_bit;
int dma_req_sel;
struct dma_chan *rx_dma_chan;
struct dma_chan *tx_dma_chan;
......@@ -832,9 +831,9 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
clk_prepare_enable(tup->uart_clk);
/* Reset the UART controller to clear all previous status.*/
tegra_periph_reset_assert(tup->uart_clk);
reset_control_assert(tup->rst);
udelay(10);
tegra_periph_reset_deassert(tup->uart_clk);
reset_control_deassert(tup->rst);
tup->rx_in_progress = 0;
tup->tx_in_progress = 0;
......@@ -910,15 +909,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
dma_addr_t dma_phys;
int ret;
struct dma_slave_config dma_sconfig;
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_chan = dma_request_channel(mask, NULL, NULL);
if (!dma_chan) {
dma_chan = dma_request_slave_channel_reason(tup->uport.dev,
dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
dev_err(tup->uport.dev,
"Dma channel is not available, will try later\n");
return -EPROBE_DEFER;
"DMA channel alloc failed: %d\n", ret);
return ret;
}
if (dma_to_memory) {
......@@ -938,7 +936,6 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
dma_buf = tup->uport.state->xmit.buf;
}
dma_sconfig.slave_id = tup->dma_req_sel;
if (dma_to_memory) {
dma_sconfig.src_addr = tup->uport.mapbase;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
......@@ -1222,17 +1219,8 @@ static int tegra_uart_parse_dt(struct platform_device *pdev,
struct tegra_uart_port *tup)
{
struct device_node *np = pdev->dev.of_node;
u32 of_dma[2];
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");
if (port < 0) {
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)
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->irq = platform_get_irq(pdev, 0);
u->regshift = 2;
......
......@@ -17,7 +17,6 @@
*/
#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/gpio.h>
......@@ -29,6 +28,7 @@
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/usb/ehci_def.h>
#include <linux/usb/tegra_usb_phy.h>
......@@ -62,6 +62,7 @@ static int (*orig_hub_control)(struct usb_hcd *hcd,
struct tegra_ehci_hcd {
struct tegra_usb_phy *phy;
struct clk *clk;
struct reset_control *rst;
int port_resuming;
bool needs_double_reset;
enum tegra_usb_phy_port_speed port_speed;
......@@ -385,13 +386,20 @@ static int tegra_ehci_probe(struct platform_device *pdev)
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);
if (err)
goto cleanup_hcd_create;
tegra_periph_reset_assert(tegra->clk);
reset_control_assert(tegra->rst);
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);
if (IS_ERR(u_phy)) {
......
......@@ -92,7 +92,7 @@
#define TEGRA20_CLK_OWR 71
#define TEGRA20_CLK_AFI 72
#define TEGRA20_CLK_CSITE 73
#define TEGRA20_CLK_PCIE_XCLK 74
/* 74 */
#define TEGRA20_CLK_AVPUCQ 75
#define TEGRA20_CLK_LA 76
/* 77 */
......
......@@ -92,7 +92,7 @@
#define TEGRA30_CLK_OWR 71
#define TEGRA30_CLK_AFI 72
#define TEGRA30_CLK_CSITE 73
#define TEGRA30_CLK_PCIEX 74
/* 74 */
#define TEGRA30_CLK_AVPUCQ 75
#define TEGRA30_CLK_LA 76
/* 77 */
......
......@@ -120,13 +120,6 @@ static inline void tegra_cpu_clock_resume(void)
}
#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);
#endif /* __LINUX_CLK_TEGRA_H_ */
......@@ -19,6 +19,7 @@
#define _MACH_TEGRA_POWERGATE_H_
struct clk;
struct reset_control;
#define TEGRA_POWERGATE_CPU 0
#define TEGRA_POWERGATE_3D 1
......@@ -52,7 +53,8 @@ int tegra_powergate_power_off(int id);
int tegra_powergate_remove_clamping(int id);
/* 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
static inline int tegra_powergate_is_powered(int id)
{
......@@ -74,7 +76,8 @@ static inline int tegra_powergate_remove_clamping(int id)
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;
}
......
config SND_SOC_TEGRA
tristate "SoC Audio for the Tegra System-on-Chip"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on COMMON_CLK
depends on RESET_CONTROLLER
select REGMAP_MMIO
select SND_SOC_GENERIC_DMAENGINE_PCM
help
......
......@@ -313,7 +313,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
{
struct tegra20_ac97 *ac97;
struct resource *mem;
u32 of_dma[2];
void __iomem *regs;
int ret = 0;
......@@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
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,
"nvidia,codec-reset-gpio", 0);
if (gpio_is_valid(ac97->reset_gpio)) {
......@@ -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_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
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_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
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);
if (ret)
......
......@@ -339,9 +339,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = {
static int tegra20_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra20_i2s *i2s;
struct resource *mem, *memregion, *dmareq;
u32 of_dma[2];
u32 dma_ch;
struct resource *mem, *memregion;
void __iomem *regs;
int ret;
......@@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
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,
resource_size(mem), DRV_NAME);
if (!memregion) {
......@@ -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_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
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_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4;
i2s->playback_dma_data.slave_id = dma_ch;
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
......
......@@ -24,8 +24,8 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/clk/tegra.h>
#include <sound/soc.h>
#include "tegra30_ahub.h"
......@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
}
int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
dma_addr_t *fiforeg,
unsigned int *reqsel)
char *dmachan, int dmachan_len,
dma_addr_t *fiforeg)
{
int channel;
u32 reg, val;
......@@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
__set_bit(channel, ahub->rx_usage);
*rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
snprintf(dmachan, dmachan_len, "rx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
*reqsel = ahub->dma_sel + channel;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
......@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
(channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
......@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
......@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
......@@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
dma_addr_t *fiforeg,
unsigned int *reqsel)
char *dmachan, int dmachan_len,
dma_addr_t *fiforeg)
{
int channel;
u32 reg, val;
......@@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
__set_bit(channel, ahub->tx_usage);
*txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
snprintf(dmachan, dmachan_len, "tx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
*reqsel = ahub->dma_sel + channel;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
......@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
(channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
......@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
......@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
......@@ -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 reg;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 1 << txcif);
pm_runtime_put(ahub->dev);
return 0;
}
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)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg;
pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 0);
pm_runtime_put(ahub->dev);
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
#define CLK_LIST_MASK_TEGRA30 BIT(0)
#define CLK_LIST_MASK_TEGRA114 BIT(1)
#define MOD_LIST_MASK_TEGRA30 BIT(0)
#define MOD_LIST_MASK_TEGRA114 BIT(1)
#define MOD_LIST_MASK_TEGRA124 BIT(2)
#define CLK_LIST_MASK_TEGRA30_OR_LATER \
(CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114)
#define MOD_LIST_MASK_TEGRA30_OR_LATER \
(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 {
const char *clk_name;
u32 clk_list_mask;
} configlink_clocks[] = {
{ "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER },
{ "amx", CLK_LIST_MASK_TEGRA114 },
{ "adx", CLK_LIST_MASK_TEGRA114 },
const char *rst_name;
u32 mod_list_mask;
} configlink_mods[] = {
{ "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER },
{ "amx", MOD_LIST_MASK_TEGRA114_OR_LATER },
{ "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) \
......@@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
};
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,
};
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,
};
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,
};
......@@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
const struct tegra30_ahub_soc_data *soc_data;
struct clk *clk;
struct reset_control *rst;
int i;
struct resource *res0, *res1, *region;
u32 of_dma[2];
void __iomem *regs_apbif, *regs_ahub;
int ret = 0;
......@@ -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.
* Ensure that here.
*/
for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
if (!(configlink_clocks[i].clk_list_mask &
soc_data->clk_list_mask))
for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) {
if (!(configlink_mods[i].mod_list_mask &
soc_data->mod_list_mask))
continue;
clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "Can't get clock %s\n",
configlink_clocks[i].clk_name);
ret = PTR_ERR(clk);
rst = reset_control_get(&pdev->dev,
configlink_mods[i].rst_name);
if (IS_ERR(rst)) {
dev_err(&pdev->dev, "Can't get reset %s\n",
configlink_mods[i].rst_name);
ret = PTR_ERR(rst);
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),
......@@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
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);
if (!res0) {
dev_err(&pdev->dev, "No apbif memory resource\n");
......
......@@ -465,15 +465,15 @@ enum tegra30_ahub_rxcif {
};
extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
dma_addr_t *fiforeg,
unsigned int *reqsel);
char *dmachan, int dmachan_len,
dma_addr_t *fiforeg);
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_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
dma_addr_t *fiforeg,
unsigned int *reqsel);
char *dmachan, int dmachan_len,
dma_addr_t *fiforeg);
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_free_tx_fifo(enum tegra30_ahub_txcif txcif);
......@@ -502,7 +502,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg,
struct tegra30_ahub_cif_conf *conf);
struct tegra30_ahub_soc_data {
u32 clk_list_mask;
u32 mod_list_mask;
void (*set_audio_cif)(struct regmap *regmap,
unsigned int reg,
struct tegra30_ahub_cif_conf *conf);
......@@ -524,7 +524,6 @@ struct tegra30_ahub {
struct device *dev;
struct clk *clk_d_audio;
struct clk *clk_apbif;
int dma_sel;
resource_size_t apbif_addr;
struct regmap *regmap_apbif;
struct regmap *regmap_ahub;
......
......@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
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,
unsigned int fmt)
{
......@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
}
static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
.startup = tegra30_i2s_startup,
.shutdown = tegra30_i2s_shutdown,
.set_fmt = tegra30_i2s_set_fmt,
.hw_params = tegra30_i2s_hw_params,
.trigger = tegra30_i2s_trigger,
......@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
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,
&i2s->dai, 1);
if (ret) {
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
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) {
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
goto err_unregister_component;
......@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
err_unregister_component:
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:
if (!pm_runtime_status_suspended(&pdev->dev))
tegra30_i2s_runtime_suspend(&pdev->dev);
......@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
tegra_pcm_platform_unregister(&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);
return 0;
......
......@@ -238,11 +238,14 @@ struct tegra30_i2s {
struct clk *clk_i2s;
enum tegra30_ahub_txcif capture_i2s_cif;
enum tegra30_ahub_rxcif capture_fifo_cif;
char capture_dma_chan[8];
struct snd_dmaengine_dai_dma_data capture_dma_data;
enum tegra30_ahub_rxcif playback_i2s_cif;
enum tegra30_ahub_txcif playback_fifo_cif;
char playback_dma_chan[8];
struct snd_dmaengine_dai_dma_data playback_dma_data;
struct regmap *regmap;
struct snd_dmaengine_pcm_config dma_config;
};
#endif
......@@ -61,12 +61,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = {
int tegra_pcm_platform_register(struct device *dev)
{
return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_COMPAT);
return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0);
}
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)
{
return snd_dmaengine_pcm_unregister(dev);
......
......@@ -31,7 +31,12 @@
#ifndef __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_with_chan_names(struct device *dev,
struct snd_dmaengine_pcm_config *config,
char *txdmachan, char *rxdmachan);
void tegra_pcm_platform_unregister(struct device *dev);
#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