diff options
author | Thierry Reding <treding@nvidia.com> | 2013-12-17 17:09:16 (GMT) |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2013-12-17 17:09:16 (GMT) |
commit | b03bb79d4f3677adef410274fe73e6f16a1b3f41 (patch) | |
tree | 5731451c1bead0550a2726bf948b25f7c67dc073 | |
parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) | |
parent | 8a0a1af30cbf56b41220a02e34835022c4d72f41 (diff) | |
download | linux-b03bb79d4f3677adef410274fe73e6f16a1b3f41.tar.xz |
Merge tag 'tegra-for-3.14-dmas-resets-rework' into drm/for-next
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.
91 files changed, 6603 insertions, 3569 deletions
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt index 1608a54..68ac65f 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt @@ -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). diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt index 0c80c26..9acea9d 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt @@ -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 { diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt new file mode 100644 index 0000000..ded5d62 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt @@ -0,0 +1,63 @@ +NVIDIA Tegra124 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra124-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in", and the board-specific oscillator "osc". +- #clock-cells : Should be 1. + 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: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra124-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car TEGRA124_CLK_USB2>; + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + osc: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <112400000>; + }; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k> <&osc>; + }; +}; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt index fcfed5b..6c5901b 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt @@ -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 { diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt index 0f71408..63618cd 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt @@ -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 { diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt index 90fa7da..c6908e7 100644 --- a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt +++ b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt @@ -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>; }; diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index b4fa934..ab45c02 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -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"; }; }; diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt index ef77cc7..87507e9 100644 --- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt +++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt index 2995fae..0382b8b 100644 --- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt +++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt @@ -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 */ diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt index c6d7b11..f357c16 100644 --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt @@ -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 */ diff --git a/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt b/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt index 5aeee53..5ae601e 100644 --- a/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt +++ b/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt @@ -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 diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt index 6b75107..24cee06 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt @@ -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 { diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt index c3fc57a..c7ea9d4 100644 --- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt index 93f45e9..652d1ff 100644 --- a/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt @@ -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>; }; diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt index 392a449..845850c 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt index 8b8903e..57f40f9 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt @@ -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, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt index dc62249..7788808 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt @@ -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, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt index aab6ce0..96f6a57 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt @@ -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, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt index 4b44dfb..b795d28 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt @@ -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, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt index ad589b1..436f6cd 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt @@ -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, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt index c145497..eaf0010 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt index 0df2b5c..dc30c6b 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt index 0e5c12c..946e2ac 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt @@ -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>; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt index dfa6c03..0c113ff 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt index 91ff771..7ea701e 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt @@ -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"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt index 7b53da5..bdf08e6 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt @@ -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"; }; - diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt index eefe15e..5db9144 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt @@ -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"; }; - diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt index e019fdc..4a864bd 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt @@ -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>; }; diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt index 906109d..b5082a1 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt @@ -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>; }; diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt index df09330..3dc9140 100644 --- a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt @@ -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 diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 8d42787..731249f 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -43,6 +43,7 @@ compatible = "nvidia,tegra114-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; apbdma: dma { @@ -81,6 +82,9 @@ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; ahb: ahb { @@ -124,9 +128,12 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 8>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartb: serial@70006040 { @@ -134,9 +141,12 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 9>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartc: serial@70006200 { @@ -144,9 +154,12 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 10>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartd: serial@70006300 { @@ -154,9 +167,12 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 19>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; + status = "disabled"; }; pwm: pwm { @@ -164,6 +180,8 @@ reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA114_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; @@ -175,6 +193,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C1>; clock-names = "div-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -186,6 +208,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C2>; clock-names = "div-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -197,6 +223,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C3>; clock-names = "div-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -208,6 +238,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C4>; clock-names = "div-clk"; + resets = <&tegra_car 103>; + reset-names = "i2c"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -219,6 +253,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C5>; clock-names = "div-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -226,11 +264,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d400 0x200>; interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC1>; clock-names = "spi"; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -238,11 +279,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d600 0x200>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC2>; clock-names = "spi"; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -250,11 +294,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d800 0x200>; interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC3>; clock-names = "spi"; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -262,11 +309,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000da00 0x200>; interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC4>; clock-names = "spi"; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -274,11 +324,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000dc00 0x200>; interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 27>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC5>; clock-names = "spi"; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -286,11 +339,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000de00 0x200>; interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 28>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC6>; clock-names = "spi"; + resets = <&tegra_car 105>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -306,6 +362,8 @@ reg = <0x7000e200 0x100>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; @@ -333,26 +391,39 @@ <0x70080200 0x100>, <0x70081000 0x200>; interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 1>, <&apbdma 2>, - <&apbdma 3>, <&apbdma 4>, <&apbdma 6>, <&apbdma 7>, - <&apbdma 12>, <&apbdma 13>, <&apbdma 14>, - <&apbdma 29>; clocks = <&tegra_car TEGRA114_CLK_D_AUDIO>, - <&tegra_car TEGRA114_CLK_APBIF>, - <&tegra_car TEGRA114_CLK_I2S0>, - <&tegra_car TEGRA114_CLK_I2S1>, - <&tegra_car TEGRA114_CLK_I2S2>, - <&tegra_car TEGRA114_CLK_I2S3>, - <&tegra_car TEGRA114_CLK_I2S4>, - <&tegra_car TEGRA114_CLK_DAM0>, - <&tegra_car TEGRA114_CLK_DAM1>, - <&tegra_car TEGRA114_CLK_DAM2>, - <&tegra_car TEGRA114_CLK_SPDIF_IN>, - <&tegra_car TEGRA114_CLK_AMX>, - <&tegra_car TEGRA114_CLK_ADX>; - clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + <&tegra_car TEGRA114_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>, /* spdif */ + <&tegra_car 153>, /* amx */ + <&tegra_car 154>; /* adx */ + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", "i2s3", "i2s4", "dam0", "dam1", "dam2", - "spdif_in", "amx", "adx"; + "spdif", "amx", "adx"; + dmas = <&apbdma 1>, <&apbdma 1>, + <&apbdma 2>, <&apbdma 2>, + <&apbdma 3>, <&apbdma 3>, + <&apbdma 4>, <&apbdma 4>, + <&apbdma 6>, <&apbdma 6>, + <&apbdma 7>, <&apbdma 7>, + <&apbdma 12>, <&apbdma 12>, + <&apbdma 13>, <&apbdma 13>, + <&apbdma 14>, <&apbdma 14>, + <&apbdma 29>, <&apbdma 29>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", + "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", + "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", + "rx9", "tx9"; ranges; #address-cells = <1>; #size-cells = <1>; @@ -362,6 +433,8 @@ reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA114_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; status = "disabled"; }; @@ -370,6 +443,8 @@ reg = <0x70080400 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA114_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; status = "disabled"; }; @@ -378,6 +453,8 @@ reg = <0x70080500 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA114_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; status = "disabled"; }; @@ -386,6 +463,8 @@ reg = <0x70080600 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA114_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; status = "disabled"; }; @@ -394,6 +473,8 @@ reg = <0x70080700 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA114_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; status = "disabled"; }; }; @@ -403,6 +484,8 @@ reg = <0x78000000 0x200>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disable"; }; @@ -411,6 +494,8 @@ reg = <0x78000200 0x200>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disable"; }; @@ -419,6 +504,8 @@ reg = <0x78000400 0x200>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disable"; }; @@ -427,6 +514,8 @@ reg = <0x78000600 0x200>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA114_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disable"; }; @@ -436,6 +525,8 @@ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; phy_type = "utmi"; clocks = <&tegra_car TEGRA114_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,phy = <&phy1>; status = "disabled"; }; @@ -467,6 +558,8 @@ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; phy_type = "utmi"; clocks = <&tegra_car TEGRA114_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index 8d71fc9..e57fb3ae 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -280,6 +280,8 @@ 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 { diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index df40b54..c90d0aa 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -22,6 +22,8 @@ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */ clocks = <&tegra_car TEGRA20_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; #address-cells = <1>; #size-cells = <1>; @@ -33,6 +35,8 @@ reg = <0x54040000 0x00040000>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; }; vi { @@ -40,6 +44,8 @@ reg = <0x54080000 0x00040000>; interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; }; epp { @@ -47,6 +53,8 @@ reg = <0x540c0000 0x00040000>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; }; isp { @@ -54,6 +62,8 @@ reg = <0x54100000 0x00040000>; interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; }; gr2d { @@ -61,12 +71,16 @@ reg = <0x54140000 0x00040000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; 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 { @@ -75,7 +89,9 @@ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_DISP1>, <&tegra_car TEGRA20_CLK_PLL_P>; - clock-names = "disp1", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; rgb { status = "disabled"; @@ -88,7 +104,9 @@ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_DISP2>, <&tegra_car TEGRA20_CLK_PLL_P>; - clock-names = "disp2", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; rgb { status = "disabled"; @@ -102,6 +120,8 @@ 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"; }; @@ -117,6 +137,8 @@ compatible = "nvidia,tegra20-dsi"; reg = <0x54300000 0x00040000>; clocks = <&tegra_car TEGRA20_CLK_DSI>; + resets = <&tegra_car 48>; + reset-names = "dsi"; status = "disabled"; }; }; @@ -160,6 +182,7 @@ compatible = "nvidia,tegra20-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; apbdma: dma { @@ -182,6 +205,9 @@ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; ahb { @@ -222,8 +248,11 @@ compatible = "nvidia,tegra20-ac97"; reg = <0x70002000 0x200>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 12>; clocks = <&tegra_car TEGRA20_CLK_AC97>; + resets = <&tegra_car 3>; + reset-names = "ac97"; + dmas = <&apbdma 12>, <&apbdma 12>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -231,8 +260,11 @@ compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 2>; clocks = <&tegra_car TEGRA20_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; + dmas = <&apbdma 2>, <&apbdma 2>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -240,8 +272,11 @@ compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 1>; clocks = <&tegra_car TEGRA20_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; + dmas = <&apbdma 1>, <&apbdma 1>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -257,8 +292,11 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 8>; clocks = <&tegra_car TEGRA20_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -267,8 +305,11 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 9>; clocks = <&tegra_car TEGRA20_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -277,8 +318,11 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 10>; clocks = <&tegra_car TEGRA20_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -287,8 +331,11 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 19>; clocks = <&tegra_car TEGRA20_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -297,8 +344,11 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 20>; clocks = <&tegra_car TEGRA20_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -307,6 +357,8 @@ reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA20_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; @@ -326,6 +378,10 @@ clocks = <&tegra_car TEGRA20_CLK_I2C1>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -333,10 +389,13 @@ compatible = "nvidia,tegra20-sflash"; reg = <0x7000c380 0x80>; interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 11>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SPI>; + resets = <&tegra_car 43>; + reset-names = "spi"; + dmas = <&apbdma 11>, <&apbdma 11>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -349,6 +408,10 @@ clocks = <&tegra_car TEGRA20_CLK_I2C2>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -361,6 +424,10 @@ 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"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -373,6 +440,10 @@ clocks = <&tegra_car TEGRA20_CLK_DVC>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -380,10 +451,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d400 0x200>; interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC1>; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -391,10 +465,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d600 0x200>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC2>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -402,10 +479,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d800 0x200>; interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC3>; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -413,10 +493,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000da00 0x200>; interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC4>; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -425,6 +508,8 @@ reg = <0x7000e200 0x100>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; @@ -478,9 +563,12 @@ clocks = <&tegra_car TEGRA20_CLK_PEX>, <&tegra_car TEGRA20_CLK_AFI>, - <&tegra_car TEGRA20_CLK_PCIE_XCLK>, <&tegra_car TEGRA20_CLK_PLL_E>; - clock-names = "pex", "afi", "pcie_xclk", "pll_e"; + 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 { @@ -517,6 +605,8 @@ phy_type = "utmi"; nvidia,has-legacy-mode; clocks = <&tegra_car TEGRA20_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,needs-double-reset; nvidia,phy = <&phy1>; status = "disabled"; @@ -548,6 +638,8 @@ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; phy_type = "ulpi"; clocks = <&tegra_car TEGRA20_CLK_USB2>; + resets = <&tegra_car 58>; + reset-names = "usb"; nvidia,phy = <&phy2>; status = "disabled"; }; @@ -569,6 +661,8 @@ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; phy_type = "utmi"; clocks = <&tegra_car TEGRA20_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; @@ -597,6 +691,8 @@ reg = <0xc8000000 0x200>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disabled"; }; @@ -605,6 +701,8 @@ reg = <0xc8000200 0x200>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disabled"; }; @@ -613,6 +711,8 @@ reg = <0xc8000400 0x200>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disabled"; }; @@ -621,6 +721,8 @@ reg = <0xc8000600 0x200>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 2bd55cf..31259b0 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -40,10 +40,13 @@ clocks = <&tegra_car TEGRA30_CLK_PCIE>, <&tegra_car TEGRA30_CLK_AFI>, - <&tegra_car TEGRA30_CLK_PCIEX>, <&tegra_car TEGRA30_CLK_PLL_E>, <&tegra_car TEGRA30_CLK_CML0>; - clock-names = "pex", "afi", "pcie_xclk", "pll_e", "cml"; + clock-names = "pex", "afi", "pll_e", "cml"; + resets = <&tegra_car 70>, + <&tegra_car 72>, + <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; status = "disabled"; pci@1,0 { @@ -92,6 +95,8 @@ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */ clocks = <&tegra_car TEGRA30_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; #address-cells = <1>; #size-cells = <1>; @@ -103,6 +108,8 @@ reg = <0x54040000 0x00040000>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; }; vi { @@ -110,6 +117,8 @@ reg = <0x54080000 0x00040000>; interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; }; epp { @@ -117,6 +126,8 @@ reg = <0x540c0000 0x00040000>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; }; isp { @@ -124,12 +135,16 @@ reg = <0x54100000 0x00040000>; interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; }; gr2d { compatible = "nvidia,tegra30-gr2d"; reg = <0x54140000 0x00040000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + resets = <&tegra_car 21>; + reset-names = "2d"; clocks = <&tegra_car TEGRA30_CLK_GR2D>; }; @@ -139,6 +154,9 @@ clocks = <&tegra_car TEGRA30_CLK_GR3D &tegra_car TEGRA30_CLK_GR3D2>; clock-names = "3d", "3d2"; + resets = <&tegra_car 24>, + <&tegra_car 98>; + reset-names = "3d", "3d2"; }; dc@54200000 { @@ -147,7 +165,9 @@ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_DISP1>, <&tegra_car TEGRA30_CLK_PLL_P>; - clock-names = "disp1", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; rgb { status = "disabled"; @@ -160,7 +180,9 @@ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_DISP2>, <&tegra_car TEGRA30_CLK_PLL_P>; - clock-names = "disp2", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; rgb { status = "disabled"; @@ -174,6 +196,8 @@ clocks = <&tegra_car TEGRA30_CLK_HDMI>, <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>; clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; status = "disabled"; }; @@ -189,6 +213,8 @@ compatible = "nvidia,tegra30-dsi"; reg = <0x54300000 0x00040000>; clocks = <&tegra_car TEGRA30_CLK_DSIA>; + resets = <&tegra_car 48>; + reset-names = "dsi"; status = "disabled"; }; }; @@ -234,6 +260,7 @@ compatible = "nvidia,tegra30-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; apbdma: dma { @@ -272,6 +299,9 @@ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; ahb: ahb { @@ -315,8 +345,11 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 8>; clocks = <&tegra_car TEGRA30_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -325,8 +358,11 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 9>; clocks = <&tegra_car TEGRA30_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -335,8 +371,11 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 10>; clocks = <&tegra_car TEGRA30_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -345,8 +384,11 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 19>; clocks = <&tegra_car TEGRA30_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -355,8 +397,11 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 20>; clocks = <&tegra_car TEGRA30_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -365,6 +410,8 @@ reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA30_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; @@ -384,6 +431,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C1>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -396,6 +447,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C2>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -408,6 +463,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C3>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -419,7 +478,11 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_I2C4>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + resets = <&tegra_car 103>; + reset-names = "i2c"; clock-names = "div-clk", "fast-clk"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -432,6 +495,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C5>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -439,10 +506,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d400 0x200>; interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC1>; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -450,10 +520,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d600 0x200>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC2>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -461,10 +534,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d800 0x200>; interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC3>; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -472,10 +548,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000da00 0x200>; interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC4>; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -483,10 +562,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000dc00 0x200>; interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 27>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC5>; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -494,10 +576,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000de00 0x200>; interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 28>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC6>; + resets = <&tegra_car 106>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -506,6 +591,8 @@ reg = <0x7000e200 0x100>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; @@ -540,21 +627,29 @@ reg = <0x70080000 0x200 0x70080200 0x100>; interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; - nvidia,dma-request-selector = <&apbdma 1>; clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>, - <&tegra_car TEGRA30_CLK_APBIF>, - <&tegra_car TEGRA30_CLK_I2S0>, - <&tegra_car TEGRA30_CLK_I2S1>, - <&tegra_car TEGRA30_CLK_I2S2>, - <&tegra_car TEGRA30_CLK_I2S3>, - <&tegra_car TEGRA30_CLK_I2S4>, - <&tegra_car TEGRA30_CLK_DAM0>, - <&tegra_car TEGRA30_CLK_DAM1>, - <&tegra_car TEGRA30_CLK_DAM2>, - <&tegra_car TEGRA30_CLK_SPDIF_IN>; - clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + <&tegra_car TEGRA30_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>; /* spdif */ + 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>; @@ -564,6 +659,8 @@ reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA30_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; status = "disabled"; }; @@ -572,6 +669,8 @@ reg = <0x70080400 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA30_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; status = "disabled"; }; @@ -580,6 +679,8 @@ reg = <0x70080500 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA30_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; status = "disabled"; }; @@ -588,6 +689,8 @@ reg = <0x70080600 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA30_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; status = "disabled"; }; @@ -596,6 +699,8 @@ reg = <0x70080700 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA30_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; status = "disabled"; }; }; @@ -605,6 +710,8 @@ reg = <0x78000000 0x200>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disabled"; }; @@ -613,6 +720,8 @@ reg = <0x78000200 0x200>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disabled"; }; @@ -621,6 +730,8 @@ reg = <0x78000400 0x200>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disabled"; }; @@ -629,6 +740,8 @@ reg = <0x78000600 0x200>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disabled"; }; @@ -638,6 +751,8 @@ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,needs-double-reset; nvidia,phy = <&phy1>; status = "disabled"; @@ -671,6 +786,8 @@ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; phy_type = "ulpi"; clocks = <&tegra_car TEGRA30_CLK_USB2>; + resets = <&tegra_car 58>; + reset-names = "usb"; nvidia,phy = <&phy2>; status = "disabled"; }; @@ -692,6 +809,8 @@ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 09e740f..15c0929 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -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 diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 85d28e7..f6f5b54 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -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; diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index f49fac2..f7dfb72 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -6,7 +6,12 @@ obj-y += clk-periph-gate.o obj-y += clk-pll.o obj-y += clk-pll-out.o obj-y += clk-super.o - +obj-y += clk-tegra-audio.o +obj-y += clk-tegra-periph.o +obj-y += clk-tegra-pmc.o +obj-y += clk-tegra-fixed.o +obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h new file mode 100644 index 0000000..cf0c323 --- /dev/null +++ b/drivers/clk/tegra/clk-id.h @@ -0,0 +1,235 @@ +/* + * This header provides IDs for clocks common between several Tegra SoCs + */ +#ifndef _TEGRA_CLK_ID_H +#define _TEGRA_CLK_ID_H + +enum clk_id { + tegra_clk_actmon, + tegra_clk_adx, + tegra_clk_adx1, + tegra_clk_afi, + tegra_clk_amx, + tegra_clk_amx1, + tegra_clk_apbdma, + tegra_clk_apbif, + tegra_clk_audio0, + tegra_clk_audio0_2x, + tegra_clk_audio0_mux, + tegra_clk_audio1, + tegra_clk_audio1_2x, + tegra_clk_audio1_mux, + tegra_clk_audio2, + tegra_clk_audio2_2x, + tegra_clk_audio2_mux, + tegra_clk_audio3, + tegra_clk_audio3_2x, + tegra_clk_audio3_mux, + tegra_clk_audio4, + tegra_clk_audio4_2x, + tegra_clk_audio4_mux, + tegra_clk_blink, + tegra_clk_bsea, + tegra_clk_bsev, + tegra_clk_cclk_g, + tegra_clk_cclk_lp, + tegra_clk_cilab, + tegra_clk_cilcd, + tegra_clk_cile, + tegra_clk_clk_32k, + tegra_clk_clk72Mhz, + tegra_clk_clk_m, + tegra_clk_clk_m_div2, + tegra_clk_clk_m_div4, + tegra_clk_clk_out_1, + tegra_clk_clk_out_1_mux, + tegra_clk_clk_out_2, + tegra_clk_clk_out_2_mux, + tegra_clk_clk_out_3, + tegra_clk_clk_out_3_mux, + tegra_clk_cml0, + tegra_clk_cml1, + tegra_clk_csi, + tegra_clk_csite, + tegra_clk_csus, + tegra_clk_cve, + tegra_clk_dam0, + tegra_clk_dam1, + tegra_clk_dam2, + tegra_clk_d_audio, + tegra_clk_dds, + tegra_clk_dfll_ref, + tegra_clk_dfll_soc, + tegra_clk_disp1, + tegra_clk_disp2, + tegra_clk_dp2, + tegra_clk_dpaux, + tegra_clk_dsia, + tegra_clk_dsialp, + tegra_clk_dsia_mux, + tegra_clk_dsib, + tegra_clk_dsiblp, + tegra_clk_dsib_mux, + tegra_clk_dtv, + tegra_clk_emc, + tegra_clk_entropy, + tegra_clk_epp, + tegra_clk_epp_8, + tegra_clk_extern1, + tegra_clk_extern2, + tegra_clk_extern3, + tegra_clk_fuse, + tegra_clk_fuse_burn, + tegra_clk_gpu, + tegra_clk_gr2d, + tegra_clk_gr2d_8, + tegra_clk_gr3d, + tegra_clk_gr3d_8, + tegra_clk_hclk, + tegra_clk_hda, + tegra_clk_hda2codec_2x, + tegra_clk_hda2hdmi, + tegra_clk_hdmi, + tegra_clk_hdmi_audio, + tegra_clk_host1x, + tegra_clk_host1x_8, + tegra_clk_i2c1, + tegra_clk_i2c2, + tegra_clk_i2c3, + tegra_clk_i2c4, + tegra_clk_i2c5, + tegra_clk_i2c6, + tegra_clk_i2cslow, + tegra_clk_i2s0, + tegra_clk_i2s0_sync, + tegra_clk_i2s1, + tegra_clk_i2s1_sync, + tegra_clk_i2s2, + tegra_clk_i2s2_sync, + tegra_clk_i2s3, + tegra_clk_i2s3_sync, + tegra_clk_i2s4, + tegra_clk_i2s4_sync, + tegra_clk_isp, + tegra_clk_isp_8, + tegra_clk_ispb, + tegra_clk_kbc, + tegra_clk_kfuse, + tegra_clk_la, + tegra_clk_mipi, + tegra_clk_mipi_cal, + tegra_clk_mpe, + tegra_clk_mselect, + tegra_clk_msenc, + tegra_clk_ndflash, + tegra_clk_ndflash_8, + tegra_clk_ndspeed, + tegra_clk_ndspeed_8, + tegra_clk_nor, + tegra_clk_owr, + tegra_clk_pcie, + tegra_clk_pclk, + tegra_clk_pll_a, + tegra_clk_pll_a_out0, + tegra_clk_pll_c, + tegra_clk_pll_c2, + tegra_clk_pll_c3, + tegra_clk_pll_c4, + tegra_clk_pll_c_out1, + tegra_clk_pll_d, + tegra_clk_pll_d2, + tegra_clk_pll_d2_out0, + tegra_clk_pll_d_out0, + tegra_clk_pll_dp, + tegra_clk_pll_e_out0, + tegra_clk_pll_m, + tegra_clk_pll_m_out1, + tegra_clk_pll_p, + tegra_clk_pll_p_out1, + tegra_clk_pll_p_out2, + tegra_clk_pll_p_out2_int, + tegra_clk_pll_p_out3, + tegra_clk_pll_p_out4, + tegra_clk_pll_p_out5, + tegra_clk_pll_ref, + tegra_clk_pll_re_out, + tegra_clk_pll_re_vco, + tegra_clk_pll_u, + tegra_clk_pll_u_12m, + tegra_clk_pll_u_480m, + tegra_clk_pll_u_48m, + tegra_clk_pll_u_60m, + tegra_clk_pll_x, + tegra_clk_pll_x_out0, + tegra_clk_pwm, + tegra_clk_rtc, + tegra_clk_sata, + tegra_clk_sata_cold, + tegra_clk_sata_oob, + tegra_clk_sbc1, + tegra_clk_sbc1_8, + tegra_clk_sbc2, + tegra_clk_sbc2_8, + tegra_clk_sbc3, + tegra_clk_sbc3_8, + tegra_clk_sbc4, + tegra_clk_sbc4_8, + tegra_clk_sbc5, + tegra_clk_sbc5_8, + tegra_clk_sbc6, + tegra_clk_sbc6_8, + tegra_clk_sclk, + tegra_clk_sdmmc1, + tegra_clk_sdmmc2, + tegra_clk_sdmmc3, + tegra_clk_sdmmc4, + tegra_clk_se, + tegra_clk_soc_therm, + tegra_clk_sor0, + tegra_clk_sor0_lvds, + tegra_clk_spdif, + tegra_clk_spdif_2x, + tegra_clk_spdif_in, + tegra_clk_spdif_in_sync, + tegra_clk_spdif_mux, + tegra_clk_spdif_out, + tegra_clk_timer, + tegra_clk_trace, + tegra_clk_tsec, + tegra_clk_tsensor, + tegra_clk_tvdac, + tegra_clk_tvo, + tegra_clk_uarta, + tegra_clk_uartb, + tegra_clk_uartc, + tegra_clk_uartd, + tegra_clk_uarte, + tegra_clk_usb2, + tegra_clk_usb3, + tegra_clk_usbd, + tegra_clk_vcp, + tegra_clk_vde, + tegra_clk_vde_8, + tegra_clk_vfir, + tegra_clk_vi, + tegra_clk_vi_8, + tegra_clk_vi_9, + tegra_clk_vic03, + tegra_clk_vim2_clk, + tegra_clk_vimclk_sync, + tegra_clk_vi_sensor, + tegra_clk_vi_sensor2, + tegra_clk_vi_sensor_8, + tegra_clk_xusb_dev, + tegra_clk_xusb_dev_src, + tegra_clk_xusb_falcon_src, + tegra_clk_xusb_fs_src, + tegra_clk_xusb_host, + tegra_clk_xusb_host_src, + tegra_clk_xusb_hs_src, + tegra_clk_xusb_ss, + tegra_clk_xusb_ss_src, + tegra_clk_max, +}; + +#endif /* _TEGRA_CLK_ID_H */ diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index bafee98..5070153 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -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, @@ -151,12 +129,16 @@ 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, - unsigned long flags, int clk_num, - struct tegra_clk_periph_regs *pregs, int *enable_refcnt) + unsigned long flags, int clk_num, int *enable_refcnt) { struct tegra_clk_periph_gate *gate; struct clk *clk; struct clk_init_data init; + struct tegra_clk_periph_regs *pregs; + + pregs = get_reg_bank(clk_num); + if (!pregs) + return ERR_PTR(-EINVAL); gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) { diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b2309d3..c534043 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -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, @@ -170,27 +130,50 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { .disable = clk_periph_disable, }; +const struct clk_ops tegra_clk_periph_no_gate_ops = { + .get_parent = clk_periph_get_parent, + .set_parent = clk_periph_set_parent, + .recalc_rate = clk_periph_recalc_rate, + .round_rate = clk_periph_round_rate, + .set_rate = clk_periph_set_rate, +}; + static struct clk *_tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, - void __iomem *clk_base, u32 offset, bool div, + void __iomem *clk_base, u32 offset, unsigned long flags) { struct clk *clk; struct clk_init_data init; + struct tegra_clk_periph_regs *bank; + bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); + + if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { + flags |= CLK_SET_RATE_PARENT; + init.ops = &tegra_clk_periph_nodiv_ops; + } else if (periph->gate.flags & TEGRA_PERIPH_NO_GATE) + init.ops = &tegra_clk_periph_no_gate_ops; + else + init.ops = &tegra_clk_periph_ops; init.name = name; - init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; init.flags = flags; init.parent_names = parent_names; init.num_parents = num_parents; + bank = get_reg_bank(periph->gate.clk_num); + if (!bank) + return ERR_PTR(-EINVAL); + /* Data in .init is copied by clk_register(), so stack variable OK */ periph->hw.init = &init; periph->magic = TEGRA_CLK_PERIPH_MAGIC; periph->mux.reg = clk_base + offset; periph->divider.reg = div ? (clk_base + offset) : NULL; periph->gate.clk_base = clk_base; + periph->gate.regs = bank; + periph->gate.enable_refcnt = periph_clk_enb_refcnt; clk = clk_register(NULL, &periph->hw); if (IS_ERR(clk)) @@ -209,7 +192,7 @@ struct clk *tegra_clk_register_periph(const char *name, u32 offset, unsigned long flags) { return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, true, flags); + periph, clk_base, offset, flags); } struct clk *tegra_clk_register_periph_nodiv(const char *name, @@ -217,6 +200,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, struct tegra_clk_periph *periph, void __iomem *clk_base, u32 offset) { + periph->gate.flags |= TEGRA_PERIPH_NO_DIV; return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, false, CLK_SET_RATE_PARENT); + periph, clk_base, offset, CLK_SET_RATE_PARENT); } diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 197074a..2dd4322 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -77,7 +77,23 @@ #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) #define PLLE_SS_CTRL 0x68 -#define PLLE_SS_DISABLE (7 << 10) +#define PLLE_SS_CNTL_BYPASS_SS BIT(10) +#define PLLE_SS_CNTL_INTERP_RESET BIT(11) +#define PLLE_SS_CNTL_SSC_BYP BIT(12) +#define PLLE_SS_CNTL_CENTER BIT(14) +#define PLLE_SS_CNTL_INVERT BIT(15) +#define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\ + PLLE_SS_CNTL_SSC_BYP) +#define PLLE_SS_MAX_MASK 0x1ff +#define PLLE_SS_MAX_VAL 0x25 +#define PLLE_SS_INC_MASK (0xff << 16) +#define PLLE_SS_INC_VAL (0x1 << 16) +#define PLLE_SS_INCINTRV_MASK (0x3f << 24) +#define PLLE_SS_INCINTRV_VAL (0x20 << 24) +#define PLLE_SS_COEFFICIENTS_MASK \ + (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK) +#define PLLE_SS_COEFFICIENTS_VAL \ + (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) #define PLLE_AUX_PLLP_SEL BIT(2) #define PLLE_AUX_ENABLE_SWCTL BIT(4) @@ -121,6 +137,36 @@ #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) +#define PLLSS_MISC_KCP 0 +#define PLLSS_MISC_KVCO 0 +#define PLLSS_MISC_SETUP 0 +#define PLLSS_EN_SDM 0 +#define PLLSS_EN_SSC 0 +#define PLLSS_EN_DITHER2 0 +#define PLLSS_EN_DITHER 1 +#define PLLSS_SDM_RESET 0 +#define PLLSS_CLAMP 0 +#define PLLSS_SDM_SSC_MAX 0 +#define PLLSS_SDM_SSC_MIN 0 +#define PLLSS_SDM_SSC_STEP 0 +#define PLLSS_SDM_DIN 0 +#define PLLSS_MISC_DEFAULT ((PLLSS_MISC_KCP << 25) | \ + (PLLSS_MISC_KVCO << 24) | \ + PLLSS_MISC_SETUP) +#define PLLSS_CFG_DEFAULT ((PLLSS_EN_SDM << 31) | \ + (PLLSS_EN_SSC << 30) | \ + (PLLSS_EN_DITHER2 << 29) | \ + (PLLSS_EN_DITHER << 28) | \ + (PLLSS_SDM_RESET) << 27 | \ + (PLLSS_CLAMP << 22)) +#define PLLSS_CTRL1_DEFAULT \ + ((PLLSS_SDM_SSC_MAX << 16) | PLLSS_SDM_SSC_MIN) +#define PLLSS_CTRL2_DEFAULT \ + ((PLLSS_SDM_SSC_STEP << 16) | PLLSS_SDM_DIN) +#define PLLSS_LOCK_OVERRIDE BIT(24) +#define PLLSS_REF_SRC_SEL_SHIFT 25 +#define PLLSS_REF_SRC_SEL_MASK (3 << PLLSS_REF_SRC_SEL_SHIFT) + #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) #define pll_readl_base(p) pll_readl(p->params->base_reg, p) #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) @@ -134,7 +180,7 @@ #define mask(w) ((1 << (w)) - 1) #define divm_mask(p) mask(p->params->div_nmp->divm_width) #define divn_mask(p) mask(p->params->div_nmp->divn_width) -#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ +#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ mask(p->params->div_nmp->divp_width)) #define divm_max(p) (divm_mask(p)) @@ -154,10 +200,10 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) { u32 val; - if (!(pll->flags & TEGRA_PLL_USE_LOCK)) + if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) return; - if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) + if (!(pll->params->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) return; val = pll_readl_misc(pll); @@ -171,13 +217,13 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) u32 val, lock_mask; void __iomem *lock_addr; - if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { + if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) { udelay(pll->params->lock_delay); return 0; } lock_addr = pll->clk_base; - if (pll->flags & TEGRA_PLL_LOCK_MISC) + if (pll->params->flags & TEGRA_PLL_LOCK_MISC) lock_addr += pll->params->misc_reg; else lock_addr += pll->params->base_reg; @@ -204,7 +250,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) struct tegra_clk_pll *pll = to_clk_pll(hw); u32 val; - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; @@ -223,12 +269,12 @@ static void _clk_pll_enable(struct clk_hw *hw) clk_pll_enable_lock(pll); val = pll_readl_base(pll); - if (pll->flags & TEGRA_PLL_BYPASS) + if (pll->params->flags & TEGRA_PLL_BYPASS) val &= ~PLL_BASE_BYPASS; val |= PLL_BASE_ENABLE; pll_writel_base(val, pll); - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); @@ -241,12 +287,12 @@ static void _clk_pll_disable(struct clk_hw *hw) u32 val; val = pll_readl_base(pll); - if (pll->flags & TEGRA_PLL_BYPASS) + if (pll->params->flags & TEGRA_PLL_BYPASS) val &= ~PLL_BASE_BYPASS; val &= ~PLL_BASE_ENABLE; pll_writel_base(val, pll); - if (pll->flags & TEGRA_PLLM) { + if (pll->params->flags & TEGRA_PLLM) { val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); @@ -326,7 +372,7 @@ static int _get_table_rate(struct clk_hw *hw, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table *sel; - for (sel = pll->freq_table; sel->input_rate != 0; sel++) + for (sel = pll->params->freq_table; sel->input_rate != 0; sel++) if (sel->input_rate == parent_rate && sel->output_rate == rate) break; @@ -389,12 +435,11 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || (1 << p_div) > divp_max(pll) || cfg->output_rate > pll->params->vco_max) { - pr_err("%s: Failed to set %s rate %lu\n", - __func__, __clk_get_name(hw->clk), rate); - WARN_ON(1); return -EINVAL; } + cfg->output_rate >>= p_div; + if (pll->params->pdiv_tohw) { ret = _p_div_to_hw(hw, 1 << p_div); if (ret < 0) @@ -414,7 +459,7 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((pll->flags & TEGRA_PLLM) && + if ((params->flags & TEGRA_PLLM) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -450,7 +495,7 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((pll->flags & TEGRA_PLLM) && + if ((params->flags & TEGRA_PLLM) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -479,11 +524,11 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; - if (pll->flags & TEGRA_PLL_SET_LFCON) { + if (pll->params->flags & TEGRA_PLL_SET_LFCON) { val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); if (cfg->n >= PLLDU_LFCON_SET_DIVN) val |= 1 << PLL_MISC_LFCON_SHIFT; - } else if (pll->flags & TEGRA_PLL_SET_DCCON) { + } else if (pll->params->flags & TEGRA_PLL_SET_DCCON) { val &= ~(1 << PLL_MISC_DCCON_SHIFT); if (rate >= (pll->params->vco_max >> 1)) val |= 1 << PLL_MISC_DCCON_SHIFT; @@ -505,7 +550,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, _update_pll_mnp(pll, cfg); - if (pll->flags & TEGRA_PLL_HAS_CPCON) + if (pll->params->flags & TEGRA_PLL_HAS_CPCON) _update_pll_cpcon(pll, cfg, rate); if (state) { @@ -524,11 +569,11 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags = 0; int ret = 0; - if (pll->flags & TEGRA_PLL_FIXED) { - if (rate != pll->fixed_rate) { + if (pll->params->flags & TEGRA_PLL_FIXED) { + if (rate != pll->params->fixed_rate) { pr_err("%s: Can not change %s fixed rate %lu to %lu\n", __func__, __clk_get_name(hw->clk), - pll->fixed_rate, rate); + pll->params->fixed_rate, rate); return -EINVAL; } return 0; @@ -536,6 +581,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (_get_table_rate(hw, &cfg, rate, parent_rate) && _calc_rate(hw, &cfg, rate, parent_rate)) { + pr_err("%s: Failed to set %s rate %lu\n", __func__, + __clk_get_name(hw->clk), rate); WARN_ON(1); return -EINVAL; } @@ -559,18 +606,16 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; - if (pll->flags & TEGRA_PLL_FIXED) - return pll->fixed_rate; + if (pll->params->flags & TEGRA_PLL_FIXED) + return pll->params->fixed_rate; /* PLLM is used for memory; we do not change rate */ - if (pll->flags & TEGRA_PLLM) + if (pll->params->flags & TEGRA_PLLM) return __clk_get_rate(hw->clk); if (_get_table_rate(hw, &cfg, rate, *prate) && - _calc_rate(hw, &cfg, rate, *prate)) { - WARN_ON(1); + _calc_rate(hw, &cfg, rate, *prate)) return -EINVAL; - } return cfg.output_rate; } @@ -586,17 +631,19 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, val = pll_readl_base(pll); - if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) + if ((pll->params->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) return parent_rate; - if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { + if ((pll->params->flags & TEGRA_PLL_FIXED) && + !(val & PLL_BASE_OVERRIDE)) { struct tegra_clk_pll_freq_table sel; - if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, + parent_rate)) { pr_err("Clock %s has unknown fixed frequency\n", __clk_get_name(hw->clk)); BUG(); } - return pll->fixed_rate; + return pll->params->fixed_rate; } _get_pll_mnp(pll, &cfg); @@ -664,7 +711,7 @@ static int clk_plle_enable(struct clk_hw *hw) u32 val; int err; - if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; clk_pll_disable(hw); @@ -680,7 +727,7 @@ static int clk_plle_enable(struct clk_hw *hw) return err; } - if (pll->flags & TEGRA_PLLE_CONFIGURE) { + if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { /* configure dividers */ val = pll_readl_base(pll); val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); @@ -744,7 +791,7 @@ const struct clk_ops tegra_clk_plle_ops = { .enable = clk_plle_enable, }; -#ifdef CONFIG_ARCH_TEGRA_114_SOC +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate) @@ -755,6 +802,48 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, return 1; } +static unsigned long _clip_vco_min(unsigned long vco_min, + unsigned long parent_rate) +{ + return DIV_ROUND_UP(vco_min, parent_rate) * parent_rate; +} + +static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, + void __iomem *clk_base, + unsigned long parent_rate) +{ + u32 val; + u32 step_a, step_b; + + switch (parent_rate) { + case 12000000: + case 13000000: + case 26000000: + step_a = 0x2B; + step_b = 0x0B; + break; + case 16800000: + step_a = 0x1A; + step_b = 0x09; + break; + case 19200000: + step_a = 0x12; + step_b = 0x08; + break; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, parent_rate); + WARN_ON(1); + return -EINVAL; + } + + val = step_a << pll_params->stepa_shift; + val |= step_b << pll_params->stepb_shift; + writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); + + return 0; +} + static int clk_pll_iddq_enable(struct clk_hw *hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); @@ -1173,7 +1262,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) unsigned long flags = 0; unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); - if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; if (pll->lock) @@ -1217,6 +1306,18 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) if (ret < 0) goto out; + val = pll_readl(PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); + val &= ~PLLE_SS_COEFFICIENTS_MASK; + val |= PLLE_SS_COEFFICIENTS_VAL; + pll_writel(val, PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + val &= ~PLLE_SS_CNTL_INTERP_RESET; + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + /* TODO: enable hw control of xusb brick pll */ out: @@ -1248,9 +1349,8 @@ static void clk_plle_tegra114_disable(struct clk_hw *hw) #endif static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, - void __iomem *pmc, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + void __iomem *pmc, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; @@ -1261,10 +1361,7 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, pll->clk_base = clk_base; pll->pmc = pmc; - pll->freq_table = freq_table; pll->params = pll_params; - pll->fixed_rate = fixed_rate; - pll->flags = pll_flags; pll->lock = lock; if (!pll_params->div_nmp) @@ -1293,17 +1390,15 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1317,17 +1412,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1339,7 +1432,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, return clk; } -#ifdef CONFIG_ARCH_TEGRA_114_SOC +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) const struct clk_ops tegra_clk_pllxc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_iddq_enable, @@ -1386,21 +1479,46 @@ const struct clk_ops tegra_clk_plle_tegra114_ops = { struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; + int err; + u32 val, val_iddq; + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } if (!pll_params->pdiv_tohw) return ERR_PTR(-EINVAL); - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); + if (err) + return ERR_PTR(err); + + val = readl_relaxed(clk_base + pll_params->base_reg); + val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); + + if (val & PLL_BASE_ENABLE) + WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); + else { + val_iddq |= BIT(pll_params->iddq_bit_idx); + writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); + } + + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1414,19 +1532,19 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock, unsigned long parent_rate) { u32 val; struct tegra_clk_pll *pll; struct clk *clk; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1461,23 +1579,32 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; - struct clk *clk; + struct clk *clk, *parent; + unsigned long parent_rate; if (!pll_params->pdiv_tohw) return ERR_PTR(-EINVAL); - pll_flags |= TEGRA_PLL_BYPASS; - pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; - pll_flags |= TEGRA_PLLM; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll_params->flags |= TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll_params->flags |= TEGRA_PLLM; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1491,10 +1618,8 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct clk *parent, *clk; @@ -1507,20 +1632,21 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); parent = __clk_lookup(parent_name); - if (IS_ERR(parent)) { + if (!parent) { WARN(1, "parent clk %s of %s must be registered first\n", name, parent_name); return ERR_PTR(-EINVAL); } - pll_flags |= TEGRA_PLL_BYPASS; - pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, - freq_table, lock); + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll_params->flags |= TEGRA_PLL_BYPASS; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - parent_rate = __clk_get_rate(parent); - /* * Most of PLLC register fields are shadowed, and can not be read * directly from PLL h/w. Hence, actual PLLC boot state is unknown. @@ -1567,17 +1693,15 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, struct clk *tegra_clk_register_plle_tegra114(const char *name, const char *parent_name, void __iomem *clk_base, unsigned long flags, - unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { struct tegra_clk_pll *pll; struct clk *clk; u32 val, val_aux; - pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params, - TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock); + pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1587,11 +1711,13 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, val_aux = pll_readl(pll_params->aux_reg, pll); if (val & PLL_BASE_ENABLE) { - if (!(val_aux & PLLE_AUX_PLLRE_SEL)) + if ((val_aux & PLLE_AUX_PLLRE_SEL) || + (val_aux & PLLE_AUX_PLLP_SEL)) WARN(1, "pll_e enabled with unsupported parent %s\n", - (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref"); + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : + "pll_re_vco"); } else { - val_aux |= PLLE_AUX_PLLRE_SEL; + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); pll_writel(val, pll_params->aux_reg, pll); } @@ -1603,3 +1729,92 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, return clk; } #endif + +#ifdef CONFIG_ARCH_TEGRA_124_SOC +const struct clk_ops tegra_clk_pllss_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pll_iddq_enable, + .disable = clk_pll_iddq_disable, + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_ramp_round_rate, + .set_rate = clk_pllxc_set_rate, +}; + +struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk, *parent; + struct tegra_clk_pll_freq_table cfg; + unsigned long parent_rate; + u32 val; + int i; + + if (!pll_params->div_nmp) + return ERR_PTR(-EINVAL); + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + pll_params->flags = TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_USE_LOCK; + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + val = pll_readl_base(pll); + val &= ~PLLSS_REF_SRC_SEL_MASK; + pll_writel_base(val, pll); + + parent_rate = __clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + /* initialize PLL to minimum rate */ + + cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); + cfg.n = cfg.m * pll_params->vco_min / parent_rate; + + for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) + ; + if (!i) { + kfree(pll); + return ERR_PTR(-EINVAL); + } + + cfg.p = pll_params->pdiv_tohw[i-1].hw_val; + + _update_pll_mnp(pll, &cfg); + + pll_writel_misc(PLLSS_MISC_DEFAULT, pll); + pll_writel(PLLSS_CFG_DEFAULT, pll_params->ext_misc_reg[0], pll); + pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[1], pll); + pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[2], pll); + + val = pll_readl_base(pll); + if (val & PLL_BASE_ENABLE) { + if (val & BIT(pll_params->iddq_bit_idx)) { + WARN(1, "%s is on but IDDQ set\n", name); + kfree(pll); + return ERR_PTR(-EINVAL); + } + } else + val |= BIT(pll_params->iddq_bit_idx); + + val &= ~PLLSS_LOCK_OVERRIDE; + pll_writel_base(val, pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pllss_ops); + + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} +#endif diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c new file mode 100644 index 0000000..5c38aab --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-audio.c @@ -0,0 +1,215 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#include "clk.h" +#include "clk-id.h" + +#define AUDIO_SYNC_CLK_I2S0 0x4a0 +#define AUDIO_SYNC_CLK_I2S1 0x4a4 +#define AUDIO_SYNC_CLK_I2S2 0x4a8 +#define AUDIO_SYNC_CLK_I2S3 0x4ac +#define AUDIO_SYNC_CLK_I2S4 0x4b0 +#define AUDIO_SYNC_CLK_SPDIF 0x4b4 + +#define AUDIO_SYNC_DOUBLER 0x49c + +#define PLLA_OUT 0xb4 + +struct tegra_sync_source_initdata { + char *name; + unsigned long rate; + unsigned long max_rate; + int clk_id; +}; + +#define SYNC(_name) \ + {\ + .name = #_name,\ + .rate = 24000000,\ + .max_rate = 24000000,\ + .clk_id = tegra_clk_ ## _name,\ + } + +struct tegra_audio_clk_initdata { + char *gate_name; + char *mux_name; + u32 offset; + int gate_clk_id; + int mux_clk_id; +}; + +#define AUDIO(_name, _offset) \ + {\ + .gate_name = #_name,\ + .mux_name = #_name"_mux",\ + .offset = _offset,\ + .gate_clk_id = tegra_clk_ ## _name,\ + .mux_clk_id = tegra_clk_ ## _name ## _mux,\ + } + +struct tegra_audio2x_clk_initdata { + char *parent; + char *gate_name; + char *name_2x; + char *div_name; + int clk_id; + int clk_num; + u8 div_offset; +}; + +#define AUDIO2X(_name, _num, _offset) \ + {\ + .parent = #_name,\ + .gate_name = #_name"_2x",\ + .name_2x = #_name"_doubler",\ + .div_name = #_name"_div",\ + .clk_id = tegra_clk_ ## _name ## _2x,\ + .clk_num = _num,\ + .div_offset = _offset,\ + } + +static DEFINE_SPINLOCK(clk_doubler_lock); + +static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; + +static struct tegra_sync_source_initdata sync_source_clks[] __initdata = { + SYNC(spdif_in_sync), + SYNC(i2s0_sync), + SYNC(i2s1_sync), + SYNC(i2s2_sync), + SYNC(i2s3_sync), + SYNC(i2s4_sync), + SYNC(vimclk_sync), +}; + +static struct tegra_audio_clk_initdata audio_clks[] = { + AUDIO(audio0, AUDIO_SYNC_CLK_I2S0), + AUDIO(audio1, AUDIO_SYNC_CLK_I2S1), + AUDIO(audio2, AUDIO_SYNC_CLK_I2S2), + AUDIO(audio3, AUDIO_SYNC_CLK_I2S3), + AUDIO(audio4, AUDIO_SYNC_CLK_I2S4), + AUDIO(spdif, AUDIO_SYNC_CLK_SPDIF), +}; + +static struct tegra_audio2x_clk_initdata audio2x_clks[] = { + AUDIO2X(audio0, 113, 24), + AUDIO2X(audio1, 114, 25), + AUDIO2X(audio2, 115, 26), + AUDIO2X(audio3, 116, 27), + AUDIO2X(audio4, 117, 28), + AUDIO2X(spdif, 118, 29), +}; + +void __init tegra_audio_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_a_params) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + /* PLLA */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, + pmc_base, 0, pll_a_params, NULL); + *dt_clk = clk; + } + + /* PLLA_OUT0 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a_out0, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", + clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", + clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(sync_source_clks); i++) { + struct tegra_sync_source_initdata *data; + + data = &sync_source_clks[i]; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_sync_source(data->name, + data->rate, data->max_rate); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(audio_clks); i++) { + struct tegra_audio_clk_initdata *data; + + data = &audio_clks[i]; + dt_clk = tegra_lookup_dt_id(data->mux_clk_id, tegra_clks); + + if (!dt_clk) + continue; + clk = clk_register_mux(NULL, data->mux_name, mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), + CLK_SET_RATE_NO_REPARENT, + clk_base + data->offset, 0, 3, 0, + NULL); + *dt_clk = clk; + + dt_clk = tegra_lookup_dt_id(data->gate_clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_gate(NULL, data->gate_name, data->mux_name, + 0, clk_base + data->offset, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(audio2x_clks); i++) { + struct tegra_audio2x_clk_initdata *data; + + data = &audio2x_clks[i]; + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_fixed_factor(NULL, data->name_2x, + data->parent, CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider(data->div_name, + data->name_2x, clk_base + AUDIO_SYNC_DOUBLER, + 0, 0, data->div_offset, 1, 0, + &clk_doubler_lock); + clk = tegra_clk_register_periph_gate(data->gate_name, + data->div_name, TEGRA_PERIPH_NO_RESET, + clk_base, CLK_SET_RATE_PARENT, data->clk_num, + periph_clk_enb_refcnt); + *dt_clk = clk; + } +} + diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c new file mode 100644 index 0000000..f3b7738 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -0,0 +1,111 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#include "clk.h" +#include "clk-id.h" + +#define OSC_CTRL 0x50 +#define OSC_CTRL_OSC_FREQ_SHIFT 28 +#define OSC_CTRL_PLL_REF_DIV_SHIFT 26 + +int __init tegra_osc_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks, + unsigned long *input_freqs, int num, + unsigned long *osc_freq, + unsigned long *pll_ref_freq) +{ + struct clk *clk; + struct clk **dt_clk; + u32 val, pll_ref_div; + unsigned osc_idx; + + val = readl_relaxed(clk_base + OSC_CTRL); + osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT; + + if (osc_idx < num) + *osc_freq = input_freqs[osc_idx]; + else + *osc_freq = 0; + + if (!*osc_freq) { + WARN_ON(1); + return -EINVAL; + } + + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks); + if (!dt_clk) + return 0; + + clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, + *osc_freq); + *dt_clk = clk; + + /* pll_ref */ + val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; + pll_ref_div = 1 << val; + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks); + if (!dt_clk) + return 0; + + clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", + 0, 1, pll_ref_div); + *dt_clk = clk; + + if (pll_ref_freq) + *pll_ref_freq = *osc_freq / pll_ref_div; + + return 0; +} + +void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + + /* clk_32k */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, + CLK_IS_ROOT, 32768); + *dt_clk = clk; + } + + /* clk_m_div2 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div2, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", + CLK_SET_RATE_PARENT, 1, 2); + *dt_clk = clk; + } + + /* clk_m_div4 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div4, tegra_clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", + CLK_SET_RATE_PARENT, 1, 4); + *dt_clk = clk; + } +} + diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c new file mode 100644 index 0000000..5c35885 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -0,0 +1,674 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#include "clk.h" +#include "clk-id.h" + +#define CLK_SOURCE_I2S0 0x1d8 +#define CLK_SOURCE_I2S1 0x100 +#define CLK_SOURCE_I2S2 0x104 +#define CLK_SOURCE_NDFLASH 0x160 +#define CLK_SOURCE_I2S3 0x3bc +#define CLK_SOURCE_I2S4 0x3c0 +#define CLK_SOURCE_SPDIF_OUT 0x108 +#define CLK_SOURCE_SPDIF_IN 0x10c +#define CLK_SOURCE_PWM 0x110 +#define CLK_SOURCE_ADX 0x638 +#define CLK_SOURCE_ADX1 0x670 +#define CLK_SOURCE_AMX 0x63c +#define CLK_SOURCE_AMX1 0x674 +#define CLK_SOURCE_HDA 0x428 +#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 +#define CLK_SOURCE_SBC1 0x134 +#define CLK_SOURCE_SBC2 0x118 +#define CLK_SOURCE_SBC3 0x11c +#define CLK_SOURCE_SBC4 0x1b4 +#define CLK_SOURCE_SBC5 0x3c8 +#define CLK_SOURCE_SBC6 0x3cc +#define CLK_SOURCE_SATA_OOB 0x420 +#define CLK_SOURCE_SATA 0x424 +#define CLK_SOURCE_NDSPEED 0x3f8 +#define CLK_SOURCE_VFIR 0x168 +#define CLK_SOURCE_SDMMC1 0x150 +#define CLK_SOURCE_SDMMC2 0x154 +#define CLK_SOURCE_SDMMC3 0x1bc +#define CLK_SOURCE_SDMMC4 0x164 +#define CLK_SOURCE_CVE 0x140 +#define CLK_SOURCE_TVO 0x188 +#define CLK_SOURCE_TVDAC 0x194 +#define CLK_SOURCE_VDE 0x1c8 +#define CLK_SOURCE_CSITE 0x1d4 +#define CLK_SOURCE_LA 0x1f8 +#define CLK_SOURCE_TRACE 0x634 +#define CLK_SOURCE_OWR 0x1cc +#define CLK_SOURCE_NOR 0x1d0 +#define CLK_SOURCE_MIPI 0x174 +#define CLK_SOURCE_I2C1 0x124 +#define CLK_SOURCE_I2C2 0x198 +#define CLK_SOURCE_I2C3 0x1b8 +#define CLK_SOURCE_I2C4 0x3c4 +#define CLK_SOURCE_I2C5 0x128 +#define CLK_SOURCE_I2C6 0x65c +#define CLK_SOURCE_UARTA 0x178 +#define CLK_SOURCE_UARTB 0x17c +#define CLK_SOURCE_UARTC 0x1a0 +#define CLK_SOURCE_UARTD 0x1c0 +#define CLK_SOURCE_UARTE 0x1c4 +#define CLK_SOURCE_3D 0x158 +#define CLK_SOURCE_2D 0x15c +#define CLK_SOURCE_MPE 0x170 +#define CLK_SOURCE_UARTE 0x1c4 +#define CLK_SOURCE_VI_SENSOR 0x1a8 +#define CLK_SOURCE_VI 0x148 +#define CLK_SOURCE_EPP 0x16c +#define CLK_SOURCE_MSENC 0x1f0 +#define CLK_SOURCE_TSEC 0x1f4 +#define CLK_SOURCE_HOST1X 0x180 +#define CLK_SOURCE_HDMI 0x18c +#define CLK_SOURCE_DISP1 0x138 +#define CLK_SOURCE_DISP2 0x13c +#define CLK_SOURCE_CILAB 0x614 +#define CLK_SOURCE_CILCD 0x618 +#define CLK_SOURCE_CILE 0x61c +#define CLK_SOURCE_DSIALP 0x620 +#define CLK_SOURCE_DSIBLP 0x624 +#define CLK_SOURCE_TSENSOR 0x3b8 +#define CLK_SOURCE_D_AUDIO 0x3d0 +#define CLK_SOURCE_DAM0 0x3d8 +#define CLK_SOURCE_DAM1 0x3dc +#define CLK_SOURCE_DAM2 0x3e0 +#define CLK_SOURCE_ACTMON 0x3e8 +#define CLK_SOURCE_EXTERN1 0x3ec +#define CLK_SOURCE_EXTERN2 0x3f0 +#define CLK_SOURCE_EXTERN3 0x3f4 +#define CLK_SOURCE_I2CSLOW 0x3fc +#define CLK_SOURCE_SE 0x42c +#define CLK_SOURCE_MSELECT 0x3b4 +#define CLK_SOURCE_DFLL_REF 0x62c +#define CLK_SOURCE_DFLL_SOC 0x630 +#define CLK_SOURCE_SOC_THERM 0x644 +#define CLK_SOURCE_XUSB_HOST_SRC 0x600 +#define CLK_SOURCE_XUSB_FALCON_SRC 0x604 +#define CLK_SOURCE_XUSB_FS_SRC 0x608 +#define CLK_SOURCE_XUSB_SS_SRC 0x610 +#define CLK_SOURCE_XUSB_DEV_SRC 0x60c +#define CLK_SOURCE_ISP 0x144 +#define CLK_SOURCE_SOR0 0x414 +#define CLK_SOURCE_DPAUX 0x418 +#define CLK_SOURCE_SATA_OOB 0x420 +#define CLK_SOURCE_SATA 0x424 +#define CLK_SOURCE_ENTROPY 0x628 +#define CLK_SOURCE_VI_SENSOR2 0x658 +#define CLK_SOURCE_HDMI_AUDIO 0x668 +#define CLK_SOURCE_VIC03 0x678 +#define CLK_SOURCE_CLK72MHZ 0x66c + +#define MASK(x) (BIT(x) - 1) + +#define MUX(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ + NULL) + +#define MUX_FLAGS(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id, flags)\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, _gate_flags, _clk_id, _parents##_idx, flags,\ + NULL) + +#define MUX8(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ + NULL) + +#define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ + _parents##_idx, 0, _lock) + +#define INT(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0, NULL) + +#define INT_FLAGS(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id, flags)\ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, flags, NULL) + +#define INT8(_name, _parents, _offset,\ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0, NULL) + +#define UART(_name, _parents, _offset,\ + _clk_num, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ + _parents##_idx, 0, NULL) + +#define I2C(_name, _parents, _offset,\ + _clk_num, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ + _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) + +#define XUSB(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ + _clk_id, _parents##_idx, 0, NULL) + +#define AUDIO(_name, _offset, _clk_num,\ + _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ + _offset, 16, 0xE01F, 0, 0, 8, 1, \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags, \ + _clk_id, mux_d_audio_clk_idx, 0, NULL) + +#define NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, \ + _gate_flags, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ + _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ + _clk_id, _parents##_idx, 0, _lock) + +#define GATE(_name, _parent_name, \ + _clk_num, _gate_flags, _clk_id, _flags) \ + { \ + .name = _name, \ + .clk_id = _clk_id, \ + .p.parent_name = _parent_name, \ + .periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 0, 0, 0, \ + _clk_num, _gate_flags, 0, NULL), \ + .flags = _flags \ + } + +#define PLLP_BASE 0xa0 +#define PLLP_MISC 0xac +#define PLLP_OUTA 0xa4 +#define PLLP_OUTB 0xa8 +#define PLLP_OUTC 0x67c + +#define PLL_BASE_LOCK BIT(27) +#define PLL_MISC_LOCK_ENABLE 18 + +static DEFINE_SPINLOCK(PLLP_OUTA_lock); +static DEFINE_SPINLOCK(PLLP_OUTB_lock); +static DEFINE_SPINLOCK(PLLP_OUTC_lock); +static DEFINE_SPINLOCK(sor0_lock); + +#define MUX_I2S_SPDIF(_id) \ +static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ + #_id, "pll_p",\ + "clk_m"}; +MUX_I2S_SPDIF(audio0) +MUX_I2S_SPDIF(audio1) +MUX_I2S_SPDIF(audio2) +MUX_I2S_SPDIF(audio3) +MUX_I2S_SPDIF(audio4) +MUX_I2S_SPDIF(audio) + +#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm_clkm[] = { + "pll_p", "pll_c", "pll_m", "clk_m" +}; +#define mux_pllp_pllc_pllm_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; +#define mux_pllp_pllc_pllm_idx NULL + +static const char *mux_pllp_pllc_clk32_clkm[] = { + "pll_p", "pll_c", "clk_32k", "clk_m" +}; +#define mux_pllp_pllc_clk32_clkm_idx NULL + +static const char *mux_plla_pllc_pllp_clkm[] = { + "pll_a_out0", "pll_c", "pll_p", "clk_m" +}; +#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { + "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" +}; +static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, +}; + +static const char *mux_pllp_clkm[] = { + "pll_p", "clk_m" +}; +static u32 mux_pllp_clkm_idx[] = { + [0] = 0, [1] = 3, +}; + +static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { + "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx + +static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { + "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", + "pll_d2_out0", "clk_m" +}; +#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL + +static const char *mux_pllm_pllc_pllp_plla[] = { + "pll_m", "pll_c", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc_clkm[] = { + "pll_p", "pll_c", "pll_m" +}; +static u32 mux_pllp_pllc_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 3, +}; + +static const char *mux_pllp_pllc_clkm_clk32[] = { + "pll_p", "pll_c", "clk_m", "clk_32k" +}; +#define mux_pllp_pllc_clkm_clk32_idx NULL + +static const char *mux_plla_clk32_pllp_clkm_plle[] = { + "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" +}; +#define mux_plla_clk32_pllp_clkm_plle_idx NULL + +static const char *mux_clkm_pllp_pllc_pllre[] = { + "clk_m", "pll_p", "pll_c", "pll_re_out" +}; +static u32 mux_clkm_pllp_pllc_pllre_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 5, +}; + +static const char *mux_clkm_48M_pllp_480M[] = { + "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" +}; +#define mux_clkm_48M_pllp_480M_idx NULL + +static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { + "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" +}; +static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, +}; + +static const char *mux_d_audio_clk[] = { + "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; +static u32 mux_d_audio_clk_idx[] = { + [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, + [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, +}; + +static const char *mux_pllp_plld_pllc_clkm[] = { + "pll_p", "pll_d_out0", "pll_c", "clk_m" +}; +#define mux_pllp_plld_pllc_clkm_idx NULL +static const char *mux_pllm_pllc_pllp_plla_clkm_pllc4[] = { + "pll_m", "pll_c", "pll_p", "pll_a_out0", "clk_m", "pll_c4", +}; +static u32 mux_pllm_pllc_pllp_plla_clkm_pllc4_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 6, [5] = 7, +}; + +static const char *mux_pllp_clkm1[] = { + "pll_p", "clk_m", +}; +#define mux_pllp_clkm1_idx NULL + +static const char *mux_pllp3_pllc_clkm[] = { + "pll_p_out3", "pll_c", "pll_c2", "clk_m", +}; +#define mux_pllp3_pllc_clkm_idx NULL + +static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { + "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" +}; +static u32 mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, +}; + +static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { + "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", +}; +static u32 mux_pllm_pllc2_c_c3_pllp_plla_pllc4_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, [6] = 7, +}; + +static const char *mux_clkm_plldp_sor0lvds[] = { + "clk_m", "pll_dp", "sor0_lvds", +}; +#define mux_clkm_plldp_sor0lvds_idx NULL + +static struct tegra_periph_init_data periph_clks[] = { + AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, tegra_clk_d_audio), + AUDIO("dam0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, tegra_clk_dam0), + AUDIO("dam1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, tegra_clk_dam1), + AUDIO("dam2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, tegra_clk_dam2), + I2C("i2c1", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, tegra_clk_i2c1), + I2C("i2c2", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, tegra_clk_i2c2), + I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, tegra_clk_i2c3), + I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, tegra_clk_i2c4), + I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, tegra_clk_i2c5), + INT("vde", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde), + INT("vi", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi), + INT("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp), + INT("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x), + INT("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60, 0, tegra_clk_mpe), + INT("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d), + INT("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d), + INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8), + INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8), + INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9), + INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp_8), + INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, tegra_clk_msenc), + INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec), + INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), + INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), + INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), + INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), + INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03), + INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, tegra_clk_mselect, CLK_IGNORE_UNUSED), + MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, tegra_clk_i2s0), + MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, tegra_clk_i2s1), + MUX("i2s2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, tegra_clk_i2s2), + MUX("i2s3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, tegra_clk_i2s3), + MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, tegra_clk_i2s4), + MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_out), + MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_in), + MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, tegra_clk_pwm), + MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, tegra_clk_adx), + MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, tegra_clk_amx), + MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda), + MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x), + MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, tegra_clk_vfir), + MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1), + MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2), + MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3), + MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4), + MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), + MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), + MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), + MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, tegra_clk_nor), + MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, tegra_clk_mipi), + MUX("vi_sensor", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor), + MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, tegra_clk_cilab), + MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, tegra_clk_cilcd), + MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, tegra_clk_cile), + MUX("dsialp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, tegra_clk_dsialp), + MUX("dsiblp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, tegra_clk_dsiblp), + MUX("tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, tegra_clk_tsensor), + MUX("actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, tegra_clk_actmon), + MUX("dfll_ref", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_ref), + MUX("dfll_soc", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_soc), + MUX("i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, tegra_clk_i2cslow), + MUX("sbc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1), + MUX("sbc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2), + MUX("sbc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3), + MUX("sbc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4), + MUX("sbc5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5), + MUX("sbc6", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6), + MUX("cve", mux_pllp_plld_pllc_clkm, CLK_SOURCE_CVE, 49, 0, tegra_clk_cve), + MUX("tvo", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVO, 49, 0, tegra_clk_tvo), + MUX("tvdac", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVDAC, 53, 0, tegra_clk_tvdac), + MUX("ndflash", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash), + MUX("ndspeed", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed), + MUX("sata_oob", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob), + MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata), + MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), + MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), + MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), + MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), + MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), + MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), + MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4_8), + MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5_8), + MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6_8), + MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), + MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), + MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), + MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), + MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), + MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), + MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), + MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), + MUX8("isp", mux_pllm_pllc_pllp_plla_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_8), + MUX8("entropy", mux_pllp_clkm1, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy), + MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), + MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), + MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), + MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), + NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), + NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), + NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), + UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), + UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), + UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), + UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), + UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 65, tegra_clk_uarte), + XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), + XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), + XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), + XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src), + XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), +}; + +static struct tegra_periph_init_data gate_clks[] = { + GATE("rtc", "clk_32k", 4, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_rtc, 0), + GATE("timer", "clk_m", 5, 0, tegra_clk_timer, 0), + GATE("isp", "clk_m", 23, 0, tegra_clk_isp, 0), + GATE("vcp", "clk_m", 29, 0, tegra_clk_vcp, 0), + GATE("apbdma", "clk_m", 34, 0, tegra_clk_apbdma, 0), + GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), + GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), + GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), + GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), + GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0), + GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), + GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), + GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), + GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), + GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), + GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), + GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), + GATE("csi", "pll_p_out3", 52, 0, tegra_clk_csi, 0), + GATE("afi", "clk_m", 72, 0, tegra_clk_afi, 0), + GATE("csus", "clk_m", 92, TEGRA_PERIPH_NO_RESET, tegra_clk_csus, 0), + GATE("dds", "clk_m", 150, TEGRA_PERIPH_ON_APB, tegra_clk_dds, 0), + GATE("dp2", "clk_m", 152, TEGRA_PERIPH_ON_APB, tegra_clk_dp2, 0), + GATE("dtv", "clk_m", 79, TEGRA_PERIPH_ON_APB, tegra_clk_dtv, 0), + GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), + GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), + GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), + GATE("dsia", "dsia_mux", 48, 0, tegra_clk_dsia, 0), + GATE("dsib", "dsib_mux", 82, 0, tegra_clk_dsib, 0), + GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), + GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), + GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), + GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), + GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), + GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), + GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), +}; + +struct pll_out_data { + char *div_name; + char *pll_out_name; + u32 offset; + int clk_id; + u8 div_shift; + u8 div_flags; + u8 rst_shift; + spinlock_t *lock; +}; + +#define PLL_OUT(_num, _offset, _div_shift, _div_flags, _rst_shift, _id) \ + {\ + .div_name = "pll_p_out" #_num "_div",\ + .pll_out_name = "pll_p_out" #_num,\ + .offset = _offset,\ + .div_shift = _div_shift,\ + .div_flags = _div_flags | TEGRA_DIVIDER_FIXED |\ + TEGRA_DIVIDER_ROUND_UP,\ + .rst_shift = _rst_shift,\ + .clk_id = tegra_clk_ ## _id,\ + .lock = &_offset ##_lock,\ + } + +static struct pll_out_data pllp_out_clks[] = { + PLL_OUT(1, PLLP_OUTA, 8, 0, 0, pll_p_out1), + PLL_OUT(2, PLLP_OUTA, 24, 0, 16, pll_p_out2), + PLL_OUT(2, PLLP_OUTA, 24, TEGRA_DIVIDER_INT, 16, pll_p_out2_int), + PLL_OUT(3, PLLP_OUTB, 8, 0, 0, pll_p_out3), + PLL_OUT(4, PLLP_OUTB, 24, 0, 16, pll_p_out4), + PLL_OUT(5, PLLP_OUTC, 24, 0, 16, pll_p_out5), +}; + +static void __init periph_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + int i; + struct clk *clk; + struct clk **dt_clk; + + for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { + struct tegra_clk_periph_regs *bank; + struct tegra_periph_init_data *data; + + data = periph_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + bank = get_reg_bank(data->periph.gate.clk_num); + if (!bank) + continue; + + data->periph.gate.regs = bank; + clk = tegra_clk_register_periph(data->name, + data->p.parent_names, data->num_parents, + &data->periph, clk_base, data->offset, + data->flags); + *dt_clk = clk; + } +} + +static void __init gate_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + int i; + struct clk *clk; + struct clk **dt_clk; + + for (i = 0; i < ARRAY_SIZE(gate_clks); i++) { + struct tegra_periph_init_data *data; + + data = gate_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_periph_gate(data->name, + data->p.parent_name, data->periph.gate.flags, + clk_base, data->flags, + data->periph.gate.clk_num, + periph_clk_enb_refcnt); + *dt_clk = clk; + } +} + +static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p, tegra_clks); + if (dt_clk) { + /* PLLP */ + clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, + pmc_base, 0, pll_params, NULL); + clk_register_clkdev(clk, "pll_p", NULL); + *dt_clk = clk; + } + + for (i = 0; i < ARRAY_SIZE(pllp_out_clks); i++) { + struct pll_out_data *data; + + data = pllp_out_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_divider(data->div_name, "pll_p", + clk_base + data->offset, 0, data->div_flags, + data->div_shift, 8, 1, data->lock); + clk = tegra_clk_register_pll_out(data->pll_out_name, + data->div_name, clk_base + data->offset, + data->rst_shift + 1, data->rst_shift, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + data->lock); + *dt_clk = clk; + } +} + +void __init tegra_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params) +{ + init_pllp(clk_base, pmc_base, tegra_clks, pll_params); + periph_clk_init(clk_base, tegra_clks); + gate_clk_init(clk_base, tegra_clks); +} diff --git a/drivers/clk/tegra/clk-tegra-pmc.c b/drivers/clk/tegra/clk-tegra-pmc.c new file mode 100644 index 0000000..08b21c1 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-pmc.c @@ -0,0 +1,132 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#include "clk.h" +#include "clk-id.h" + +#define PMC_CLK_OUT_CNTRL 0x1a8 +#define PMC_DPD_PADS_ORIDE 0x1c +#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 +#define PMC_CTRL 0 +#define PMC_CTRL_BLINK_ENB 7 +#define PMC_BLINK_TIMER 0x40 + +struct pmc_clk_init_data { + char *mux_name; + char *gate_name; + const char **parents; + int num_parents; + int mux_id; + int gate_id; + char *dev_name; + u8 mux_shift; + u8 gate_shift; +}; + +#define PMC_CLK(_num, _mux_shift, _gate_shift)\ + {\ + .mux_name = "clk_out_" #_num "_mux",\ + .gate_name = "clk_out_" #_num,\ + .parents = clk_out ##_num ##_parents,\ + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\ + .mux_id = tegra_clk_clk_out_ ##_num ##_mux,\ + .gate_id = tegra_clk_clk_out_ ##_num,\ + .dev_name = "extern" #_num,\ + .mux_shift = _mux_shift,\ + .gate_shift = _gate_shift,\ + } + +static DEFINE_SPINLOCK(clk_out_lock); + +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern1", +}; + +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern2", +}; + +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern3", +}; + +static struct pmc_clk_init_data pmc_clks[] = { + PMC_CLK(1, 6, 2), + PMC_CLK(2, 14, 10), + PMC_CLK(3, 22, 18), +}; + +void __init tegra_pmc_clk_init(void __iomem *pmc_base, + struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + int i; + + for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) { + struct pmc_clk_init_data *data; + + data = pmc_clks + i; + + dt_clk = tegra_lookup_dt_id(data->mux_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_mux(NULL, data->mux_name, data->parents, + data->num_parents, CLK_SET_RATE_NO_REPARENT, + pmc_base + PMC_CLK_OUT_CNTRL, data->mux_shift, + 3, 0, &clk_out_lock); + *dt_clk = clk; + + + dt_clk = tegra_lookup_dt_id(data->gate_id, tegra_clks); + if (!dt_clk) + continue; + + clk = clk_register_gate(NULL, data->gate_name, data->mux_name, + 0, pmc_base + PMC_CLK_OUT_CNTRL, + data->gate_shift, 0, &clk_out_lock); + *dt_clk = clk; + clk_register_clkdev(clk, data->dev_name, data->gate_name); + } + + /* blink */ + writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); + clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, + pmc_base + PMC_DPD_PADS_ORIDE, + PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); + + dt_clk = tegra_lookup_dt_id(tegra_clk_blink, tegra_clks); + if (!dt_clk) + return; + + clk = clk_register_gate(NULL, "blink", "blink_override", 0, + pmc_base + PMC_CTRL, + PMC_CTRL_BLINK_ENB, 0, NULL); + clk_register_clkdev(clk, "blink", NULL); + *dt_clk = clk; +} + diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c new file mode 100644 index 0000000..05dce4a --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -0,0 +1,149 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> + +#include "clk.h" +#include "clk-id.h" + +#define PLLX_BASE 0xe0 +#define PLLX_MISC 0xe4 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 + +#define CCLKG_BURST_POLICY 0x368 +#define CCLKLP_BURST_POLICY 0x370 +#define SCLK_BURST_POLICY 0x028 +#define SYSTEM_CLK_RATE 0x030 + +static DEFINE_SPINLOCK(sysrate_lock); + +static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", + "pll_p", "pll_p_out2", "unused", + "clk_32k", "pll_m_out1" }; + +static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x" }; + +static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x", "pll_x_out0" }; + +static void __init tegra_sclk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + struct clk *clk; + struct clk **dt_clk; + + /* SCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("sclk", sclk_parents, + ARRAY_SIZE(sclk_parents), + CLK_SET_RATE_PARENT, + clk_base + SCLK_BURST_POLICY, + 0, 4, 0, 0, NULL); + *dt_clk = clk; + } + + /* HCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_hclk, tegra_clks); + if (dt_clk) { + clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, + clk_base + SYSTEM_CLK_RATE, 4, 2, 0, + &sysrate_lock); + clk = clk_register_gate(NULL, "hclk", "hclk_div", + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + clk_base + SYSTEM_CLK_RATE, + 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); + *dt_clk = clk; + } + + /* PCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pclk, tegra_clks); + if (!dt_clk) + return; + + clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, + clk_base + SYSTEM_CLK_RATE, 0, 2, 0, + &sysrate_lock); + clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | + CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, + 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); + *dt_clk = clk; +} + +void __init tegra_super_clk_gen4_init(void __iomem *clk_base, + void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *params) +{ + struct clk *clk; + struct clk **dt_clk; + + /* CCLKG */ + dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, + ARRAY_SIZE(cclk_g_parents), + CLK_SET_RATE_PARENT, + clk_base + CCLKG_BURST_POLICY, + 0, 4, 0, 0, NULL); + *dt_clk = clk; + } + + /* CCLKLP */ + dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, + ARRAY_SIZE(cclk_lp_parents), + CLK_SET_RATE_PARENT, + clk_base + CCLKLP_BURST_POLICY, + 0, 4, 8, 9, NULL); + *dt_clk = clk; + } + + tegra_sclk_init(clk_base, tegra_clks); + +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) + /* PLLX */ + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks); + if (!dt_clk) + return; + + clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, + pmc_base, CLK_IGNORE_UNUSED, params, NULL); + *dt_clk = clk; + + /* PLLX_OUT0 */ + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x_out0, tegra_clks); + if (!dt_clk) + return; + clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", + CLK_SET_RATE_PARENT, 1, 2); + *dt_clk = clk; +#endif +} + diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9467da7..90d9d25 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -23,30 +23,15 @@ #include <linux/delay.h> #include <linux/export.h> #include <linux/clk/tegra.h> +#include <dt-bindings/clock/tegra114-car.h> #include "clk.h" +#include "clk-id.h" -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00C #define RST_DFLL_DVCO 0x2F4 -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35C -#define RST_DEVICES_X 0x28C -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ #define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */ #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */ -#define RST_DEVICES_NUM 5 /* RST_DFLL_DVCO bitfields */ #define DVFS_DFLL_RESET_SHIFT 0 @@ -73,25 +58,7 @@ #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_X 0x280 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c -#define CLK_OUT_ENB_SET_X 0x284 -#define CLK_OUT_ENB_CLR_X 0x288 -#define CLK_OUT_ENB_NUM 6 +#define TEGRA114_CLK_PERIPH_BANKS 5 #define PLLC_BASE 0x80 #define PLLC_MISC2 0x88 @@ -139,25 +106,6 @@ #define PLLE_AUX 0x48c #define PLLC_OUT 0x84 #define PLLM_OUT 0x94 -#define PLLP_OUTA 0xa4 -#define PLLP_OUTB 0xa8 -#define PLLA_OUT 0xb4 - -#define AUDIO_SYNC_CLK_I2S0 0x4a0 -#define AUDIO_SYNC_CLK_I2S1 0x4a4 -#define AUDIO_SYNC_CLK_I2S2 0x4a8 -#define AUDIO_SYNC_CLK_I2S3 0x4ac -#define AUDIO_SYNC_CLK_I2S4 0x4b0 -#define AUDIO_SYNC_CLK_SPDIF 0x4b4 - -#define AUDIO_SYNC_DOUBLER 0x49c - -#define PMC_CLK_OUT_CNTRL 0x1a8 -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_CTRL 0 -#define PMC_CTRL_BLINK_ENB 7 -#define PMC_BLINK_TIMER 0x40 #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_SHIFT 28 @@ -166,9 +114,6 @@ #define PLLXC_SW_MAX_P 6 #define CCLKG_BURST_POLICY 0x368 -#define CCLKLP_BURST_POLICY 0x370 -#define SCLK_BURST_POLICY 0x028 -#define SYSTEM_CLK_RATE 0x030 #define UTMIP_PLL_CFG2 0x488 #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) @@ -196,91 +141,8 @@ #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) -#define CLK_SOURCE_I2S0 0x1d8 -#define CLK_SOURCE_I2S1 0x100 -#define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_I2S3 0x3bc -#define CLK_SOURCE_I2S4 0x3c0 -#define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c -#define CLK_SOURCE_PWM 0x110 -#define CLK_SOURCE_ADX 0x638 -#define CLK_SOURCE_AMX 0x63c -#define CLK_SOURCE_HDA 0x428 -#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 -#define CLK_SOURCE_SBC5 0x3c8 -#define CLK_SOURCE_SBC6 0x3cc -#define CLK_SOURCE_SATA_OOB 0x420 -#define CLK_SOURCE_SATA 0x424 -#define CLK_SOURCE_NDSPEED 0x3f8 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_VDE 0x1c8 #define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_TRACE 0x634 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 -#define CLK_SOURCE_I2C1 0x124 -#define CLK_SOURCE_I2C2 0x198 -#define CLK_SOURCE_I2C3 0x1b8 -#define CLK_SOURCE_I2C4 0x3c4 -#define CLK_SOURCE_I2C5 0x128 -#define CLK_SOURCE_UARTA 0x178 -#define CLK_SOURCE_UARTB 0x17c -#define CLK_SOURCE_UARTC 0x1a0 -#define CLK_SOURCE_UARTD 0x1c0 -#define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_UARTA_DBG 0x178 -#define CLK_SOURCE_UARTB_DBG 0x17c -#define CLK_SOURCE_UARTC_DBG 0x1a0 -#define CLK_SOURCE_UARTD_DBG 0x1c0 -#define CLK_SOURCE_UARTE_DBG 0x1c4 -#define CLK_SOURCE_3D 0x158 -#define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_VI_SENSOR 0x1a8 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_MSENC 0x1f0 -#define CLK_SOURCE_TSEC 0x1f4 -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_HDMI 0x18c -#define CLK_SOURCE_DISP1 0x138 -#define CLK_SOURCE_DISP2 0x13c -#define CLK_SOURCE_CILAB 0x614 -#define CLK_SOURCE_CILCD 0x618 -#define CLK_SOURCE_CILE 0x61c -#define CLK_SOURCE_DSIALP 0x620 -#define CLK_SOURCE_DSIBLP 0x624 -#define CLK_SOURCE_TSENSOR 0x3b8 -#define CLK_SOURCE_D_AUDIO 0x3d0 -#define CLK_SOURCE_DAM0 0x3d8 -#define CLK_SOURCE_DAM1 0x3dc -#define CLK_SOURCE_DAM2 0x3e0 -#define CLK_SOURCE_ACTMON 0x3e8 -#define CLK_SOURCE_EXTERN1 0x3ec -#define CLK_SOURCE_EXTERN2 0x3f0 -#define CLK_SOURCE_EXTERN3 0x3f4 -#define CLK_SOURCE_I2CSLOW 0x3fc -#define CLK_SOURCE_SE 0x42c -#define CLK_SOURCE_MSELECT 0x3b4 -#define CLK_SOURCE_DFLL_REF 0x62c -#define CLK_SOURCE_DFLL_SOC 0x630 -#define CLK_SOURCE_SOC_THERM 0x644 -#define CLK_SOURCE_XUSB_HOST_SRC 0x600 -#define CLK_SOURCE_XUSB_FALCON_SRC 0x604 -#define CLK_SOURCE_XUSB_FS_SRC 0x608 #define CLK_SOURCE_XUSB_SS_SRC 0x610 -#define CLK_SOURCE_XUSB_DEV_SRC 0x60c #define CLK_SOURCE_EMC 0x19c /* PLLM override registers */ @@ -298,19 +160,13 @@ static struct cpu_clk_suspend_context { } tegra114_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_d2_lock); static DEFINE_SPINLOCK(pll_u_lock); -static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(pll_re_lock); -static DEFINE_SPINLOCK(clk_doubler_lock); -static DEFINE_SPINLOCK(clk_out_lock); -static DEFINE_SPINLOCK(sysrate_lock); static struct div_nmp pllxc_nmp = { .divm_shift = 0, @@ -370,6 +226,8 @@ static struct tegra_clk_pll_params pll_c_params = { .stepb_shift = 9, .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllcx_nmp = { @@ -417,6 +275,8 @@ static struct tegra_clk_pll_params pll_c2_params = { .ext_misc_reg[0] = 0x4f0, .ext_misc_reg[1] = 0x4f4, .ext_misc_reg[2] = 0x4f8, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_c3_params = { @@ -437,6 +297,8 @@ static struct tegra_clk_pll_params pll_c3_params = { .ext_misc_reg[0] = 0x504, .ext_misc_reg[1] = 0x508, .ext_misc_reg[2] = 0x50c, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllm_nmp = { @@ -483,6 +345,8 @@ static struct tegra_clk_pll_params pll_m_params = { .div_nmp = &pllm_nmp, .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllp_nmp = { @@ -516,6 +380,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &pllp_nmp, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, + .fixed_rate = 408000000, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { @@ -543,6 +410,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &pllp_nmp, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { @@ -579,6 +448,9 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_d2_params = { @@ -594,6 +466,9 @@ static struct tegra_clk_pll_params pll_d2_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct pdiv_map pllu_p[] = { @@ -634,6 +509,9 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_delay = 1000, .pdiv_tohw = pllu_p, .div_nmp = &pllu_nmp, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { @@ -667,12 +545,15 @@ static struct tegra_clk_pll_params pll_x_params = { .stepb_shift = 24, .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ {336000000, 100000000, 100, 21, 16, 11}, {312000000, 100000000, 200, 26, 24, 13}, + {12000000, 100000000, 200, 1, 24, 13}, {0, 0, 0, 0, 0, 0}, }; @@ -699,6 +580,9 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, .div_nmp = &plle_nmp, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; static struct div_nmp pllre_nmp = { @@ -725,53 +609,7 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .iddq_reg = PLLRE_MISC, .iddq_bit_idx = PLLRE_IDDQ_BIT, .div_nmp = &pllre_nmp, -}; - -/* Peripheral clock registers */ - -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, -}; - -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, -}; - -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, -}; - -static struct tegra_clk_periph_regs periph_v_regs = { - .enb_reg = CLK_OUT_ENB_V, - .enb_set_reg = CLK_OUT_ENB_SET_V, - .enb_clr_reg = CLK_OUT_ENB_CLR_V, - .rst_reg = RST_DEVICES_V, - .rst_set_reg = RST_DEVICES_SET_V, - .rst_clr_reg = RST_DEVICES_CLR_V, -}; - -static struct tegra_clk_periph_regs periph_w_regs = { - .enb_reg = CLK_OUT_ENB_W, - .enb_set_reg = CLK_OUT_ENB_SET_W, - .enb_clr_reg = CLK_OUT_ENB_CLR_W, - .rst_reg = RST_DEVICES_W, - .rst_set_reg = RST_DEVICES_SET_W, - .rst_clr_reg = RST_DEVICES_CLR_W, + .flags = TEGRA_PLL_USE_LOCK, }; /* possible OSC frequencies in Hz */ @@ -787,120 +625,6 @@ static unsigned long tegra114_input_freq[] = { #define MASK(x) (BIT(x) - 1) -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) - -#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, flags) - -#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id, \ - _parents##_idx, 0) - -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id, flags)\ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, flags) - -#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\ - _clk_num, periph_clk_enb_refcnt, 0, _clk_id, \ - _parents##_idx, 0) - -#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - 30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_mask, _clk_num, _regs, \ - _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ - _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ - 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id, _parents##_idx, 0) - -#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ - _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ - _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags , _clk_id, \ - mux_d_audio_clk_idx, 0) - -enum tegra114_clk { - rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12, - ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19, - gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27, - host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40, - sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48, - mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56, - emc, usb2, usb3, vde = 61, bsea = 62, bsev = 63, uartd = 65, - i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73, - la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80, - i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91, - csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102, - i2c4 = 103, sbc5 = 104, sbc6 = 105, d_audio, apbif = 107, dam0, dam1, - dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x, - audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120, - extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128, - cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148, - dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192, - vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k, - clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2, - pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3, - pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0, - pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0, - pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync, - i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0, - audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, - blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src, - xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp, - dfll_ref = 264, dfll_soc, - - /* Mux clocks */ - - audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux, - spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux, - dsib_mux, clk_max, -}; - struct utmi_clk_param { /* Oscillator Frequency in KHz */ u32 osc_frequency; @@ -934,122 +658,11 @@ static const struct utmi_clk_param utmi_parameters[] = { /* peripheral mux definitions */ -#define MUX_I2S_SPDIF(_id) \ -static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ - #_id, "pll_p",\ - "clk_m"}; -MUX_I2S_SPDIF(audio0) -MUX_I2S_SPDIF(audio1) -MUX_I2S_SPDIF(audio2) -MUX_I2S_SPDIF(audio3) -MUX_I2S_SPDIF(audio4) -MUX_I2S_SPDIF(audio) - -#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL -#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL - -static const char *mux_pllp_pllc_pllm_clkm[] = { - "pll_p", "pll_c", "pll_m", "clk_m" -}; -#define mux_pllp_pllc_pllm_clkm_idx NULL - -static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; -#define mux_pllp_pllc_pllm_idx NULL - -static const char *mux_pllp_pllc_clk32_clkm[] = { - "pll_p", "pll_c", "clk_32k", "clk_m" -}; -#define mux_pllp_pllc_clk32_clkm_idx NULL - -static const char *mux_plla_pllc_pllp_clkm[] = { - "pll_a_out0", "pll_c", "pll_p", "clk_m" -}; -#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx - -static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { - "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" -}; -static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { - [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, -}; - -static const char *mux_pllp_clkm[] = { - "pll_p", "clk_m" -}; -static u32 mux_pllp_clkm_idx[] = { - [0] = 0, [1] = 3, -}; - -static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { - "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" -}; -#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx - -static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { - "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", - "pll_d2_out0", "clk_m" -}; -#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL - -static const char *mux_pllm_pllc_pllp_plla[] = { - "pll_m", "pll_c", "pll_p", "pll_a_out0" -}; -#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx - -static const char *mux_pllp_pllc_clkm[] = { - "pll_p", "pll_c", "pll_m" -}; -static u32 mux_pllp_pllc_clkm_idx[] = { - [0] = 0, [1] = 1, [2] = 3, -}; - -static const char *mux_pllp_pllc_clkm_clk32[] = { - "pll_p", "pll_c", "clk_m", "clk_32k" -}; -#define mux_pllp_pllc_clkm_clk32_idx NULL - -static const char *mux_plla_clk32_pllp_clkm_plle[] = { - "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" -}; -#define mux_plla_clk32_pllp_clkm_plle_idx NULL - -static const char *mux_clkm_pllp_pllc_pllre[] = { - "clk_m", "pll_p", "pll_c", "pll_re_out" -}; -static u32 mux_clkm_pllp_pllc_pllre_idx[] = { - [0] = 0, [1] = 1, [2] = 3, [3] = 5, -}; - -static const char *mux_clkm_48M_pllp_480M[] = { - "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" -}; -#define mux_clkm_48M_pllp_480M_idx NULL - -static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { - "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" -}; -static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { - [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, -}; - static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0", }; #define mux_plld_out0_plld2_out0_idx NULL -static const char *mux_d_audio_clk[] = { - "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", -}; -static u32 mux_d_audio_clk_idx[] = { - [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, - [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, -}; - static const char *mux_pllmcp_clkm[] = { "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud", }; @@ -1064,8 +677,253 @@ static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 0 }, }; -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { + [tegra_clk_rtc] = { .dt_id = TEGRA114_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, + [tegra_clk_epp_8] = { .dt_id = TEGRA114_CLK_EPP, .present = true }, + [tegra_clk_gr2d_8] = { .dt_id = TEGRA114_CLK_GR2D, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA114_CLK_USBD, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA114_CLK_ISP, .present = true }, + [tegra_clk_gr3d_8] = { .dt_id = TEGRA114_CLK_GR3D, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA114_CLK_DISP2, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA114_CLK_DISP1, .present = true }, + [tegra_clk_host1x_8] = { .dt_id = TEGRA114_CLK_HOST1X, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA114_CLK_VCP, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA114_CLK_APBDMA, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA114_CLK_KBC, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA114_CLK_KFUSE, .present = true }, + [tegra_clk_sbc1_8] = { .dt_id = TEGRA114_CLK_SBC1, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA114_CLK_NOR, .present = true }, + [tegra_clk_sbc2_8] = { .dt_id = TEGRA114_CLK_SBC2, .present = true }, + [tegra_clk_sbc3_8] = { .dt_id = TEGRA114_CLK_SBC3, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA114_CLK_I2C5, .present = true }, + [tegra_clk_dsia] = { .dt_id = TEGRA114_CLK_DSIA, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA114_CLK_MIPI, .present = true }, + [tegra_clk_hdmi] = { .dt_id = TEGRA114_CLK_HDMI, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, + [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, + [tegra_clk_vde_8] = { .dt_id = TEGRA114_CLK_VDE, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA114_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, + [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, + [tegra_clk_trace] = { .dt_id = TEGRA114_CLK_TRACE, .present = true }, + [tegra_clk_soc_therm] = { .dt_id = TEGRA114_CLK_SOC_THERM, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA114_CLK_DTV, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA114_CLK_NDSPEED, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA114_CLK_I2CSLOW, .present = true }, + [tegra_clk_dsib] = { .dt_id = TEGRA114_CLK_DSIB, .present = true }, + [tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true }, + [tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true }, + [tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA114_CLK_I2S4, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA114_CLK_I2C4, .present = true }, + [tegra_clk_sbc5_8] = { .dt_id = TEGRA114_CLK_SBC5, .present = true }, + [tegra_clk_sbc6_8] = { .dt_id = TEGRA114_CLK_SBC6, .present = true }, + [tegra_clk_d_audio] = { .dt_id = TEGRA114_CLK_D_AUDIO, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA114_CLK_APBIF, .present = true }, + [tegra_clk_dam0] = { .dt_id = TEGRA114_CLK_DAM0, .present = true }, + [tegra_clk_dam1] = { .dt_id = TEGRA114_CLK_DAM1, .present = true }, + [tegra_clk_dam2] = { .dt_id = TEGRA114_CLK_DAM2, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA114_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA114_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA114_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA114_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA114_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA114_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA114_CLK_SPDIF_2X, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA114_CLK_ACTMON, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA114_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA114_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA114_CLK_EXTERN3, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA114_CLK_HDA, .present = true }, + [tegra_clk_se] = { .dt_id = TEGRA114_CLK_SE, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA114_CLK_HDA2HDMI, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA114_CLK_CILAB, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA114_CLK_CILCD, .present = true }, + [tegra_clk_cile] = { .dt_id = TEGRA114_CLK_CILE, .present = true }, + [tegra_clk_dsialp] = { .dt_id = TEGRA114_CLK_DSIALP, .present = true }, + [tegra_clk_dsiblp] = { .dt_id = TEGRA114_CLK_DSIBLP, .present = true }, + [tegra_clk_dds] = { .dt_id = TEGRA114_CLK_DDS, .present = true }, + [tegra_clk_dp2] = { .dt_id = TEGRA114_CLK_DP2, .present = true }, + [tegra_clk_amx] = { .dt_id = TEGRA114_CLK_AMX, .present = true }, + [tegra_clk_adx] = { .dt_id = TEGRA114_CLK_ADX, .present = true }, + [tegra_clk_xusb_ss] = { .dt_id = TEGRA114_CLK_XUSB_SS, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA114_CLK_UARTB, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA114_CLK_VFIR, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA114_CLK_SPDIF_IN, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA114_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_vi_8] = { .dt_id = TEGRA114_CLK_VI, .present = true }, + [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA114_CLK_VI_SENSOR, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA114_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA114_CLK_FUSE_BURN, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA114_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA114_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA114_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA114_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA114_CLK_PLL_REF, .present = true }, + [tegra_clk_pll_c] = { .dt_id = TEGRA114_CLK_PLL_C, .present = true }, + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA114_CLK_PLL_C_OUT1, .present = true }, + [tegra_clk_pll_c2] = { .dt_id = TEGRA114_CLK_PLL_C2, .present = true }, + [tegra_clk_pll_c3] = { .dt_id = TEGRA114_CLK_PLL_C3, .present = true }, + [tegra_clk_pll_m] = { .dt_id = TEGRA114_CLK_PLL_M, .present = true }, + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA114_CLK_PLL_M_OUT1, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA114_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA114_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2_int] = { .dt_id = TEGRA114_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA114_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA114_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA114_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA114_CLK_PLL_A_OUT0, .present = true }, + [tegra_clk_pll_d] = { .dt_id = TEGRA114_CLK_PLL_D, .present = true }, + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA114_CLK_PLL_D_OUT0, .present = true }, + [tegra_clk_pll_d2] = { .dt_id = TEGRA114_CLK_PLL_D2, .present = true }, + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA114_CLK_PLL_D2_OUT0, .present = true }, + [tegra_clk_pll_u] = { .dt_id = TEGRA114_CLK_PLL_U, .present = true }, + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA114_CLK_PLL_U_480M, .present = true }, + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA114_CLK_PLL_U_60M, .present = true }, + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA114_CLK_PLL_U_48M, .present = true }, + [tegra_clk_pll_u_12m] = { .dt_id = TEGRA114_CLK_PLL_U_12M, .present = true }, + [tegra_clk_pll_x] = { .dt_id = TEGRA114_CLK_PLL_X, .present = true }, + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA114_CLK_PLL_X_OUT0, .present = true }, + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA114_CLK_PLL_RE_VCO, .present = true }, + [tegra_clk_pll_re_out] = { .dt_id = TEGRA114_CLK_PLL_RE_OUT, .present = true }, + [tegra_clk_pll_e_out0] = { .dt_id = TEGRA114_CLK_PLL_E_OUT0, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA114_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA114_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA114_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA114_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA114_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA114_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA114_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA114_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA114_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA114_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA114_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA114_CLK_SPDIF, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA114_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA114_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA114_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA114_CLK_BLINK, .present = true }, + [tegra_clk_xusb_host_src] = { .dt_id = TEGRA114_CLK_XUSB_HOST_SRC, .present = true }, + [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true }, + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true }, + [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA114_CLK_XUSB_SS_SRC, .present = true }, + [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA114_CLK_XUSB_DEV_SRC, .present = true }, + [tegra_clk_xusb_dev] = { .dt_id = TEGRA114_CLK_XUSB_DEV, .present = true }, + [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA114_CLK_XUSB_HS_SRC, .present = true }, + [tegra_clk_sclk] = { .dt_id = TEGRA114_CLK_SCLK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA114_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA114_CLK_PCLK, .present = true }, + [tegra_clk_cclk_g] = { .dt_id = TEGRA114_CLK_CCLK_G, .present = true }, + [tegra_clk_cclk_lp] = { .dt_id = TEGRA114_CLK_CCLK_LP, .present = true }, + [tegra_clk_dfll_ref] = { .dt_id = TEGRA114_CLK_DFLL_REF, .present = true }, + [tegra_clk_dfll_soc] = { .dt_id = TEGRA114_CLK_DFLL_SOC, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA114_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA114_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA114_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA114_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA114_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA114_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_dsia_mux] = { .dt_id = TEGRA114_CLK_DSIA_MUX, .present = true }, + [tegra_clk_dsib_mux] = { .dt_id = TEGRA114_CLK_DSIB_MUX, .present = true }, +}; + +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "clk_m", .dt_id = TEGRA114_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA114_CLK_PLL_REF }, + { .con_id = "clk_32k", .dt_id = TEGRA114_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA114_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA114_CLK_CLK_M_DIV4 }, + { .con_id = "pll_c", .dt_id = TEGRA114_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA114_CLK_PLL_C_OUT1 }, + { .con_id = "pll_c2", .dt_id = TEGRA114_CLK_PLL_C2 }, + { .con_id = "pll_c3", .dt_id = TEGRA114_CLK_PLL_C3 }, + { .con_id = "pll_p", .dt_id = TEGRA114_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA114_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA114_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA114_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA114_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA114_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA114_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA114_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA114_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA114_CLK_PLL_U }, + { .con_id = "pll_u_480M", .dt_id = TEGRA114_CLK_PLL_U_480M }, + { .con_id = "pll_u_60M", .dt_id = TEGRA114_CLK_PLL_U_60M }, + { .con_id = "pll_u_48M", .dt_id = TEGRA114_CLK_PLL_U_48M }, + { .con_id = "pll_u_12M", .dt_id = TEGRA114_CLK_PLL_U_12M }, + { .con_id = "pll_d", .dt_id = TEGRA114_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA114_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA114_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA114_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA114_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA114_CLK_PLL_A_OUT0 }, + { .con_id = "pll_re_vco", .dt_id = TEGRA114_CLK_PLL_RE_VCO }, + { .con_id = "pll_re_out", .dt_id = TEGRA114_CLK_PLL_RE_OUT }, + { .con_id = "pll_e_out0", .dt_id = TEGRA114_CLK_PLL_E_OUT0 }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA114_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA114_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA114_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA114_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA114_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA114_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA114_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA114_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA114_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA114_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA114_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA114_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA114_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA114_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA114_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA114_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA114_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA114_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA114_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA114_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA114_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA114_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA114_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA114_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA114_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA114_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA114_CLK_FUSE }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA114_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA114_CLK_TIMER }, +}; + +static struct clk **clks; static unsigned long osc_freq; static unsigned long pll_ref_freq; @@ -1086,16 +944,14 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) /* clk_m */ clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, osc_freq); - clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; + clks[TEGRA114_CLK_CLK_M] = clk; /* pll_ref */ val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; pll_ref_div = 1 << val; clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + clks[TEGRA114_CLK_PLL_REF] = clk; pll_ref_freq = osc_freq / pll_ref_div; @@ -1109,20 +965,17 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) /* clk_32k */ clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, 32768); - clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; + clks[TEGRA114_CLK_CLK_32K] = clk; /* clk_m_div2 */ clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "clk_m_div2", NULL); - clks[clk_m_div2] = clk; + clks[TEGRA114_CLK_CLK_M_DIV2] = clk; /* clk_m_div4 */ clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", CLK_SET_RATE_PARENT, 1, 4); - clk_register_clkdev(clk, "clk_m_div4", NULL); - clks[clk_m_div4] = clk; + clks[TEGRA114_CLK_CLK_M_DIV4] = clk; } @@ -1208,63 +1061,6 @@ static __init void tegra114_utmi_param_configure(void __iomem *clk_base) writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); } -static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params) -{ - pll_params->vco_min = - DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq; -} - -static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, - void __iomem *clk_base) -{ - u32 val; - u32 step_a, step_b; - - switch (pll_ref_freq) { - case 12000000: - case 13000000: - case 26000000: - step_a = 0x2B; - step_b = 0x0B; - break; - case 16800000: - step_a = 0x1A; - step_b = 0x09; - break; - case 19200000: - step_a = 0x12; - step_b = 0x08; - break; - default: - pr_err("%s: Unexpected reference rate %lu\n", - __func__, pll_ref_freq); - WARN_ON(1); - return -EINVAL; - } - - val = step_a << pll_params->stepa_shift; - val |= step_b << pll_params->stepb_shift; - writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); - - return 0; -} - -static void __init _init_iddq(struct tegra_clk_pll_params *pll_params, - void __iomem *clk_base) -{ - u32 val, val_iddq; - - val = readl_relaxed(clk_base + pll_params->base_reg); - val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); - - if (val & BIT(30)) - WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); - else { - val_iddq |= BIT(pll_params->iddq_bit_idx); - writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); - } -} - static void __init tegra114_pll_init(void __iomem *clk_base, void __iomem *pmc) { @@ -1272,104 +1068,34 @@ static void __init tegra114_pll_init(void __iomem *clk_base, struct clk *clk; /* PLLC */ - _clip_vco_min(&pll_c_params); - if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) { - _init_iddq(&pll_c_params, clk_base); - clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, - pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, - pll_c_freq_table, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; - - /* PLLC_OUT1 */ - clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", - clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", - clk_base + PLLC_OUT, 1, 0, - CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; - } + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, &pll_c_params, NULL); + clks[TEGRA114_CLK_PLL_C] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clks[TEGRA114_CLK_PLL_C_OUT1] = clk; /* PLLC2 */ - _clip_vco_min(&pll_c2_params); - clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, - &pll_c2_params, TEGRA_PLL_USE_LOCK, - pll_cx_freq_table, NULL); - clk_register_clkdev(clk, "pll_c2", NULL); - clks[pll_c2] = clk; + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, + &pll_c2_params, NULL); + clks[TEGRA114_CLK_PLL_C2] = clk; /* PLLC3 */ - _clip_vco_min(&pll_c3_params); - clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, - &pll_c3_params, TEGRA_PLL_USE_LOCK, - pll_cx_freq_table, NULL); - clk_register_clkdev(clk, "pll_c3", NULL); - clks[pll_c3] = clk; - - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, - 408000000, &pll_p_params, - TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, - pll_p_freq_table, NULL); - clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP | TEGRA_DIVIDER_INT, 24, - 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, + &pll_c3_params, NULL); + clks[TEGRA114_CLK_PLL_C3] = clk; /* PLLM */ - _clip_vco_min(&pll_m_params); clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLL_USE_LOCK, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA114_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -1378,41 +1104,20 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA114_CLK_PLL_M_OUT1] = clk; /* PLLM_UD */ clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", CLK_SET_RATE_PARENT, 1, 1); - /* PLLX */ - _clip_vco_min(&pll_x_params); - if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) { - _init_iddq(&pll_x_params, clk_base); - clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, - pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, - TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; - } - - /* PLLX_OUT0 */ - clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", - CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_x_out0", NULL); - clks[pll_x_out0] = clk; - /* PLLU */ val = readl(clk_base + pll_u_params.base_reg); val &= ~BIT(24); /* disable PLLU_OVERRIDE */ writel(val, clk_base + pll_u_params.base_reg); clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, - 0, &pll_u_params, TEGRA_PLLU | - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, &pll_u_lock); + clks[TEGRA114_CLK_PLL_U] = clk; tegra114_utmi_param_configure(clk_base); @@ -1420,731 +1125,97 @@ static void __init tegra114_pll_init(void __iomem *clk_base, clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 22, 0, &pll_u_lock); - clk_register_clkdev(clk, "pll_u_480M", NULL); - clks[pll_u_480M] = clk; + clks[TEGRA114_CLK_PLL_U_480M] = clk; /* PLLU_60M */ clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", CLK_SET_RATE_PARENT, 1, 8); - clk_register_clkdev(clk, "pll_u_60M", NULL); - clks[pll_u_60M] = clk; + clks[TEGRA114_CLK_PLL_U_60M] = clk; /* PLLU_48M */ clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", CLK_SET_RATE_PARENT, 1, 10); - clk_register_clkdev(clk, "pll_u_48M", NULL); - clks[pll_u_48M] = clk; + clks[TEGRA114_CLK_PLL_U_48M] = clk; /* PLLU_12M */ clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", CLK_SET_RATE_PARENT, 1, 40); - clk_register_clkdev(clk, "pll_u_12M", NULL); - clks[pll_u_12M] = clk; + clks[TEGRA114_CLK_PLL_U_12M] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, - 0, &pll_d_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + &pll_d_params, &pll_d_lock); + clks[TEGRA114_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA114_CLK_PLL_D_OUT0] = clk; /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, - 0, &pll_d2_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock); - clk_register_clkdev(clk, "pll_d2", NULL); - clks[pll_d2] = clk; + &pll_d2_params, &pll_d2_lock); + clks[TEGRA114_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d2_out0", NULL); - clks[pll_d2_out0] = clk; - - /* PLLA */ - clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, - 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; - - /* PLLA_OUT0 */ - clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", - clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", - clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | - CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA114_CLK_PLL_D2_OUT0] = clk; /* PLLRE */ - _clip_vco_min(&pll_re_vco_params); clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, - 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, - NULL, &pll_re_lock, pll_ref_freq); - clk_register_clkdev(clk, "pll_re_vco", NULL); - clks[pll_re_vco] = clk; + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); + clks[TEGRA114_CLK_PLL_RE_VCO] = clk; clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, clk_base + PLLRE_BASE, 16, 4, 0, pll_re_div_table, &pll_re_lock); - clk_register_clkdev(clk, "pll_re_out", NULL); - clks[pll_re_out] = clk; + clks[TEGRA114_CLK_PLL_RE_OUT] = clk; /* PLLE */ - clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco", - clk_base, 0, 100000000, &pll_e_params, - pll_e_freq_table, NULL); - clk_register_clkdev(clk, "pll_e_out0", NULL); - clks[pll_e_out0] = clk; -} - -static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", -}; - -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", -}; - -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", -}; - -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", -}; - -static void __init tegra114_audio_clk_init(void __iomem *clk_base) -{ - struct clk *clk; - - /* spdif_in_sync */ - clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, - 24000000); - clk_register_clkdev(clk, "spdif_in_sync", NULL); - clks[spdif_in_sync] = clk; - - /* i2s0_sync */ - clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s0_sync", NULL); - clks[i2s0_sync] = clk; - - /* i2s1_sync */ - clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s1_sync", NULL); - clks[i2s1_sync] = clk; - - /* i2s2_sync */ - clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s2_sync", NULL); - clks[i2s2_sync] = clk; - - /* i2s3_sync */ - clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s3_sync", NULL); - clks[i2s3_sync] = clk; - - /* i2s4_sync */ - clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s4_sync", NULL); - clks[i2s4_sync] = clk; - - /* vimclk_sync */ - clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); - clk_register_clkdev(clk, "vimclk_sync", NULL); - clks[vimclk_sync] = clk; - - /* audio0 */ - clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, - NULL); - clks[audio0_mux] = clk; - clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S0, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio0", NULL); - clks[audio0] = clk; - - /* audio1 */ - clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, - NULL); - clks[audio1_mux] = clk; - clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S1, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio1", NULL); - clks[audio1] = clk; - - /* audio2 */ - clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, - NULL); - clks[audio2_mux] = clk; - clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S2, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio2", NULL); - clks[audio2] = clk; - - /* audio3 */ - clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, - NULL); - clks[audio3_mux] = clk; - clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S3, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio3", NULL); - clks[audio3] = clk; - - /* audio4 */ - clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, - NULL); - clks[audio4_mux] = clk; - clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S4, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio4", NULL); - clks[audio4] = clk; - - /* spdif */ - clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, - NULL); - clks[spdif_mux] = clk; - clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, - clk_base + AUDIO_SYNC_CLK_SPDIF, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "spdif", NULL); - clks[spdif] = clk; - - /* audio0_2x */ - clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio0_2x", NULL); - clks[audio0_2x] = clk; - - /* audio1_2x */ - clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio1_2x", NULL); - clks[audio1_2x] = clk; - - /* audio2_2x */ - clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio2_2x", NULL); - clks[audio2_2x] = clk; - - /* audio3_2x */ - clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio3_2x", NULL); - clks[audio3_2x] = clk; - - /* audio4_2x */ - clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio4_2x", NULL); - clks[audio4_2x] = clk; - - /* spdif_2x */ - clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, - 0, &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 118, - &periph_v_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "spdif_2x", NULL); - clks[spdif_2x] = clk; -} - -static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) -{ - struct clk *clk; - - /* clk_out_1 */ - clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, - ARRAY_SIZE(clk_out1_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, - &clk_out_lock); - clks[clk_out_1_mux] = clk; - clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern1", "clk_out_1"); - clks[clk_out_1] = clk; - - /* clk_out_2 */ - clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, - ARRAY_SIZE(clk_out2_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, - &clk_out_lock); - clks[clk_out_2_mux] = clk; - clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern2", "clk_out_2"); - clks[clk_out_2] = clk; - - /* clk_out_3 */ - clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, - ARRAY_SIZE(clk_out3_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, - &clk_out_lock); - clks[clk_out_3_mux] = clk; - clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern3", "clk_out_3"); - clks[clk_out_3] = clk; - - /* blink */ - /* clear the blink timer register to directly output clk_32k */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; - + clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", + clk_base, 0, &pll_e_params, NULL); + clks[TEGRA114_CLK_PLL_E_OUT0] = clk; } -static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", - "pll_p", "pll_p_out2", "unused", - "clk_32k", "pll_m_out1" }; - -static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", - "pll_p", "pll_p_out4", "unused", - "unused", "pll_x" }; - -static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", - "pll_p", "pll_p_out4", "unused", - "unused", "pll_x", "pll_x_out0" }; - -static void __init tegra114_super_clk_init(void __iomem *clk_base) +static __init void tegra114_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) { struct clk *clk; + u32 val; - /* CCLKG */ - clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, - ARRAY_SIZE(cclk_g_parents), - CLK_SET_RATE_PARENT, - clk_base + CCLKG_BURST_POLICY, - 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk_g", NULL); - clks[cclk_g] = clk; - - /* CCLKLP */ - clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, - ARRAY_SIZE(cclk_lp_parents), - CLK_SET_RATE_PARENT, - clk_base + CCLKLP_BURST_POLICY, - 0, 4, 8, 9, NULL); - clk_register_clkdev(clk, "cclk_lp", NULL); - clks[cclk_lp] = clk; - - /* SCLK */ - clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), - CLK_SET_RATE_PARENT, - clk_base + SCLK_BURST_POLICY, - 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + SYSTEM_CLK_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT | - CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, - 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + SYSTEM_CLK_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | - CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, - 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; -} - -static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm), - TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx), - TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), - TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), - TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1), - TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2), - TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3), - TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4), - TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, msenc), - TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), - TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab), - TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd), - TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile), - TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp), - TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), - TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se), - TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), - TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_ref), - TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_soc), - TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm), - TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src), - TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src), - TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src), - TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src), - TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src), - TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio), - TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0), - TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1), - TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2), -}; - -static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, disp2), -}; + /* xusb_hs_src */ + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); + val |= BIT(25); /* always select PLLU_60M */ + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); -static __init void tegra114_periph_clk_init(void __iomem *clk_base) -{ - struct tegra_periph_init_data *data; - struct clk *clk; - int i; - u32 val; + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; - /* apbdma */ - clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, - 0, 34, &periph_h_regs, - periph_clk_enb_refcnt); - clks[apbdma] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_ON_APB | - TEGRA_PERIPH_NO_RESET, clk_base, - 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_ON_APB | - TEGRA_PERIPH_NO_RESET, clk_base, - 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); - clks[kbc] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; - - /* kfuse */ - clk = tegra_clk_register_periph_gate("kfuse", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 40, - &periph_h_regs, periph_clk_enb_refcnt); - clks[kfuse] = clk; - - /* fuse */ - clk = tegra_clk_register_periph_gate("fuse", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - &periph_h_regs, periph_clk_enb_refcnt); - clks[fuse] = clk; - - /* fuse_burn */ - clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 39, - &periph_h_regs, periph_clk_enb_refcnt); - clks[fuse_burn] = clk; - - /* apbif */ - clk = tegra_clk_register_periph_gate("apbif", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 107, - &periph_v_regs, periph_clk_enb_refcnt); - clks[apbif] = clk; - - /* hda2hdmi */ - clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 128, - &periph_w_regs, periph_clk_enb_refcnt); - clks[hda2hdmi] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, - 29, &periph_l_regs, - periph_clk_enb_refcnt); - clks[vcp] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, - 0, 62, &periph_h_regs, - periph_clk_enb_refcnt); - clks[bsea] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, - 0, 63, &periph_h_regs, - periph_clk_enb_refcnt); - clks[bsev] = clk; - - /* mipi-cal */ - clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, - 0, 56, &periph_h_regs, - periph_clk_enb_refcnt); - clks[mipi_cal] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, - 0, 22, &periph_l_regs, - periph_clk_enb_refcnt); - clks[usbd] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, - 0, 58, &periph_h_regs, - periph_clk_enb_refcnt); - clks[usb2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, - 0, 59, &periph_h_regs, - periph_clk_enb_refcnt); - clks[usb3] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); - clks[csi] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, - 23, &periph_l_regs, - periph_clk_enb_refcnt); - clks[isp] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, - &periph_u_regs, periph_clk_enb_refcnt); - clks[csus] = clk; - - /* dds */ - clk = tegra_clk_register_periph_gate("dds", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 150, - &periph_w_regs, periph_clk_enb_refcnt); - clks[dds] = clk; - - /* dp2 */ - clk = tegra_clk_register_periph_gate("dp2", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 152, - &periph_w_regs, periph_clk_enb_refcnt); - clks[dp2] = clk; - - /* dtv */ - clk = tegra_clk_register_periph_gate("dtv", "clk_m", - TEGRA_PERIPH_ON_APB, clk_base, 0, 79, - &periph_u_regs, periph_clk_enb_refcnt); - clks[dtv] = clk; - - /* dsia */ + /* dsia mux */ clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); - clks[dsia_mux] = clk; - clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, - 0, 48, &periph_h_regs, - periph_clk_enb_refcnt); - clks[dsia] = clk; + clks[TEGRA114_CLK_DSIA_MUX] = clk; - /* dsib */ + /* dsib mux */ clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, ARRAY_SIZE(mux_plld_out0_plld2_out0), CLK_SET_RATE_NO_REPARENT, clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); - clks[dsib_mux] = clk; - clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, - 0, 82, &periph_u_regs, - periph_clk_enb_refcnt); - clks[dsib] = clk; + clks[TEGRA114_CLK_DSIB_MUX] = clk; - /* xusb_hs_src */ - val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); - val |= BIT(25); /* always select PLLU_60M */ - writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); - - clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, - 1, 1); - clks[xusb_hs_src] = clk; - - /* xusb_host */ - clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, - clk_base, 0, 89, &periph_u_regs, - periph_clk_enb_refcnt); - clks[xusb_host] = clk; - - /* xusb_ss */ - clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, - clk_base, 0, 156, &periph_w_regs, - periph_clk_enb_refcnt); - clks[xusb_host] = clk; - - /* xusb_dev */ - clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, - clk_base, 0, 95, &periph_u_regs, - periph_clk_enb_refcnt); - clks[xusb_dev] = clk; - - /* emc */ + /* emc mux */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), CLK_SET_RATE_NO_REPARENT, clk_base + CLK_SOURCE_EMC, 29, 3, 0, NULL); - clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, - CLK_IGNORE_UNUSED, 57, &periph_h_regs, - periph_clk_enb_refcnt); - clks[emc] = clk; - - for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { - data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, - data->num_parents, &data->periph, - clk_base, data->offset, data->flags); - clks[data->clk_id] = clk; - } - for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { - data = &tegra_periph_nodiv_clk_list[i]; - clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, data->num_parents, - &data->periph, clk_base, data->offset); - clks[data->clk_id] = clk; - } + tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks, + &pll_p_params); } /* Tegra114 CPU clock and reset control functions */ @@ -2207,28 +1278,37 @@ static const struct of_device_id pmc_match[] __initconst = { * breaks */ static struct tegra_clk_init_table init_table[] __initdata = { - {uarta, pll_p, 408000000, 0}, - {uartb, pll_p, 408000000, 0}, - {uartc, pll_p, 408000000, 0}, - {uartd, pll_p, 408000000, 0}, - {pll_a, clk_max, 564480000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {extern1, pll_a_out0, 0, 1}, - {clk_out_1_mux, extern1, 0, 1}, - {clk_out_1, clk_max, 0, 1}, - {i2s0, pll_a_out0, 11289600, 0}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {i2s3, pll_a_out0, 11289600, 0}, - {i2s4, pll_a_out0, 11289600, 0}, - {dfll_soc, pll_p, 51000000, 1}, - {dfll_ref, pll_p, 51000000, 1}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ + {TEGRA114_CLK_UARTA, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0}, + {TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1}, + {TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1}, + {TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1}, + {TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1}, + {TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, + {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, + {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, + {TEGRA114_CLK_DISP1, TEGRA114_CLK_PLL_P, 0, 0}, + {TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0}, + {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, + {TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0}, + {TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0}, + + /* This MUST be the last entry. */ + {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, }; static void __init tegra114_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA114_CLK_CLK_MAX); } @@ -2359,7 +1439,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); static void __init tegra114_clock_init(struct device_node *np) { struct device_node *node; - int i; clk_base = of_iomap(np, 0); if (!clk_base) { @@ -2381,29 +1460,24 @@ static void __init tegra114_clock_init(struct device_node *np) return; } + clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX, + TEGRA114_CLK_PERIPH_BANKS); + if (!clks) + return; + if (tegra114_osc_clk_init(clk_base) < 0) return; tegra114_fixed_clk_init(clk_base); tegra114_pll_init(clk_base, pmc_base); - tegra114_periph_clk_init(clk_base); - tegra114_audio_clk_init(clk_base); - tegra114_pmc_clk_init(pmc_base); - tegra114_super_clk_init(clk_base); - - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err - ("Tegra114 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra114_periph_clk_init(clk_base, pmc_base); + tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); + tegra_pmc_clk_init(pmc_base, tegra114_clks); + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, + &pll_x_params); + + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra114_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c new file mode 100644 index 0000000..aff86b5 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra124.c @@ -0,0 +1,1424 @@ +/* + * 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/clk/tegra.h> +#include <dt-bindings/clock/tegra124-car.h> + +#include "clk.h" +#include "clk-id.h" + +#define CLK_SOURCE_CSITE 0x1d4 +#define CLK_SOURCE_EMC 0x19c +#define CLK_SOURCE_XUSB_SS_SRC 0x610 + +#define PLLC_BASE 0x80 +#define PLLC_OUT 0x84 +#define PLLC_MISC2 0x88 +#define PLLC_MISC 0x8c +#define PLLC2_BASE 0x4e8 +#define PLLC2_MISC 0x4ec +#define PLLC3_BASE 0x4fc +#define PLLC3_MISC 0x500 +#define PLLM_BASE 0x90 +#define PLLM_OUT 0x94 +#define PLLM_MISC 0x9c +#define PLLP_BASE 0xa0 +#define PLLP_MISC 0xac +#define PLLA_BASE 0xb0 +#define PLLA_MISC 0xbc +#define PLLD_BASE 0xd0 +#define PLLD_MISC 0xdc +#define PLLU_BASE 0xc0 +#define PLLU_MISC 0xcc +#define PLLX_BASE 0xe0 +#define PLLX_MISC 0xe4 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 +#define PLLE_BASE 0xe8 +#define PLLE_MISC 0xec +#define PLLD2_BASE 0x4b8 +#define PLLD2_MISC 0x4bc +#define PLLE_AUX 0x48c +#define PLLRE_BASE 0x4c4 +#define PLLRE_MISC 0x4c8 +#define PLLDP_BASE 0x590 +#define PLLDP_MISC 0x594 +#define PLLC4_BASE 0x5a4 +#define PLLC4_MISC 0x5a8 + +#define PLLC_IDDQ_BIT 26 +#define PLLRE_IDDQ_BIT 16 +#define PLLSS_IDDQ_BIT 19 + +#define PLL_BASE_LOCK BIT(27) +#define PLLE_MISC_LOCK BIT(11) +#define PLLRE_MISC_LOCK BIT(24) + +#define PLL_MISC_LOCK_ENABLE 18 +#define PLLC_MISC_LOCK_ENABLE 24 +#define PLLDU_MISC_LOCK_ENABLE 22 +#define PLLE_MISC_LOCK_ENABLE 9 +#define PLLRE_MISC_LOCK_ENABLE 30 +#define PLLSS_MISC_LOCK_ENABLE 30 + +#define PLLXC_SW_MAX_P 6 + +#define PMC_PLLM_WB0_OVERRIDE 0x1dc +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 + +#define UTMIP_PLL_CFG2 0x488 +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) + +#define UTMIP_PLL_CFG1 0x484 +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6) +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) + +#define UTMIPLL_HW_PWRDN_CFG0 0x52c +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) +#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4) +#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) + +/* Tegra CPU clock and reset control regs */ +#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 + +#ifdef CONFIG_PM_SLEEP +static struct cpu_clk_suspend_context { + u32 clk_csite_src; +} tegra124_cpu_clk_sctx; +#endif + +static void __iomem *clk_base; +static void __iomem *pmc_base; + +static unsigned long osc_freq; +static unsigned long pll_ref_freq; + +static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_d2_lock); +static DEFINE_SPINLOCK(pll_e_lock); +static DEFINE_SPINLOCK(pll_re_lock); +static DEFINE_SPINLOCK(pll_u_lock); + +/* possible OSC frequencies in Hz */ +static unsigned long tegra124_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, +}; + +static const char *mux_plld_out0_plld2_out0[] = { + "pll_d_out0", "pll_d2_out0", +}; +#define mux_plld_out0_plld2_out0_idx NULL + +static const char *mux_pllmcp_clkm[] = { + "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3", +}; +#define mux_pllmcp_clkm_idx NULL + +static struct div_nmp pllxc_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 4, +}; + +static struct pdiv_map pllxc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { + /* 1 GHz */ + {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ + {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ + {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ + {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ + {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_x_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 700000000, + .vco_max = 3000000000UL, + .base_reg = PLLX_BASE, + .misc_reg = PLLX_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLX_MISC3, + .iddq_bit_idx = 3, + .max_p = 6, + .dyn_ramp_reg = PLLX_MISC2, + .stepa_shift = 16, + .stepb_shift = 24, + .pdiv_tohw = pllxc_p, + .div_nmp = &pllxc_nmp, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { + { 12000000, 624000000, 104, 1, 2}, + { 12000000, 600000000, 100, 1, 2}, + { 13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 600000000, + .vco_max = 1400000000, + .base_reg = PLLC_BASE, + .misc_reg = PLLC_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLC_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLC_MISC, + .iddq_bit_idx = PLLC_IDDQ_BIT, + .max_p = PLLXC_SW_MAX_P, + .dyn_ramp_reg = PLLC_MISC2, + .stepa_shift = 17, + .stepb_shift = 9, + .pdiv_tohw = pllxc_p, + .div_nmp = &pllxc_nmp, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllcx_nmp = { + .divm_shift = 0, + .divm_width = 2, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 3, +}; + +static struct pdiv_map pllc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 6, .hw_val = 4 }, + { .pdiv = 8, .hw_val = 5 }, + { .pdiv = 12, .hw_val = 6 }, + { .pdiv = 16, .hw_val = 7 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { + {12000000, 600000000, 100, 1, 2}, + {13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + {16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ + {19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ + {26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_c2_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC2_BASE, + .misc_reg = PLLC2_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, + .div_nmp = &pllcx_nmp, + .max_p = 7, + .ext_misc_reg[0] = 0x4f0, + .ext_misc_reg[1] = 0x4f4, + .ext_misc_reg[2] = 0x4f8, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_params pll_c3_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC3_BASE, + .misc_reg = PLLC3_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, + .div_nmp = &pllcx_nmp, + .max_p = 7, + .ext_misc_reg[0] = 0x504, + .ext_misc_reg[1] = 0x508, + .ext_misc_reg[2] = 0x50c, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllss_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 4, +}; + +static struct pdiv_map pll12g_ssd_esd_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_c4_freq_table[] = { + { 12000000, 600000000, 100, 1, 1}, + { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c4_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC4_BASE, + .misc_reg = PLLC4_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLC4_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x5ac, + .ext_misc_reg[1] = 0x5b0, + .ext_misc_reg[2] = 0x5b4, + .freq_table = pll_c4_freq_table, +}; + +static struct pdiv_map pllm_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { + {12000000, 800000000, 66, 1, 1}, /* actual: 792.0 MHz */ + {13000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ + {16800000, 800000000, 47, 1, 1}, /* actual: 789.6 MHz */ + {19200000, 800000000, 41, 1, 1}, /* actual: 787.2 MHz */ + {26000000, 800000000, 61, 2, 1}, /* actual: 793.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct div_nmp pllm_nmp = { + .divm_shift = 0, + .divm_width = 8, + .override_divm_shift = 0, + .divn_shift = 8, + .divn_width = 8, + .override_divn_shift = 8, + .divp_shift = 20, + .divp_width = 1, + .override_divp_shift = 27, +}; + +static struct tegra_clk_pll_params pll_m_params = { + .input_min = 12000000, + .input_max = 500000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 400000000, + .vco_max = 1066000000, + .base_reg = PLLM_BASE, + .misc_reg = PLLM_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .max_p = 2, + .pdiv_tohw = pllm_p, + .div_nmp = &pllm_nmp, + .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, + .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { + /* PLLE special case: use cpcon field to store cml divider value */ + {336000000, 100000000, 100, 21, 16, 11}, + {312000000, 100000000, 200, 26, 24, 13}, + {13000000, 100000000, 200, 1, 26, 13}, + {12000000, 100000000, 200, 1, 24, 13}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct div_nmp plle_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 24, + .divp_width = 4, +}; + +static struct tegra_clk_pll_params pll_e_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 75000000, + .vco_min = 1600000000, + .vco_max = 2400000000U, + .base_reg = PLLE_BASE, + .misc_reg = PLLE_MISC, + .aux_reg = PLLE_AUX, + .lock_mask = PLLE_MISC_LOCK, + .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &plle_nmp, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, +}; + +static const struct clk_div_table pll_re_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 3 }, + { .val = 3, .div = 4 }, + { .val = 4, .div = 5 }, + { .val = 5, .div = 6 }, + { .val = 0, .div = 0 }, +}; + +static struct div_nmp pllre_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 16, + .divp_width = 4, +}; + +static struct tegra_clk_pll_params pll_re_vco_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 300000000, + .vco_max = 600000000, + .base_reg = PLLRE_BASE, + .misc_reg = PLLRE_MISC, + .lock_mask = PLLRE_MISC_LOCK, + .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLRE_MISC, + .iddq_bit_idx = PLLRE_IDDQ_BIT, + .div_nmp = &pllre_nmp, + .flags = TEGRA_PLL_USE_LOCK, +}; + +static struct div_nmp pllp_nmp = { + .divm_shift = 0, + .divm_width = 5, + .divn_shift = 8, + .divn_width = 10, + .divp_shift = 20, + .divp_width = 3, +}; + +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { + {12000000, 216000000, 432, 12, 1, 8}, + {13000000, 216000000, 432, 13, 1, 8}, + {16800000, 216000000, 360, 14, 1, 8}, + {19200000, 216000000, 360, 16, 1, 8}, + {26000000, 216000000, 432, 26, 1, 8}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_p_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLP_BASE, + .misc_reg = PLLP_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &pllp_nmp, + .freq_table = pll_p_freq_table, + .fixed_rate = 408000000, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { + {9600000, 282240000, 147, 5, 0, 4}, + {9600000, 368640000, 192, 5, 0, 4}, + {9600000, 240000000, 200, 8, 0, 8}, + + {28800000, 282240000, 245, 25, 0, 8}, + {28800000, 368640000, 320, 25, 0, 8}, + {28800000, 240000000, 200, 24, 0, 8}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_a_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLA_BASE, + .misc_reg = PLLA_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &pllp_nmp, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { + {12000000, 216000000, 864, 12, 4, 12}, + {13000000, 216000000, 864, 13, 4, 12}, + {16800000, 216000000, 720, 14, 4, 12}, + {19200000, 216000000, 720, 16, 4, 12}, + {26000000, 216000000, 864, 26, 4, 12}, + + {12000000, 594000000, 594, 12, 1, 12}, + {13000000, 594000000, 594, 13, 1, 12}, + {16800000, 594000000, 495, 14, 1, 12}, + {19200000, 594000000, 495, 16, 1, 12}, + {26000000, 594000000, 594, 26, 1, 12}, + + {12000000, 1000000000, 1000, 12, 1, 12}, + {13000000, 1000000000, 1000, 13, 1, 12}, + {19200000, 1000000000, 625, 12, 1, 12}, + {26000000, 1000000000, 1000, 26, 1, 12}, + + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_d_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 500000000, + .vco_max = 1000000000, + .base_reg = PLLD_BASE, + .misc_reg = PLLD_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .div_nmp = &pllp_nmp, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, +}; + +static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { + { 12000000, 148500000, 99, 1, 8}, + { 12000000, 594000000, 99, 1, 1}, + { 13000000, 594000000, 91, 1, 1}, /* actual: 591.5 MHz */ + { 16800000, 594000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 594000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 594000000, 91, 2, 1}, /* actual: 591.5 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params tegra124_pll_d2_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLD2_BASE, + .misc_reg = PLLD2_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLD2_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x570, + .ext_misc_reg[1] = 0x574, + .ext_misc_reg[2] = 0x578, + .max_p = 15, + .freq_table = tegra124_pll_d2_freq_table, +}; + +static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { + { 12000000, 600000000, 100, 1, 1}, + { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_dp_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLDP_BASE, + .misc_reg = PLLDP_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLDP_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .pdiv_tohw = pll12g_ssd_esd_p, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = 0x598, + .ext_misc_reg[1] = 0x59c, + .ext_misc_reg[2] = 0x5a0, + .max_p = 5, + .freq_table = pll_dp_freq_table, +}; + +static struct pdiv_map pllu_p[] = { + { .pdiv = 1, .hw_val = 1 }, + { .pdiv = 2, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct div_nmp pllu_nmp = { + .divm_shift = 0, + .divm_width = 5, + .divn_shift = 8, + .divn_width = 10, + .divp_shift = 20, + .divp_width = 1, +}; + +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { + {12000000, 480000000, 960, 12, 2, 12}, + {13000000, 480000000, 960, 13, 2, 12}, + {16800000, 480000000, 400, 7, 2, 5}, + {19200000, 480000000, 200, 4, 2, 3}, + {26000000, 480000000, 960, 26, 2, 12}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_u_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .base_reg = PLLU_BASE, + .misc_reg = PLLU_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .pdiv_tohw = pllu_p, + .div_nmp = &pllu_nmp, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, +}; + +struct utmi_clk_param { + /* Oscillator Frequency in KHz */ + u32 osc_frequency; + /* UTMIP PLL Enable Delay Count */ + u8 enable_delay_count; + /* UTMIP PLL Stable count */ + u8 stable_count; + /* UTMIP PLL Active delay count */ + u8 active_delay_count; + /* UTMIP PLL Xtal frequency count */ + u8 xtal_freq_count; +}; + +static const struct utmi_clk_param utmi_parameters[] = { + {.osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7F}, + {.osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4B, .active_delay_count = 0x06, + .xtal_freq_count = 0xBB}, + {.osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2F, .active_delay_count = 0x04, + .xtal_freq_count = 0x76}, + {.osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xFE}, + {.osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0A, + .xtal_freq_count = 0xA4}, +}; + +static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { + [tegra_clk_ispb] = { .dt_id = TEGRA124_CLK_ISPB, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA124_CLK_GR_2D, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, + [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA124_CLK_GR_3D, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA124_CLK_KBC, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA124_CLK_KFUSE, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA124_CLK_SBC1, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA124_CLK_NOR, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA124_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA124_CLK_SBC3, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA124_CLK_I2C5, .present = true }, + [tegra_clk_dsia] = { .dt_id = TEGRA124_CLK_DSIA, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA124_CLK_MIPI, .present = true }, + [tegra_clk_hdmi] = { .dt_id = TEGRA124_CLK_HDMI, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA124_CLK_CSI, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA124_CLK_I2C2, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA124_CLK_UARTC, .present = true }, + [tegra_clk_mipi_cal] = { .dt_id = TEGRA124_CLK_MIPI_CAL, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA124_CLK_EMC, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA124_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA124_CLK_USB3, .present = true }, + [tegra_clk_vde_8] = { .dt_id = TEGRA124_CLK_VDE, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA124_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA124_CLK_BSEV, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, + [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, + [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA124_CLK_CSITE, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA124_CLK_LA, .present = true }, + [tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true }, + [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true }, + [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true }, + [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true }, + [tegra_clk_xusb_host] = { .dt_id = TEGRA124_CLK_XUSB_HOST, .present = true }, + [tegra_clk_msenc] = { .dt_id = TEGRA124_CLK_MSENC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA124_CLK_CSUS, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA124_CLK_MSELECT, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA124_CLK_TSENSOR, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA124_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA124_CLK_I2S4, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA124_CLK_I2C4, .present = true }, + [tegra_clk_sbc5] = { .dt_id = TEGRA124_CLK_SBC5, .present = true }, + [tegra_clk_sbc6] = { .dt_id = TEGRA124_CLK_SBC6, .present = true }, + [tegra_clk_d_audio] = { .dt_id = TEGRA124_CLK_D_AUDIO, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA124_CLK_APBIF, .present = true }, + [tegra_clk_dam0] = { .dt_id = TEGRA124_CLK_DAM0, .present = true }, + [tegra_clk_dam1] = { .dt_id = TEGRA124_CLK_DAM1, .present = true }, + [tegra_clk_dam2] = { .dt_id = TEGRA124_CLK_DAM2, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA124_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA124_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA124_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA124_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA124_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA124_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA124_CLK_SPDIF_2X, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA124_CLK_ACTMON, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA124_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA124_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA124_CLK_EXTERN3, .present = true }, + [tegra_clk_sata_oob] = { .dt_id = TEGRA124_CLK_SATA_OOB, .present = true }, + [tegra_clk_sata] = { .dt_id = TEGRA124_CLK_SATA, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA124_CLK_HDA, .present = true }, + [tegra_clk_se] = { .dt_id = TEGRA124_CLK_SE, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA124_CLK_HDA2HDMI, .present = true }, + [tegra_clk_sata_cold] = { .dt_id = TEGRA124_CLK_SATA_COLD, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA124_CLK_CILAB, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA124_CLK_CILCD, .present = true }, + [tegra_clk_cile] = { .dt_id = TEGRA124_CLK_CILE, .present = true }, + [tegra_clk_dsialp] = { .dt_id = TEGRA124_CLK_DSIALP, .present = true }, + [tegra_clk_dsiblp] = { .dt_id = TEGRA124_CLK_DSIBLP, .present = true }, + [tegra_clk_entropy] = { .dt_id = TEGRA124_CLK_ENTROPY, .present = true }, + [tegra_clk_dds] = { .dt_id = TEGRA124_CLK_DDS, .present = true }, + [tegra_clk_dp2] = { .dt_id = TEGRA124_CLK_DP2, .present = true }, + [tegra_clk_amx] = { .dt_id = TEGRA124_CLK_AMX, .present = true }, + [tegra_clk_adx] = { .dt_id = TEGRA124_CLK_ADX, .present = true }, + [tegra_clk_xusb_ss] = { .dt_id = TEGRA124_CLK_XUSB_SS, .present = true }, + [tegra_clk_i2c6] = { .dt_id = TEGRA124_CLK_I2C6, .present = true }, + [tegra_clk_vim2_clk] = { .dt_id = TEGRA124_CLK_VIM2_CLK, .present = true }, + [tegra_clk_hdmi_audio] = { .dt_id = TEGRA124_CLK_HDMI_AUDIO, .present = true }, + [tegra_clk_clk72Mhz] = { .dt_id = TEGRA124_CLK_CLK72MHZ, .present = true }, + [tegra_clk_vic03] = { .dt_id = TEGRA124_CLK_VIC03, .present = true }, + [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, + [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, + [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, + [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, + [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA124_CLK_VFIR, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA124_CLK_SPDIF_IN, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA124_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_vi_9] = { .dt_id = TEGRA124_CLK_VI, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA124_CLK_VI_SENSOR, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA124_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA124_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA124_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA124_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true }, + [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true }, + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true }, + [tegra_clk_pll_c2] = { .dt_id = TEGRA124_CLK_PLL_C2, .present = true }, + [tegra_clk_pll_c3] = { .dt_id = TEGRA124_CLK_PLL_C3, .present = true }, + [tegra_clk_pll_m] = { .dt_id = TEGRA124_CLK_PLL_M, .present = true }, + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA124_CLK_PLL_M_OUT1, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA124_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA124_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA124_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA124_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA124_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA124_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA124_CLK_PLL_A_OUT0, .present = true }, + [tegra_clk_pll_d] = { .dt_id = TEGRA124_CLK_PLL_D, .present = true }, + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA124_CLK_PLL_D_OUT0, .present = true }, + [tegra_clk_pll_d2] = { .dt_id = TEGRA124_CLK_PLL_D2, .present = true }, + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA124_CLK_PLL_D2_OUT0, .present = true }, + [tegra_clk_pll_u] = { .dt_id = TEGRA124_CLK_PLL_U, .present = true }, + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA124_CLK_PLL_U_480M, .present = true }, + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA124_CLK_PLL_U_60M, .present = true }, + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA124_CLK_PLL_U_48M, .present = true }, + [tegra_clk_pll_u_12m] = { .dt_id = TEGRA124_CLK_PLL_U_12M, .present = true }, + [tegra_clk_pll_x] = { .dt_id = TEGRA124_CLK_PLL_X, .present = true }, + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA124_CLK_PLL_X_OUT0, .present = true }, + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA124_CLK_PLL_RE_VCO, .present = true }, + [tegra_clk_pll_re_out] = { .dt_id = TEGRA124_CLK_PLL_RE_OUT, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA124_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA124_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA124_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA124_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA124_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA124_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA124_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA124_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA124_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true }, + [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true }, + [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, + [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA124_CLK_XUSB_SS_SRC, .present = true }, + [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA124_CLK_XUSB_DEV_SRC, .present = true }, + [tegra_clk_xusb_dev] = { .dt_id = TEGRA124_CLK_XUSB_DEV, .present = true }, + [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA124_CLK_XUSB_HS_SRC, .present = true }, + [tegra_clk_sclk] = { .dt_id = TEGRA124_CLK_SCLK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA124_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA124_CLK_PCLK, .present = true }, + [tegra_clk_cclk_g] = { .dt_id = TEGRA124_CLK_CCLK_G, .present = true }, + [tegra_clk_cclk_lp] = { .dt_id = TEGRA124_CLK_CCLK_LP, .present = true }, + [tegra_clk_dfll_ref] = { .dt_id = TEGRA124_CLK_DFLL_REF, .present = true }, + [tegra_clk_dfll_soc] = { .dt_id = TEGRA124_CLK_DFLL_SOC, .present = true }, + [tegra_clk_vi_sensor2] = { .dt_id = TEGRA124_CLK_VI_SENSOR2, .present = true }, + [tegra_clk_pll_p_out5] = { .dt_id = TEGRA124_CLK_PLL_P_OUT5, .present = true }, + [tegra_clk_pll_c4] = { .dt_id = TEGRA124_CLK_PLL_C4, .present = true }, + [tegra_clk_pll_dp] = { .dt_id = TEGRA124_CLK_PLL_DP, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA124_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA124_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA124_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true }, + [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true }, + [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true }, +}; + +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF }, + { .con_id = "clk_32k", .dt_id = TEGRA124_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA124_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA124_CLK_CLK_M_DIV4 }, + { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 }, + { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 }, + { .con_id = "pll_c3", .dt_id = TEGRA124_CLK_PLL_C3 }, + { .con_id = "pll_p", .dt_id = TEGRA124_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA124_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA124_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA124_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA124_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA124_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA124_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA124_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA124_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA124_CLK_PLL_U }, + { .con_id = "pll_u_480M", .dt_id = TEGRA124_CLK_PLL_U_480M }, + { .con_id = "pll_u_60M", .dt_id = TEGRA124_CLK_PLL_U_60M }, + { .con_id = "pll_u_48M", .dt_id = TEGRA124_CLK_PLL_U_48M }, + { .con_id = "pll_u_12M", .dt_id = TEGRA124_CLK_PLL_U_12M }, + { .con_id = "pll_d", .dt_id = TEGRA124_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA124_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA124_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA124_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA124_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA124_CLK_PLL_A_OUT0 }, + { .con_id = "pll_re_vco", .dt_id = TEGRA124_CLK_PLL_RE_VCO }, + { .con_id = "pll_re_out", .dt_id = TEGRA124_CLK_PLL_RE_OUT }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA124_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA124_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA124_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA124_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA124_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA124_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA124_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA124_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA124_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA124_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA124_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA124_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA124_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA124_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA124_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA124_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA124_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA124_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA124_CLK_FUSE }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA124_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA124_CLK_TIMER }, +}; + +static struct clk **clks; + +static void tegra124_utmi_param_configure(void __iomem *clk_base) +{ + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { + if (osc_freq == utmi_parameters[i].osc_frequency) + break; + } + + if (i >= ARRAY_SIZE(utmi_parameters)) { + pr_err("%s: Unexpected oscillator freq %lu\n", __func__, + osc_freq); + return; + } + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL stable and active counts */ + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); + reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); + + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i]. + active_delay_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; + + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL delay and oscillator frequency counts */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i]. + enable_delay_count); + + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i]. + xtal_freq_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + /* Setup HW control of UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL; + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + udelay(1); + + /* Setup SW override of UTMIPLL assuming USB2.0 + ports are assigned to USB2 */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + udelay(1); + + /* Enable HW control UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); +} + +static __init void tegra124_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) +{ + struct clk *clk; + u32 val; + + /* xusb_hs_src */ + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); + val |= BIT(25); /* always select PLLU_60M */ + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); + + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[TEGRA124_CLK_XUSB_HS_SRC] = clk; + + /* dsia mux */ + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); + clks[TEGRA124_CLK_DSIA_MUX] = clk; + + /* dsib mux */ + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); + clks[TEGRA124_CLK_DSIB_MUX] = clk; + + /* emc mux */ + clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, + ARRAY_SIZE(mux_pllmcp_clkm), 0, + clk_base + CLK_SOURCE_EMC, + 29, 3, 0, NULL); + + /* cml0 */ + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, + 0, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml0", NULL); + clks[TEGRA124_CLK_CML0] = clk; + + /* cml1 */ + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, + 1, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml1", NULL); + clks[TEGRA124_CLK_CML1] = clk; + + tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); +} + +static void __init tegra124_pll_init(void __iomem *clk_base, + void __iomem *pmc) +{ + u32 val; + struct clk *clk; + + /* PLLC */ + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, &pll_c_params, NULL); + clk_register_clkdev(clk, "pll_c", NULL); + clks[TEGRA124_CLK_PLL_C] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c_out1", NULL); + clks[TEGRA124_CLK_PLL_C_OUT1] = clk; + + /* PLLC2 */ + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, + &pll_c2_params, NULL); + clk_register_clkdev(clk, "pll_c2", NULL); + clks[TEGRA124_CLK_PLL_C2] = clk; + + /* PLLC3 */ + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, + &pll_c3_params, NULL); + clk_register_clkdev(clk, "pll_c3", NULL); + clks[TEGRA124_CLK_PLL_C3] = clk; + + /* PLLM */ + clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clk_register_clkdev(clk, "pll_m", NULL); + clks[TEGRA124_CLK_PLL_M] = clk; + + /* PLLM_OUT1 */ + clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", + clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", + clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_m_out1", NULL); + clks[TEGRA124_CLK_PLL_M_OUT1] = clk; + + /* PLLM_UD */ + clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", + CLK_SET_RATE_PARENT, 1, 1); + + /* PLLU */ + val = readl(clk_base + pll_u_params.base_reg); + val &= ~BIT(24); /* disable PLLU_OVERRIDE */ + writel(val, clk_base + pll_u_params.base_reg); + + clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, + &pll_u_params, &pll_u_lock); + clk_register_clkdev(clk, "pll_u", NULL); + clks[TEGRA124_CLK_PLL_U] = clk; + + tegra124_utmi_param_configure(clk_base); + + /* PLLU_480M */ + clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 22, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_480M", NULL); + clks[TEGRA124_CLK_PLL_U_480M] = clk; + + /* PLLU_60M */ + clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", + CLK_SET_RATE_PARENT, 1, 8); + clk_register_clkdev(clk, "pll_u_60M", NULL); + clks[TEGRA124_CLK_PLL_U_60M] = clk; + + /* PLLU_48M */ + clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", + CLK_SET_RATE_PARENT, 1, 10); + clk_register_clkdev(clk, "pll_u_48M", NULL); + clks[TEGRA124_CLK_PLL_U_48M] = clk; + + /* PLLU_12M */ + clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", + CLK_SET_RATE_PARENT, 1, 40); + clk_register_clkdev(clk, "pll_u_12M", NULL); + clks[TEGRA124_CLK_PLL_U_12M] = clk; + + /* PLLD */ + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, + &pll_d_params, &pll_d_lock); + clk_register_clkdev(clk, "pll_d", NULL); + clks[TEGRA124_CLK_PLL_D] = clk; + + /* PLLD_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d_out0", NULL); + clks[TEGRA124_CLK_PLL_D_OUT0] = clk; + + /* PLLRE */ + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); + clk_register_clkdev(clk, "pll_re_vco", NULL); + clks[TEGRA124_CLK_PLL_RE_VCO] = clk; + + clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, + clk_base + PLLRE_BASE, 16, 4, 0, + pll_re_div_table, &pll_re_lock); + clk_register_clkdev(clk, "pll_re_out", NULL); + clks[TEGRA124_CLK_PLL_RE_OUT] = clk; + + /* PLLE */ + clk = tegra_clk_register_plle_tegra114("pll_e", "pll_ref", + clk_base, 0, &pll_e_params, NULL); + clk_register_clkdev(clk, "pll_e", NULL); + clks[TEGRA124_CLK_PLL_E] = clk; + + /* PLLC4 */ + clk = tegra_clk_register_pllss("pll_c4", "pll_ref", clk_base, 0, + &pll_c4_params, NULL); + clk_register_clkdev(clk, "pll_c4", NULL); + clks[TEGRA124_CLK_PLL_C4] = clk; + + /* PLLDP */ + clk = tegra_clk_register_pllss("pll_dp", "pll_ref", clk_base, 0, + &pll_dp_params, NULL); + clk_register_clkdev(clk, "pll_dp", NULL); + clks[TEGRA124_CLK_PLL_DP] = clk; + + /* PLLD2 */ + clk = tegra_clk_register_pllss("pll_d2", "pll_ref", clk_base, 0, + &tegra124_pll_d2_params, NULL); + clk_register_clkdev(clk, "pll_d2", NULL); + clks[TEGRA124_CLK_PLL_D2] = clk; + + /* PLLD2_OUT0 ?? */ + clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d2_out0", NULL); + clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; + +} + +/* Tegra124 CPU clock and reset control functions */ +static void tegra124_wait_cpu_in_reset(u32 cpu) +{ + unsigned int reg; + + do { + reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); + cpu_relax(); + } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ +} + +static void tegra124_disable_cpu_clock(u32 cpu) +{ + /* flow controller would take care in the power sequence. */ +} + +#ifdef CONFIG_PM_SLEEP +static void tegra124_cpu_clock_suspend(void) +{ + /* switch coresite to clk_m, save off original source */ + tegra124_cpu_clk_sctx.clk_csite_src = + readl(clk_base + CLK_SOURCE_CSITE); + writel(3 << 30, clk_base + CLK_SOURCE_CSITE); +} + +static void tegra124_cpu_clock_resume(void) +{ + writel(tegra124_cpu_clk_sctx.clk_csite_src, + clk_base + CLK_SOURCE_CSITE); +} +#endif + +static struct tegra_cpu_car_ops tegra124_cpu_car_ops = { + .wait_for_reset = tegra124_wait_cpu_in_reset, + .disable_clock = tegra124_disable_cpu_clock, +#ifdef CONFIG_PM_SLEEP + .suspend = tegra124_cpu_clock_suspend, + .resume = tegra124_cpu_clock_resume, +#endif +}; + +static const struct of_device_id pmc_match[] __initconst = { + { .compatible = "nvidia,tegra124-pmc" }, + {}, +}; + +static struct tegra_clk_init_table init_table[] __initdata = { + {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0}, + {TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1}, + {TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1}, + {TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1}, + {TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1}, + {TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0}, + {TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1}, + {TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1}, + {TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1}, + {TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1}, + {TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0}, + {TEGRA124_CLK_PLL_C_OUT1, TEGRA124_CLK_CLK_MAX, 100000000, 0}, + {TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1}, + {TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0}, + {TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0}, + /* This MUST be the last entry. */ + {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, +}; + +static void __init tegra124_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX); +} + +static void __init tegra124_clock_init(struct device_node *np) +{ + struct device_node *node; + + clk_base = of_iomap(np, 0); + if (!clk_base) { + pr_err("ioremap tegra124 CAR failed\n"); + return; + } + + node = of_find_matching_node(NULL, pmc_match); + if (!node) { + pr_err("Failed to find pmc node\n"); + WARN_ON(1); + return; + } + + pmc_base = of_iomap(node, 0); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); + return; + } + + clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6); + if (!clks) + return; + + if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq, + ARRAY_SIZE(tegra124_input_freq), &osc_freq, &pll_ref_freq) < 0) + return; + + tegra_fixed_clk_init(tegra124_clks); + tegra124_pll_init(clk_base, pmc_base); + tegra124_periph_clk_init(clk_base, pmc_base); + tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); + tegra_pmc_clk_init(pmc_base, tegra124_clks); + + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, + &pll_x_params); + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); + + tegra_clk_apply_init_table = tegra124_clock_apply_init_table; + + tegra_cpu_car_ops = &tegra124_cpu_car_ops; +} +CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 056f649..dbace15 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -22,30 +22,10 @@ #include <linux/of_address.h> #include <linux/clk/tegra.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra20-car.h> #include "clk.h" - -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00c -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_NUM 3 - -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_NUM 3 +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (3<<30) @@ -67,6 +47,8 @@ #define OSC_FREQ_DET_BUSY (1<<31) #define OSC_FREQ_DET_CNT_MASK 0xFFFF +#define TEGRA20_CLK_PERIPH_BANKS 3 + #define PLLS_BASE 0xf0 #define PLLS_MISC 0xf4 #define PLLC_BASE 0x80 @@ -114,34 +96,15 @@ #define CLK_SOURCE_I2S1 0x100 #define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c #define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_SPI 0x114 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 #define CLK_SOURCE_XIO 0x120 #define CLK_SOURCE_TWC 0x12c #define CLK_SOURCE_IDE 0x144 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_CVE 0x140 -#define CLK_SOURCE_TVO 0x188 -#define CLK_SOURCE_TVDAC 0x194 #define CLK_SOURCE_HDMI 0x18c #define CLK_SOURCE_DISP1 0x138 #define CLK_SOURCE_DISP2 0x13c #define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 #define CLK_SOURCE_I2C1 0x124 #define CLK_SOURCE_I2C2 0x198 #define CLK_SOURCE_I2C3 0x1b8 @@ -151,24 +114,10 @@ #define CLK_SOURCE_UARTC 0x1a0 #define CLK_SOURCE_UARTD 0x1c0 #define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_3D 0x158 -#define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_MPE 0x170 -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_VDE 0x1c8 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_VI_SENSOR 0x1a8 #define CLK_SOURCE_EMC 0x19c #define AUDIO_SYNC_CLK 0x38 -#define PMC_CTRL 0x0 -#define PMC_CTRL_BLINK_ENB 7 -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_BLINK_TIMER 0x40 - /* Tegra CPU clock and reset control regs */ #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 @@ -188,64 +137,32 @@ static struct cpu_clk_suspend_context { } tegra20_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; -static DEFINE_SPINLOCK(pll_div_lock); -static DEFINE_SPINLOCK(sysrate_lock); - -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _clk_num, periph_clk_enb_refcnt, \ + _clk_num, \ _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id) - -#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ +#define TEGRA_INIT_DATA_DIV16(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ + _clk_num, _gate_flags, \ _clk_id) -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, _clk_num, _regs, \ +#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ + _clk_num, _gate_flags, \ _clk_id) -/* IDs assigned here must be in sync with DT bindings definition - * for Tegra20 clocks . - */ -enum tegra20_clk { - cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, - ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp, - gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma, - kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3, - dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, - usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, - pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb, - iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev2, cdev1, - uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve, - osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0, - pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1, - pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_s, pll_u, - pll_x, cop, audio, pll_ref, twd, clk_max, -}; - -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +static struct clk **clks; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { { 12000000, 600000000, 600, 12, 0, 8 }, @@ -383,6 +300,8 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_m_params = { @@ -397,6 +316,8 @@ static struct tegra_clk_pll_params pll_m_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_p_params = { @@ -411,6 +332,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON, + .fixed_rate = 216000000, }; static struct tegra_clk_pll_params pll_a_params = { @@ -425,6 +349,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_d_params = { @@ -439,6 +365,8 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct pdiv_map pllu_p[] = { @@ -460,6 +388,8 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .pdiv_tohw = pllu_p, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_x_params = { @@ -474,6 +404,8 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_HAS_CPCON, }; static struct tegra_clk_pll_params pll_e_params = { @@ -488,34 +420,160 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 0, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; -/* Peripheral clock registers */ -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, -}; - -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 }, + { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA20_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA20_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA20_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA20_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA20_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA20_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA20_CLK_PLL_X }, + { .con_id = "pll_u", .dt_id = TEGRA20_CLK_PLL_U }, + { .con_id = "pll_d", .dt_id = TEGRA20_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA20_CLK_PLL_D_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA20_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA20_CLK_PLL_A_OUT0 }, + { .con_id = "pll_e", .dt_id = TEGRA20_CLK_PLL_E }, + { .con_id = "cclk", .dt_id = TEGRA20_CLK_CCLK }, + { .con_id = "sclk", .dt_id = TEGRA20_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA20_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA20_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA20_CLK_FUSE }, + { .con_id = "twd", .dt_id = TEGRA20_CLK_TWD }, + { .con_id = "audio", .dt_id = TEGRA20_CLK_AUDIO }, + { .con_id = "audio_2x", .dt_id = TEGRA20_CLK_AUDIO_2X }, + { .dev_id = "tegra20-ac97", .dt_id = TEGRA20_CLK_AC97 }, + { .dev_id = "tegra-apbdma", .dt_id = TEGRA20_CLK_APBDMA }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA20_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA20_CLK_TIMER }, + { .dev_id = "tegra-kbc", .dt_id = TEGRA20_CLK_KBC }, + { .con_id = "csus", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSUS }, + { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_VCP }, + { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_BSEA }, + { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA20_CLK_BSEV }, + { .con_id = "emc", .dt_id = TEGRA20_CLK_EMC }, + { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA20_CLK_USBD }, + { .dev_id = "tegra-ehci.1", .dt_id = TEGRA20_CLK_USB2 }, + { .dev_id = "tegra-ehci.2", .dt_id = TEGRA20_CLK_USB3 }, + { .dev_id = "dsi", .dt_id = TEGRA20_CLK_DSI }, + { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSI }, + { .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 = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, + { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, + { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, + { .con_id = "blink", .dt_id = TEGRA20_CLK_BLINK }, + { .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF }, + { .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 }, + { .dev_id = "tegra20-i2s.1", .dt_id = TEGRA20_CLK_I2S2 }, + { .con_id = "spdif_out", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_OUT }, + { .con_id = "spdif_in", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_IN }, + { .dev_id = "spi_tegra.0", .dt_id = TEGRA20_CLK_SBC1 }, + { .dev_id = "spi_tegra.1", .dt_id = TEGRA20_CLK_SBC2 }, + { .dev_id = "spi_tegra.2", .dt_id = TEGRA20_CLK_SBC3 }, + { .dev_id = "spi_tegra.3", .dt_id = TEGRA20_CLK_SBC4 }, + { .dev_id = "spi", .dt_id = TEGRA20_CLK_SPI }, + { .dev_id = "xio", .dt_id = TEGRA20_CLK_XIO }, + { .dev_id = "twc", .dt_id = TEGRA20_CLK_TWC }, + { .dev_id = "ide", .dt_id = TEGRA20_CLK_IDE }, + { .dev_id = "tegra_nand", .dt_id = TEGRA20_CLK_NDFLASH }, + { .dev_id = "vfir", .dt_id = TEGRA20_CLK_VFIR }, + { .dev_id = "csite", .dt_id = TEGRA20_CLK_CSITE }, + { .dev_id = "la", .dt_id = TEGRA20_CLK_LA }, + { .dev_id = "tegra_w1", .dt_id = TEGRA20_CLK_OWR }, + { .dev_id = "mipi", .dt_id = TEGRA20_CLK_MIPI }, + { .dev_id = "vde", .dt_id = TEGRA20_CLK_VDE }, + { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI }, + { .dev_id = "epp", .dt_id = TEGRA20_CLK_EPP }, + { .dev_id = "mpe", .dt_id = TEGRA20_CLK_MPE }, + { .dev_id = "host1x", .dt_id = TEGRA20_CLK_HOST1X }, + { .dev_id = "3d", .dt_id = TEGRA20_CLK_GR3D }, + { .dev_id = "2d", .dt_id = TEGRA20_CLK_GR2D }, + { .dev_id = "tegra-nor", .dt_id = TEGRA20_CLK_NOR }, + { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA20_CLK_SDMMC1 }, + { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA20_CLK_SDMMC2 }, + { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA20_CLK_SDMMC3 }, + { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA20_CLK_SDMMC4 }, + { .dev_id = "cve", .dt_id = TEGRA20_CLK_CVE }, + { .dev_id = "tvo", .dt_id = TEGRA20_CLK_TVO }, + { .dev_id = "tvdac", .dt_id = TEGRA20_CLK_TVDAC }, + { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI_SENSOR }, + { .dev_id = "hdmi", .dt_id = TEGRA20_CLK_HDMI }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA20_CLK_I2C1 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA20_CLK_I2C2 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA20_CLK_I2C3 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA20_CLK_DVC }, + { .dev_id = "tegra-pwm", .dt_id = TEGRA20_CLK_PWM }, + { .dev_id = "tegra_uart.0", .dt_id = TEGRA20_CLK_UARTA }, + { .dev_id = "tegra_uart.1", .dt_id = TEGRA20_CLK_UARTB }, + { .dev_id = "tegra_uart.2", .dt_id = TEGRA20_CLK_UARTC }, + { .dev_id = "tegra_uart.3", .dt_id = TEGRA20_CLK_UARTD }, + { .dev_id = "tegra_uart.4", .dt_id = TEGRA20_CLK_UARTE }, + { .dev_id = "tegradc.0", .dt_id = TEGRA20_CLK_DISP1 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA20_CLK_DISP2 }, }; -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, +static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { + [tegra_clk_spdif_out] = { .dt_id = TEGRA20_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA20_CLK_SPDIF_IN, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA20_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA20_CLK_SDMMC2, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA20_CLK_SDMMC3, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA20_CLK_SDMMC4, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA20_CLK_LA, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA20_CLK_CSITE, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA20_CLK_VFIR, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA20_CLK_MIPI, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA20_CLK_NOR, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA20_CLK_USBD, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA20_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA20_CLK_USB3, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA20_CLK_BLINK, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA20_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA20_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA20_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA20_CLK_PLL_P, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA20_CLK_OWR, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA20_CLK_SBC1, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA20_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA20_CLK_SBC3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA20_CLK_SBC4, .present = true }, + [tegra_clk_vde] = { .dt_id = TEGRA20_CLK_VDE, .present = true }, + [tegra_clk_vi] = { .dt_id = TEGRA20_CLK_VI, .present = true }, + [tegra_clk_epp] = { .dt_id = TEGRA20_CLK_EPP, .present = true }, + [tegra_clk_mpe] = { .dt_id = TEGRA20_CLK_MPE, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA20_CLK_HOST1X, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA20_CLK_GR2D, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA20_CLK_GR3D, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA20_CLK_NDFLASH, .present = true }, + [tegra_clk_cve] = { .dt_id = TEGRA20_CLK_CVE, .present = true }, + [tegra_clk_tvo] = { .dt_id = TEGRA20_CLK_TVO, .present = true }, + [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, + [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, }; static unsigned long tegra20_clk_measure_input_freq(void) @@ -577,10 +635,8 @@ static void tegra20_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, - 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, - pll_c_freq_table, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + &pll_c_params, NULL); + clks[TEGRA20_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -589,71 +645,13 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; - - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0, - 216000000, &pll_p_params, TEGRA_PLL_FIXED | - TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL); - clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 24, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, - TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, - 24, 8, 1, &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clks[TEGRA20_CLK_PLL_C_OUT1] = clk; /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLL_HAS_CPCON, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA20_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -662,42 +660,32 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA20_CLK_PLL_M_OUT1] = clk; /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, - pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + &pll_x_params, NULL); + clks[TEGRA20_CLK_PLL_X] = clk; /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, - 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, - pll_u_freq_table, NULL); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, NULL); + clks[TEGRA20_CLK_PLL_U] = clk; /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, - 0, &pll_d_params, TEGRA_PLL_HAS_CPCON, - pll_d_freq_table, NULL); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + &pll_d_params, NULL); + clks[TEGRA20_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA20_CLK_PLL_D_OUT0] = clk; /* PLLA */ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, - 0, &pll_a_params, TEGRA_PLL_HAS_CPCON, - pll_a_freq_table, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; + &pll_a_params, NULL); + clks[TEGRA20_CLK_PLL_A] = clk; /* PLLA_OUT0 */ clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", @@ -706,15 +694,12 @@ static void tegra20_pll_init(void) clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA20_CLK_PLL_A_OUT0] = clk; /* PLLE */ clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, - 0, 100000000, &pll_e_params, - 0, pll_e_freq_table, NULL); - clk_register_clkdev(clk, "pll_e", NULL); - clks[pll_e] = clk; + 0, &pll_e_params, NULL); + clks[TEGRA20_CLK_PLL_E] = clk; } static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -732,40 +717,17 @@ static void tegra20_super_clk_init(void) clk = tegra_clk_register_super_mux("cclk", cclk_parents, ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk", NULL); - clks[cclk] = clk; + clks[TEGRA20_CLK_CCLK] = clk; /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + CLK_SYSTEM_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, - clk_base + CLK_SYSTEM_RATE, 7, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + CLK_SYSTEM_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, - clk_base + CLK_SYSTEM_RATE, 3, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; + clks[TEGRA20_CLK_SCLK] = clk; /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); - clk_register_clkdev(clk, "twd", NULL); - clks[twd] = clk; + clks[TEGRA20_CLK_TWD] = clk; } static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", @@ -784,18 +746,16 @@ static void __init tegra20_audio_clk_init(void) clk = clk_register_gate(NULL, "audio", "audio_mux", 0, clk_base + AUDIO_SYNC_CLK, 4, CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio", NULL); - clks[audio] = clk; + clks[TEGRA20_CLK_AUDIO] = clk; /* audio_2x */ clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio", CLK_SET_RATE_PARENT, 2, 1); clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler", TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 89, &periph_u_regs, + CLK_SET_RATE_PARENT, 89, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio_2x", NULL); - clks[audio_2x] = clk; + clks[TEGRA20_CLK_AUDIO_2X] = clk; } @@ -803,68 +763,36 @@ static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", "clk_m"}; static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", "clk_m"}; -static const char *spdif_out_parents[] = {"pll_a_out0", "audio_2x", "pll_p", - "clk_m"}; -static const char *spdif_in_parents[] = {"pll_p", "pll_c", "pll_m"}; static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", "clk_32k"}; static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; -static const char *mux_pllmcpa[] = {"pll_m", "pll_c", "pll_c", "pll_a"}; static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", "clk_m"}; static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, &periph_h_regs, TEGRA_PERIPH_ON_APB, spi), - TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, &periph_h_regs, 0, xio), - TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, &periph_l_regs, TEGRA_PERIPH_ON_APB, twc), - TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, &periph_l_regs, 0, ide), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, 0, ndflash), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, 0, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, 0, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), - TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, dvc), - TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), + TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), + TEGRA_INIT_DATA_MUX("i2s2", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S2), + TEGRA_INIT_DATA_MUX("spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_SPI), + TEGRA_INIT_DATA_MUX("xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, 0, TEGRA20_CLK_XIO), + TEGRA_INIT_DATA_MUX("twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_TWC), + TEGRA_INIT_DATA_MUX("ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, 0, TEGRA20_CLK_IDE), + TEGRA_INIT_DATA_DIV16("dvc", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_DVC), + TEGRA_INIT_DATA_DIV16("i2c1", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C1), + TEGRA_INIT_DATA_DIV16("i2c2", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C2), + TEGRA_INIT_DATA_DIV16("i2c3", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C3), + TEGRA_INIT_DATA_MUX("hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA20_CLK_HDMI), + TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_PWM), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, &periph_l_regs, TEGRA_PERIPH_ON_APB, uarta), - TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, uartb), - TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, &periph_h_regs, TEGRA_PERIPH_ON_APB, uartc), - TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, &periph_u_regs, TEGRA_PERIPH_ON_APB, uartd), - TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, &periph_u_regs, TEGRA_PERIPH_ON_APB, uarte), - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, &periph_l_regs, 0, disp2), + TEGRA_INIT_DATA_NODIV("uarta", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTA), + TEGRA_INIT_DATA_NODIV("uartb", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTB), + TEGRA_INIT_DATA_NODIV("uartc", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTC), + TEGRA_INIT_DATA_NODIV("uartd", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTD), + TEGRA_INIT_DATA_NODIV("uarte", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTE), + TEGRA_INIT_DATA_NODIV("disp1", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, 0, TEGRA20_CLK_DISP1), + TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), }; static void __init tegra20_periph_clk_init(void) @@ -876,69 +804,13 @@ static void __init tegra20_periph_clk_init(void) /* ac97 */ clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", TEGRA_PERIPH_ON_APB, - clk_base, 0, 3, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra20-ac97"); - clks[ac97] = clk; + clk_base, 0, 3, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_AC97] = clk; /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, - 0, 34, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-apbdma"); - clks[apbdma] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_NO_RESET, - clk_base, 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, - 0, 5, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-kbc"); - clks[kbc] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET, - clk_base, 0, 92, &periph_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csus", "tengra_camera"); - clks[csus] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, - clk_base, 0, 29, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "vcp", "tegra-avp"); - clks[vcp] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, - clk_base, 0, 62, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsea", "tegra-avp"); - clks[bsea] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, - clk_base, 0, 63, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsev", "tegra-aes"); - clks[bsev] = clk; + 0, 34, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_APBDMA] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -947,130 +819,52 @@ static void __init tegra20_periph_clk_init(void) clk_base + CLK_SOURCE_EMC, 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "emc", NULL); - clks[emc] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); - clks[usbd] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.1"); - clks[usb2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.2"); - clks[usb3] = clk; + 57, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_EMC] = clk; /* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, - 48, &periph_h_regs, periph_clk_enb_refcnt); + 48, periph_clk_enb_refcnt); clk_register_clkdev(clk, NULL, "dsi"); - clks[dsi] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csi", "tegra_camera"); - clks[csi] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "isp", "tegra_camera"); - clks[isp] = clk; + clks[TEGRA20_CLK_DSI] = clk; /* pex */ clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, - &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pex", NULL); - clks[pex] = clk; - - /* afi */ - clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "afi", NULL); - clks[afi] = clk; - - /* pcie_xclk */ - clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, - 0, 74, &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pcie_xclk", NULL); - clks[pcie_xclk] = clk; + clks[TEGRA20_CLK_PEX] = clk; /* cdev1 */ clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, - clk_base, 0, 94, &periph_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev1", NULL); - clks[cdev1] = clk; + clk_base, 0, 94, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_CDEV1] = clk; /* cdev2 */ clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, 26000000); clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, - clk_base, 0, 93, &periph_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "cdev2", NULL); - clks[cdev2] = clk; + clk_base, 0, 93, periph_clk_enb_refcnt); + clks[TEGRA20_CLK_CDEV2] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, + clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { data = &tegra_periph_nodiv_clk_list[i]; clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, + data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } -} - - -static void __init tegra20_fixed_clk_init(void) -{ - struct clk *clk; - - /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); - clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; -} - -static void __init tegra20_pmc_clk_init(void) -{ - struct clk *clk; - /* blink */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; + tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params); } static void __init tegra20_osc_clk_init(void) @@ -1084,15 +878,13 @@ static void __init tegra20_osc_clk_init(void) /* clk_m */ clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | CLK_IGNORE_UNUSED, input_freq); - clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; + clks[TEGRA20_CLK_CLK_M] = clk; /* pll_ref */ pll_ref_div = tegra20_get_pll_ref_div(); clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + clks[TEGRA20_CLK_PLL_REF] = clk; } /* Tegra20 CPU clock and reset control functions */ @@ -1226,49 +1018,49 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {pll_p, clk_max, 216000000, 1}, - {pll_p_out1, clk_max, 28800000, 1}, - {pll_p_out2, clk_max, 48000000, 1}, - {pll_p_out3, clk_max, 72000000, 1}, - {pll_p_out4, clk_max, 24000000, 1}, - {pll_c, clk_max, 600000000, 1}, - {pll_c_out1, clk_max, 120000000, 1}, - {sclk, pll_c_out1, 0, 1}, - {hclk, clk_max, 0, 1}, - {pclk, clk_max, 60000000, 1}, - {csite, clk_max, 0, 1}, - {emc, clk_max, 0, 1}, - {cclk, clk_max, 0, 1}, - {uarta, pll_p, 0, 0}, - {uartb, pll_p, 0, 0}, - {uartc, pll_p, 0, 0}, - {uartd, pll_p, 0, 0}, - {uarte, pll_p, 0, 0}, - {pll_a, clk_max, 56448000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {cdev1, clk_max, 0, 1}, - {blink, clk_max, 32768, 1}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {sdmmc1, pll_p, 48000000, 0}, - {sdmmc3, pll_p, 48000000, 0}, - {sdmmc4, pll_p, 48000000, 0}, - {spi, pll_p, 20000000, 0}, - {sbc1, pll_p, 100000000, 0}, - {sbc2, pll_p, 100000000, 0}, - {sbc3, pll_p, 100000000, 0}, - {sbc4, pll_p, 100000000, 0}, - {host1x, pll_c, 150000000, 0}, - {disp1, pll_p, 600000000, 0}, - {disp2, pll_p, 600000000, 0}, - {gr2d, pll_c, 300000000, 0}, - {gr3d, pll_c, 300000000, 0}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */ + {TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1}, + {TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1}, + {TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1}, + {TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1}, + {TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1}, + {TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1}, + {TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1}, + {TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1}, + {TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1}, + {TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0}, + {TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1}, + {TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1}, + {TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1}, + {TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1}, + {TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0}, + {TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0}, + {TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0}, + {TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0}, + {TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0}, + {TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0}, + {TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0}, + {TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0}, + {TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry */ }; static void __init tegra20_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); } /* @@ -1277,11 +1069,11 @@ static void __init tegra20_clock_apply_init_table(void) * table under two names. */ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { - TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), - TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), - TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "utmip-pad", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-ehci.0", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-otg", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK, NULL, "cpu"), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL), /* Must be the last entry */ }; static const struct of_device_id pmc_match[] __initconst = { @@ -1291,7 +1083,6 @@ static const struct of_device_id pmc_match[] __initconst = { static void __init tegra20_clock_init(struct device_node *np) { - int i; struct device_node *node; clk_base = of_iomap(np, 0); @@ -1312,30 +1103,24 @@ static void __init tegra20_clock_init(struct device_node *np) BUG(); } + clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX, + TEGRA20_CLK_PERIPH_BANKS); + if (!clks) + return; + tegra20_osc_clk_init(); - tegra20_pmc_clk_init(); - tegra20_fixed_clk_init(); + tegra_fixed_clk_init(tegra20_clks); tegra20_pll_init(); tegra20_super_clk_init(); + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL); tegra20_periph_clk_init(); tegra20_audio_clk_init(); + tegra_pmc_clk_init(pmc_base, tegra20_clks); + tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX); - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err("Tegra20 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - BUG(); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } - - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra20_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index dbe7c80..8b10c38 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -23,42 +23,9 @@ #include <linux/of_address.h> #include <linux/clk/tegra.h> #include <linux/tegra-powergate.h> - +#include <dt-bindings/clock/tegra30-car.h> #include "clk.h" - -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00c -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35c -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c -#define RST_DEVICES_NUM 5 - -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c -#define CLK_OUT_ENB_NUM 5 +#include "clk-id.h" #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) @@ -92,6 +59,8 @@ #define SYSTEM_CLK_RATE 0x030 +#define TEGRA30_CLK_PERIPH_BANKS 5 + #define PLLC_BASE 0x80 #define PLLC_MISC 0x8c #define PLLM_BASE 0x90 @@ -132,88 +101,21 @@ #define AUDIO_SYNC_CLK_I2S4 0x4b0 #define AUDIO_SYNC_CLK_SPDIF 0x4b4 -#define PMC_CLK_OUT_CNTRL 0x1a8 - -#define CLK_SOURCE_I2S0 0x1d8 -#define CLK_SOURCE_I2S1 0x100 -#define CLK_SOURCE_I2S2 0x104 -#define CLK_SOURCE_I2S3 0x3bc -#define CLK_SOURCE_I2S4 0x3c0 #define CLK_SOURCE_SPDIF_OUT 0x108 -#define CLK_SOURCE_SPDIF_IN 0x10c #define CLK_SOURCE_PWM 0x110 #define CLK_SOURCE_D_AUDIO 0x3d0 #define CLK_SOURCE_DAM0 0x3d8 #define CLK_SOURCE_DAM1 0x3dc #define CLK_SOURCE_DAM2 0x3e0 -#define CLK_SOURCE_HDA 0x428 -#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 -#define CLK_SOURCE_SBC1 0x134 -#define CLK_SOURCE_SBC2 0x118 -#define CLK_SOURCE_SBC3 0x11c -#define CLK_SOURCE_SBC4 0x1b4 -#define CLK_SOURCE_SBC5 0x3c8 -#define CLK_SOURCE_SBC6 0x3cc -#define CLK_SOURCE_SATA_OOB 0x420 -#define CLK_SOURCE_SATA 0x424 -#define CLK_SOURCE_NDFLASH 0x160 -#define CLK_SOURCE_NDSPEED 0x3f8 -#define CLK_SOURCE_VFIR 0x168 -#define CLK_SOURCE_SDMMC1 0x150 -#define CLK_SOURCE_SDMMC2 0x154 -#define CLK_SOURCE_SDMMC3 0x1bc -#define CLK_SOURCE_SDMMC4 0x164 -#define CLK_SOURCE_VDE 0x1c8 -#define CLK_SOURCE_CSITE 0x1d4 -#define CLK_SOURCE_LA 0x1f8 -#define CLK_SOURCE_OWR 0x1cc -#define CLK_SOURCE_NOR 0x1d0 -#define CLK_SOURCE_MIPI 0x174 -#define CLK_SOURCE_I2C1 0x124 -#define CLK_SOURCE_I2C2 0x198 -#define CLK_SOURCE_I2C3 0x1b8 -#define CLK_SOURCE_I2C4 0x3c4 -#define CLK_SOURCE_I2C5 0x128 -#define CLK_SOURCE_UARTA 0x178 -#define CLK_SOURCE_UARTB 0x17c -#define CLK_SOURCE_UARTC 0x1a0 -#define CLK_SOURCE_UARTD 0x1c0 -#define CLK_SOURCE_UARTE 0x1c4 -#define CLK_SOURCE_VI 0x148 -#define CLK_SOURCE_VI_SENSOR 0x1a8 -#define CLK_SOURCE_3D 0x158 #define CLK_SOURCE_3D2 0x3b0 #define CLK_SOURCE_2D 0x15c -#define CLK_SOURCE_EPP 0x16c -#define CLK_SOURCE_MPE 0x170 -#define CLK_SOURCE_HOST1X 0x180 -#define CLK_SOURCE_CVE 0x140 -#define CLK_SOURCE_TVO 0x188 -#define CLK_SOURCE_DTV 0x1dc #define CLK_SOURCE_HDMI 0x18c -#define CLK_SOURCE_TVDAC 0x194 -#define CLK_SOURCE_DISP1 0x138 -#define CLK_SOURCE_DISP2 0x13c #define CLK_SOURCE_DSIB 0xd0 -#define CLK_SOURCE_TSENSOR 0x3b8 -#define CLK_SOURCE_ACTMON 0x3e8 -#define CLK_SOURCE_EXTERN1 0x3ec -#define CLK_SOURCE_EXTERN2 0x3f0 -#define CLK_SOURCE_EXTERN3 0x3f4 -#define CLK_SOURCE_I2CSLOW 0x3fc #define CLK_SOURCE_SE 0x42c -#define CLK_SOURCE_MSELECT 0x3b4 #define CLK_SOURCE_EMC 0x19c #define AUDIO_SYNC_DOUBLER 0x49c -#define PMC_CTRL 0 -#define PMC_CTRL_BLINK_ENB 7 - -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_BLINK_TIMER 0x40 - #define UTMIP_PLL_CFG2 0x488 #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) @@ -266,89 +168,41 @@ static struct cpu_clk_suspend_context { } tegra30_cpu_clk_sctx; #endif -static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; - static void __iomem *clk_base; static void __iomem *pmc_base; static unsigned long input_freq; -static DEFINE_SPINLOCK(clk_doubler_lock); -static DEFINE_SPINLOCK(clk_out_lock); -static DEFINE_SPINLOCK(pll_div_lock); static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); -static DEFINE_SPINLOCK(sysrate_lock); - -#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id) - -#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ - _regs, _clk_num, periph_clk_enb_refcnt, \ - _gate_flags, _clk_id) - -#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 29, 3, 0, 0, 8, 1, 0, _regs, _clk_num, \ - periph_clk_enb_refcnt, _gate_flags, _clk_id) - -#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ - _clk_num, _regs, _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ - _clk_id) -#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ - _clk_num, _regs, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs, \ - _clk_num, periph_clk_enb_refcnt, 0, _clk_id) +#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ + _clk_num, _gate_flags, _clk_id) + +#define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ + _clk_num, _gate_flags, _clk_id) + +#define TEGRA_INIT_DATA_INT(_name, _parents, _offset, \ + _clk_num, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, \ + _gate_flags, _clk_id) -#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, _clk_num, _regs, \ +#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_width, _clk_num, \ _gate_flags, _clk_id) \ - TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ - _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ - _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ + _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ + _clk_num, _gate_flags, \ _clk_id) -/* - * IDs assigned here must be in sync with DT bindings definition - * for Tegra30 clocks. - */ -enum tegra30_clk { - cpu, rtc = 4, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, ndflash, - sdmmc1, sdmmc4, pwm = 17, i2s2, epp, gr2d = 21, usbd, isp, gr3d, - disp2 = 26, disp1, host1x, vcp, i2s0, cop_cache, mc, ahbdma, apbdma, - kbc = 36, statmon, pmc, kfuse = 40, sbc1, nor, sbc2 = 44, sbc3 = 46, - i2c5, dsia, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, - usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, - pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2cslow, - dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92, - cdev2, cdev1, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4, - i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x, - atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x, - spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda, - se = 127, hda2hdmi, sata_cold, uartb = 160, vfir, spdif_in, spdif_out, - vi, vi_sensor, fuse, fuse_burn, cve, tvo, clk_32k, clk_m, clk_m_div2, - clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_m, pll_m_out1, pll_p, - pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_a, pll_a_out0, - pll_d, pll_d_out0, pll_d2, pll_d2_out0, pll_u, pll_x, pll_x_out0, pll_e, - spdif_in_sync, i2s0_sync, i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, - vimclk_sync, audio0, audio1, audio2, audio3, audio4, spdif, clk_out_1, - clk_out_2, clk_out_3, sclk, blink, cclk_g, cclk_lp, twd, cml0, cml1, - hclk, pclk, clk_out_1_mux = 300, clk_max -}; - -static struct clk *clks[clk_max]; -static struct clk_onecell_data clk_data; +static struct clk **clks; /* * Structure defining the fields for USB UTMI clocks Parameters. @@ -564,6 +418,8 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_c_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct div_nmp pllm_nmp = { @@ -593,6 +449,9 @@ static struct tegra_clk_pll_params pll_m_params = { .div_nmp = &pllm_nmp, .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | + TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_p_params = { @@ -607,6 +466,9 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_p_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .fixed_rate = 408000000, }; static struct tegra_clk_pll_params pll_a_params = { @@ -621,6 +483,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_d_params = { @@ -635,6 +499,10 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, + }; static struct tegra_clk_pll_params pll_d2_params = { @@ -649,6 +517,9 @@ static struct tegra_clk_pll_params pll_d2_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_u_params = { @@ -664,6 +535,8 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .pdiv_tohw = pllu_p, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON, }; static struct tegra_clk_pll_params pll_x_params = { @@ -678,6 +551,9 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | + TEGRA_PLL_USE_LOCK, }; static struct tegra_clk_pll_params pll_e_params = { @@ -692,116 +568,299 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED, + .fixed_rate = 100000000, }; -/* Peripheral clock registers */ -static struct tegra_clk_periph_regs periph_l_regs = { - .enb_reg = CLK_OUT_ENB_L, - .enb_set_reg = CLK_OUT_ENB_SET_L, - .enb_clr_reg = CLK_OUT_ENB_CLR_L, - .rst_reg = RST_DEVICES_L, - .rst_set_reg = RST_DEVICES_SET_L, - .rst_clr_reg = RST_DEVICES_CLR_L, +static unsigned long tegra30_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, }; -static struct tegra_clk_periph_regs periph_h_regs = { - .enb_reg = CLK_OUT_ENB_H, - .enb_set_reg = CLK_OUT_ENB_SET_H, - .enb_clr_reg = CLK_OUT_ENB_CLR_H, - .rst_reg = RST_DEVICES_H, - .rst_set_reg = RST_DEVICES_SET_H, - .rst_clr_reg = RST_DEVICES_CLR_H, +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 }, + { .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA30_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA30_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA30_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA30_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA30_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA30_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA30_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA30_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA30_CLK_PLL_U }, + { .con_id = "pll_d", .dt_id = TEGRA30_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA30_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA30_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA30_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA30_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA30_CLK_PLL_A_OUT0 }, + { .con_id = "pll_e", .dt_id = TEGRA30_CLK_PLL_E }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA30_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA30_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA30_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA30_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA30_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA30_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA30_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA30_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA30_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA30_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA30_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA30_CLK_SPDIF }, + { .con_id = "audio0_2x", .dt_id = TEGRA30_CLK_AUDIO0_2X }, + { .con_id = "audio1_2x", .dt_id = TEGRA30_CLK_AUDIO1_2X }, + { .con_id = "audio2_2x", .dt_id = TEGRA30_CLK_AUDIO2_2X }, + { .con_id = "audio3_2x", .dt_id = TEGRA30_CLK_AUDIO3_2X }, + { .con_id = "audio4_2x", .dt_id = TEGRA30_CLK_AUDIO4_2X }, + { .con_id = "spdif_2x", .dt_id = TEGRA30_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA30_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA30_CLK_PCLK }, + { .con_id = "twd", .dt_id = TEGRA30_CLK_TWD }, + { .con_id = "emc", .dt_id = TEGRA30_CLK_EMC }, + { .con_id = "clk_32k", .dt_id = TEGRA30_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA30_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA30_CLK_CLK_M_DIV4 }, + { .con_id = "cml0", .dt_id = TEGRA30_CLK_CML0 }, + { .con_id = "cml1", .dt_id = TEGRA30_CLK_CML1 }, + { .con_id = "clk_m", .dt_id = TEGRA30_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA30_CLK_PLL_REF }, + { .con_id = "csus", .dev_id = "tengra_camera", .dt_id = TEGRA30_CLK_CSUS }, + { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_VCP }, + { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_BSEA }, + { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA30_CLK_BSEV }, + { .con_id = "dsia", .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DSIA }, + { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_CSI }, + { .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 = "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 }, + { .con_id = "hda2hdmi", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2HDMI }, + { .dev_id = "tegra-apbdma", .dt_id = TEGRA30_CLK_APBDMA }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA30_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA30_CLK_TIMER }, + { .dev_id = "tegra-kbc", .dt_id = TEGRA30_CLK_KBC }, + { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA30_CLK_USBD }, + { .dev_id = "tegra-ehci.1", .dt_id = TEGRA30_CLK_USB2 }, + { .dev_id = "tegra-ehci.2", .dt_id = TEGRA30_CLK_USB2 }, + { .dev_id = "kfuse-tegra", .dt_id = TEGRA30_CLK_KFUSE }, + { .dev_id = "tegra_sata_cold", .dt_id = TEGRA30_CLK_SATA_COLD }, + { .dev_id = "dtv", .dt_id = TEGRA30_CLK_DTV }, + { .dev_id = "tegra30-i2s.0", .dt_id = TEGRA30_CLK_I2S0 }, + { .dev_id = "tegra30-i2s.1", .dt_id = TEGRA30_CLK_I2S1 }, + { .dev_id = "tegra30-i2s.2", .dt_id = TEGRA30_CLK_I2S2 }, + { .dev_id = "tegra30-i2s.3", .dt_id = TEGRA30_CLK_I2S3 }, + { .dev_id = "tegra30-i2s.4", .dt_id = TEGRA30_CLK_I2S4 }, + { .con_id = "spdif_out", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_OUT }, + { .con_id = "spdif_in", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_IN }, + { .con_id = "d_audio", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_D_AUDIO }, + { .dev_id = "tegra30-dam.0", .dt_id = TEGRA30_CLK_DAM0 }, + { .dev_id = "tegra30-dam.1", .dt_id = TEGRA30_CLK_DAM1 }, + { .dev_id = "tegra30-dam.2", .dt_id = TEGRA30_CLK_DAM2 }, + { .con_id = "hda", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA }, + { .con_id = "hda2codec", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2CODEC_2X }, + { .dev_id = "spi_tegra.0", .dt_id = TEGRA30_CLK_SBC1 }, + { .dev_id = "spi_tegra.1", .dt_id = TEGRA30_CLK_SBC2 }, + { .dev_id = "spi_tegra.2", .dt_id = TEGRA30_CLK_SBC3 }, + { .dev_id = "spi_tegra.3", .dt_id = TEGRA30_CLK_SBC4 }, + { .dev_id = "spi_tegra.4", .dt_id = TEGRA30_CLK_SBC5 }, + { .dev_id = "spi_tegra.5", .dt_id = TEGRA30_CLK_SBC6 }, + { .dev_id = "tegra_sata_oob", .dt_id = TEGRA30_CLK_SATA_OOB }, + { .dev_id = "tegra_sata", .dt_id = TEGRA30_CLK_SATA }, + { .dev_id = "tegra_nand", .dt_id = TEGRA30_CLK_NDFLASH }, + { .dev_id = "tegra_nand_speed", .dt_id = TEGRA30_CLK_NDSPEED }, + { .dev_id = "vfir", .dt_id = TEGRA30_CLK_VFIR }, + { .dev_id = "csite", .dt_id = TEGRA30_CLK_CSITE }, + { .dev_id = "la", .dt_id = TEGRA30_CLK_LA }, + { .dev_id = "tegra_w1", .dt_id = TEGRA30_CLK_OWR }, + { .dev_id = "mipi", .dt_id = TEGRA30_CLK_MIPI }, + { .dev_id = "tegra-tsensor", .dt_id = TEGRA30_CLK_TSENSOR }, + { .dev_id = "i2cslow", .dt_id = TEGRA30_CLK_I2CSLOW }, + { .dev_id = "vde", .dt_id = TEGRA30_CLK_VDE }, + { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI }, + { .dev_id = "epp", .dt_id = TEGRA30_CLK_EPP }, + { .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE }, + { .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X }, + { .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D }, + { .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 }, + { .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D }, + { .dev_id = "se", .dt_id = TEGRA30_CLK_SE }, + { .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT }, + { .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR }, + { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA30_CLK_SDMMC1 }, + { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA30_CLK_SDMMC2 }, + { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA30_CLK_SDMMC3 }, + { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA30_CLK_SDMMC4 }, + { .dev_id = "cve", .dt_id = TEGRA30_CLK_CVE }, + { .dev_id = "tvo", .dt_id = TEGRA30_CLK_TVO }, + { .dev_id = "tvdac", .dt_id = TEGRA30_CLK_TVDAC }, + { .dev_id = "actmon", .dt_id = TEGRA30_CLK_ACTMON }, + { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI_SENSOR }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA30_CLK_I2C1 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA30_CLK_I2C2 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA30_CLK_I2C3 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA30_CLK_I2C4 }, + { .con_id = "div-clk", .dev_id = "tegra-i2c.4", .dt_id = TEGRA30_CLK_I2C5 }, + { .dev_id = "tegra_uart.0", .dt_id = TEGRA30_CLK_UARTA }, + { .dev_id = "tegra_uart.1", .dt_id = TEGRA30_CLK_UARTB }, + { .dev_id = "tegra_uart.2", .dt_id = TEGRA30_CLK_UARTC }, + { .dev_id = "tegra_uart.3", .dt_id = TEGRA30_CLK_UARTD }, + { .dev_id = "tegra_uart.4", .dt_id = TEGRA30_CLK_UARTE }, + { .dev_id = "hdmi", .dt_id = TEGRA30_CLK_HDMI }, + { .dev_id = "extern1", .dt_id = TEGRA30_CLK_EXTERN1 }, + { .dev_id = "extern2", .dt_id = TEGRA30_CLK_EXTERN2 }, + { .dev_id = "extern3", .dt_id = TEGRA30_CLK_EXTERN3 }, + { .dev_id = "pwm", .dt_id = TEGRA30_CLK_PWM }, + { .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DISP1 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DISP2 }, + { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DSIB }, }; -static struct tegra_clk_periph_regs periph_u_regs = { - .enb_reg = CLK_OUT_ENB_U, - .enb_set_reg = CLK_OUT_ENB_SET_U, - .enb_clr_reg = CLK_OUT_ENB_CLR_U, - .rst_reg = RST_DEVICES_U, - .rst_set_reg = RST_DEVICES_SET_U, - .rst_clr_reg = RST_DEVICES_CLR_U, -}; +static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { + [tegra_clk_clk_32k] = { .dt_id = TEGRA30_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA30_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA30_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA30_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA30_CLK_PLL_REF, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA30_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA30_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA30_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA30_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA30_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA30_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA30_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA30_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA30_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA30_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA30_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA30_CLK_SPDIF, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA30_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA30_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA30_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA30_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA30_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA30_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_audio0_2x] = { .dt_id = TEGRA30_CLK_AUDIO0_2X, .present = true }, + [tegra_clk_audio1_2x] = { .dt_id = TEGRA30_CLK_AUDIO1_2X, .present = true }, + [tegra_clk_audio2_2x] = { .dt_id = TEGRA30_CLK_AUDIO2_2X, .present = true }, + [tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true }, + [tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA30_CLK_I2S1, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA30_CLK_I2S2, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA30_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA30_CLK_I2S4, .present = true }, + [tegra_clk_spdif_in] = { .dt_id = TEGRA30_CLK_SPDIF_IN, .present = true }, + [tegra_clk_hda] = { .dt_id = TEGRA30_CLK_HDA, .present = true }, + [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA30_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_sbc1] = { .dt_id = TEGRA30_CLK_SBC1, .present = true }, + [tegra_clk_sbc2] = { .dt_id = TEGRA30_CLK_SBC2, .present = true }, + [tegra_clk_sbc3] = { .dt_id = TEGRA30_CLK_SBC3, .present = true }, + [tegra_clk_sbc4] = { .dt_id = TEGRA30_CLK_SBC4, .present = true }, + [tegra_clk_sbc5] = { .dt_id = TEGRA30_CLK_SBC5, .present = true }, + [tegra_clk_sbc6] = { .dt_id = TEGRA30_CLK_SBC6, .present = true }, + [tegra_clk_ndflash] = { .dt_id = TEGRA30_CLK_NDFLASH, .present = true }, + [tegra_clk_ndspeed] = { .dt_id = TEGRA30_CLK_NDSPEED, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA30_CLK_VFIR, .present = true }, + [tegra_clk_la] = { .dt_id = TEGRA30_CLK_LA, .present = true }, + [tegra_clk_csite] = { .dt_id = TEGRA30_CLK_CSITE, .present = true }, + [tegra_clk_owr] = { .dt_id = TEGRA30_CLK_OWR, .present = true }, + [tegra_clk_mipi] = { .dt_id = TEGRA30_CLK_MIPI, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA30_CLK_TSENSOR, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA30_CLK_I2CSLOW, .present = true }, + [tegra_clk_vde] = { .dt_id = TEGRA30_CLK_VDE, .present = true }, + [tegra_clk_vi] = { .dt_id = TEGRA30_CLK_VI, .present = true }, + [tegra_clk_epp] = { .dt_id = TEGRA30_CLK_EPP, .present = true }, + [tegra_clk_mpe] = { .dt_id = TEGRA30_CLK_MPE, .present = true }, + [tegra_clk_host1x] = { .dt_id = TEGRA30_CLK_HOST1X, .present = true }, + [tegra_clk_gr2d] = { .dt_id = TEGRA30_CLK_GR2D, .present = true }, + [tegra_clk_gr3d] = { .dt_id = TEGRA30_CLK_GR3D, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA30_CLK_MSELECT, .present = true }, + [tegra_clk_nor] = { .dt_id = TEGRA30_CLK_NOR, .present = true }, + [tegra_clk_sdmmc1] = { .dt_id = TEGRA30_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc2] = { .dt_id = TEGRA30_CLK_SDMMC2, .present = true }, + [tegra_clk_sdmmc3] = { .dt_id = TEGRA30_CLK_SDMMC3, .present = true }, + [tegra_clk_sdmmc4] = { .dt_id = TEGRA30_CLK_SDMMC4, .present = true }, + [tegra_clk_cve] = { .dt_id = TEGRA30_CLK_CVE, .present = true }, + [tegra_clk_tvo] = { .dt_id = TEGRA30_CLK_TVO, .present = true }, + [tegra_clk_tvdac] = { .dt_id = TEGRA30_CLK_TVDAC, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA30_CLK_ACTMON, .present = true }, + [tegra_clk_vi_sensor] = { .dt_id = TEGRA30_CLK_VI_SENSOR, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA30_CLK_I2C1, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA30_CLK_I2C2, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA30_CLK_I2C3, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA30_CLK_I2C4, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA30_CLK_I2C5, .present = true }, + [tegra_clk_uarta] = { .dt_id = TEGRA30_CLK_UARTA, .present = true }, + [tegra_clk_uartb] = { .dt_id = TEGRA30_CLK_UARTB, .present = true }, + [tegra_clk_uartc] = { .dt_id = TEGRA30_CLK_UARTC, .present = true }, + [tegra_clk_uartd] = { .dt_id = TEGRA30_CLK_UARTD, .present = true }, + [tegra_clk_uarte] = { .dt_id = TEGRA30_CLK_UARTE, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA30_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA30_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA30_CLK_EXTERN3, .present = true }, + [tegra_clk_disp1] = { .dt_id = TEGRA30_CLK_DISP1, .present = true }, + [tegra_clk_disp2] = { .dt_id = TEGRA30_CLK_DISP2, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA30_CLK_APBDMA, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true }, + [tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true }, + [tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true }, + [tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA30_CLK_USBD, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA30_CLK_USB2, .present = true }, + [tegra_clk_usb3] = { .dt_id = TEGRA30_CLK_USB3, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA30_CLK_CSI, .present = true }, + [tegra_clk_isp] = { .dt_id = TEGRA30_CLK_ISP, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA30_CLK_KFUSE, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA30_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA30_CLK_FUSE_BURN, .present = true }, + [tegra_clk_apbif] = { .dt_id = TEGRA30_CLK_APBIF, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA30_CLK_HDA2HDMI, .present = true }, + [tegra_clk_sata_cold] = { .dt_id = TEGRA30_CLK_SATA_COLD, .present = true }, + [tegra_clk_sata_oob] = { .dt_id = TEGRA30_CLK_SATA_OOB, .present = true }, + [tegra_clk_sata] = { .dt_id = TEGRA30_CLK_SATA, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA30_CLK_DTV, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA30_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA30_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA30_CLK_PLL_P_OUT2, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA30_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA30_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, -static struct tegra_clk_periph_regs periph_v_regs = { - .enb_reg = CLK_OUT_ENB_V, - .enb_set_reg = CLK_OUT_ENB_SET_V, - .enb_clr_reg = CLK_OUT_ENB_CLR_V, - .rst_reg = RST_DEVICES_V, - .rst_set_reg = RST_DEVICES_SET_V, - .rst_clr_reg = RST_DEVICES_CLR_V, }; -static struct tegra_clk_periph_regs periph_w_regs = { - .enb_reg = CLK_OUT_ENB_W, - .enb_set_reg = CLK_OUT_ENB_SET_W, - .enb_clr_reg = CLK_OUT_ENB_CLR_W, - .rst_reg = RST_DEVICES_W, - .rst_set_reg = RST_DEVICES_SET_W, - .rst_clr_reg = RST_DEVICES_CLR_W, -}; - -static void tegra30_clk_measure_input_freq(void) -{ - u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); - u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK; - u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; - - switch (auto_clk_control) { - case OSC_CTRL_OSC_FREQ_12MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 12000000; - break; - case OSC_CTRL_OSC_FREQ_13MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 13000000; - break; - case OSC_CTRL_OSC_FREQ_19_2MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 19200000; - break; - case OSC_CTRL_OSC_FREQ_26MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 26000000; - break; - case OSC_CTRL_OSC_FREQ_16_8MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); - input_freq = 16800000; - break; - case OSC_CTRL_OSC_FREQ_38_4MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); - input_freq = 38400000; - break; - case OSC_CTRL_OSC_FREQ_48MHZ: - BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); - input_freq = 48000000; - break; - default: - pr_err("Unexpected auto clock control value %d", - auto_clk_control); - BUG(); - return; - } -} - -static unsigned int tegra30_get_pll_ref_div(void) -{ - u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) & - OSC_CTRL_PLL_REF_DIV_MASK; - - switch (pll_ref_div) { - case OSC_CTRL_PLL_REF_DIV_1: - return 1; - case OSC_CTRL_PLL_REF_DIV_2: - return 2; - case OSC_CTRL_PLL_REF_DIV_4: - return 4; - default: - pr_err("Invalid pll ref divider %d", pll_ref_div); - BUG(); - } - return 0; -} - static void tegra30_utmi_param_configure(void) { u32 reg; @@ -863,11 +922,8 @@ static void __init tegra30_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_c_params, - TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, - pll_c_freq_table, NULL); - clk_register_clkdev(clk, "pll_c", NULL); - clks[pll_c] = clk; + &pll_c_params, NULL); + clks[TEGRA30_CLK_PLL_C] = clk; /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", @@ -876,73 +932,13 @@ static void __init tegra30_pll_init(void) clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_c_out1", NULL); - clks[pll_c_out1] = clk; - - /* PLLP */ - clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0, - 408000000, &pll_p_params, - TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL); - clk_register_clkdev(clk, "pll_p", NULL); - clks[pll_p] = clk; - - /* PLLP_OUT1 */ - clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", - clk_base + PLLP_OUTA, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out1", NULL); - clks[pll_p_out1] = clk; - - /* PLLP_OUT2 */ - clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", - clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", - clk_base + PLLP_OUTA, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out2", NULL); - clks[pll_p_out2] = clk; - - /* PLLP_OUT3 */ - clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", - clk_base + PLLP_OUTB, 1, 0, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out3", NULL); - clks[pll_p_out3] = clk; - - /* PLLP_OUT4 */ - clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", - clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | - TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, - &pll_div_lock); - clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", - clk_base + PLLP_OUTB, 17, 16, - CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, - &pll_div_lock); - clk_register_clkdev(clk, "pll_p_out4", NULL); - clks[pll_p_out4] = clk; + clks[TEGRA30_CLK_PLL_C_OUT1] = clk; /* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, - &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_m_freq_table, NULL); - clk_register_clkdev(clk, "pll_m", NULL); - clks[pll_m] = clk; + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + &pll_m_params, NULL); + clks[TEGRA30_CLK_PLL_M] = clk; /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", @@ -951,78 +947,44 @@ static void __init tegra30_pll_init(void) clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_m_out1", NULL); - clks[pll_m_out1] = clk; + clks[TEGRA30_CLK_PLL_M_OUT1] = clk; /* PLLX */ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_x_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, - pll_x_freq_table, NULL); - clk_register_clkdev(clk, "pll_x", NULL); - clks[pll_x] = clk; + &pll_x_params, NULL); + clks[TEGRA30_CLK_PLL_X] = clk; /* PLLX_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_x_out0", NULL); - clks[pll_x_out0] = clk; + clks[TEGRA30_CLK_PLL_X_OUT0] = clk; /* PLLU */ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON, - pll_u_freq_table, - NULL); - clk_register_clkdev(clk, "pll_u", NULL); - clks[pll_u] = clk; + &pll_u_params, NULL); + clks[TEGRA30_CLK_PLL_U] = clk; tegra30_utmi_param_configure(); /* PLLD */ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_d_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - pll_d_freq_table, &pll_d_lock); - clk_register_clkdev(clk, "pll_d", NULL); - clks[pll_d] = clk; + &pll_d_params, &pll_d_lock); + clks[TEGRA30_CLK_PLL_D] = clk; /* PLLD_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d_out0", NULL); - clks[pll_d_out0] = clk; + clks[TEGRA30_CLK_PLL_D_OUT0] = clk; /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, - 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - pll_d_freq_table, NULL); - clk_register_clkdev(clk, "pll_d2", NULL); - clks[pll_d2] = clk; + &pll_d2_params, NULL); + clks[TEGRA30_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "pll_d2_out0", NULL); - clks[pll_d2_out0] = clk; - - /* PLLA */ - clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base, - 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); - clk_register_clkdev(clk, "pll_a", NULL); - clks[pll_a] = clk; - - /* PLLA_OUT0 */ - clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", - clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, - 8, 8, 1, NULL); - clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", - clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | - CLK_SET_RATE_PARENT, 0, NULL); - clk_register_clkdev(clk, "pll_a_out0", NULL); - clks[pll_a_out0] = clk; + clks[TEGRA30_CLK_PLL_D2_OUT0] = clk; /* PLLE */ clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents, @@ -1030,258 +992,8 @@ static void __init tegra30_pll_init(void) CLK_SET_RATE_NO_REPARENT, clk_base + PLLE_AUX, 2, 1, 0, NULL); clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, - CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params, - TEGRA_PLLE_CONFIGURE, pll_e_freq_table, NULL); - clk_register_clkdev(clk, "pll_e", NULL); - clks[pll_e] = clk; -} - -static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", - "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",}; -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", }; -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", }; -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", }; - -static void __init tegra30_audio_clk_init(void) -{ - struct clk *clk; - - /* spdif_in_sync */ - clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, - 24000000); - clk_register_clkdev(clk, "spdif_in_sync", NULL); - clks[spdif_in_sync] = clk; - - /* i2s0_sync */ - clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s0_sync", NULL); - clks[i2s0_sync] = clk; - - /* i2s1_sync */ - clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s1_sync", NULL); - clks[i2s1_sync] = clk; - - /* i2s2_sync */ - clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s2_sync", NULL); - clks[i2s2_sync] = clk; - - /* i2s3_sync */ - clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s3_sync", NULL); - clks[i2s3_sync] = clk; - - /* i2s4_sync */ - clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); - clk_register_clkdev(clk, "i2s4_sync", NULL); - clks[i2s4_sync] = clk; - - /* vimclk_sync */ - clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); - clk_register_clkdev(clk, "vimclk_sync", NULL); - clks[vimclk_sync] = clk; - - /* audio0 */ - clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S0, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio0", NULL); - clks[audio0] = clk; - - /* audio1 */ - clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S1, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio1", NULL); - clks[audio1] = clk; - - /* audio2 */ - clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S2, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio2", NULL); - clks[audio2] = clk; - - /* audio3 */ - clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S3, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio3", NULL); - clks[audio3] = clk; - - /* audio4 */ - clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, - clk_base + AUDIO_SYNC_CLK_I2S4, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "audio4", NULL); - clks[audio4] = clk; - - /* spdif */ - clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, - ARRAY_SIZE(mux_audio_sync_clk), - CLK_SET_RATE_NO_REPARENT, - clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL); - clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, - clk_base + AUDIO_SYNC_CLK_SPDIF, 4, - CLK_GATE_SET_TO_DISABLE, NULL); - clk_register_clkdev(clk, "spdif", NULL); - clks[spdif] = clk; - - /* audio0_2x */ - clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 113, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio0_2x", NULL); - clks[audio0_2x] = clk; - - /* audio1_2x */ - clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 114, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio1_2x", NULL); - clks[audio1_2x] = clk; - - /* audio2_2x */ - clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 115, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio2_2x", NULL); - clks[audio2_2x] = clk; - - /* audio3_2x */ - clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 116, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio3_2x", NULL); - clks[audio3_2x] = clk; - - /* audio4_2x */ - clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 117, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "audio4_2x", NULL); - clks[audio4_2x] = clk; - - /* spdif_2x */ - clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", - CLK_SET_RATE_PARENT, 2, 1); - clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", - clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, 0, - &clk_doubler_lock); - clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", - TEGRA_PERIPH_NO_RESET, clk_base, - CLK_SET_RATE_PARENT, 118, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "spdif_2x", NULL); - clks[spdif_2x] = clk; -} - -static void __init tegra30_pmc_clk_init(void) -{ - struct clk *clk; - - /* clk_out_1 */ - clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, - ARRAY_SIZE(clk_out1_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, - &clk_out_lock); - clks[clk_out_1_mux] = clk; - clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern1", "clk_out_1"); - clks[clk_out_1] = clk; - - /* clk_out_2 */ - clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, - ARRAY_SIZE(clk_out2_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, - &clk_out_lock); - clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern2", "clk_out_2"); - clks[clk_out_2] = clk; - - /* clk_out_3 */ - clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, - ARRAY_SIZE(clk_out3_parents), - CLK_SET_RATE_NO_REPARENT, - pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, - &clk_out_lock); - clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, - pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, - &clk_out_lock); - clk_register_clkdev(clk, "extern3", "clk_out_3"); - clks[clk_out_3] = clk; - - /* blink */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - clks[blink] = clk; - + CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); + clks[TEGRA30_CLK_PLL_E] = clk; } static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -1332,8 +1044,7 @@ static void __init tegra30_super_clk_init(void) CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "cclk_g", NULL); - clks[cclk_g] = clk; + clks[TEGRA30_CLK_CCLK_G] = clk; /* * Clock input to cclk_lp divided from pll_p using @@ -1369,8 +1080,7 @@ static void __init tegra30_super_clk_init(void) clk_base + CCLKLP_BURST_POLICY, TEGRA_DIVIDER_2, 4, 8, 9, NULL); - clk_register_clkdev(clk, "cclk_lp", NULL); - clks[cclk_lp] = clk; + clks[TEGRA30_CLK_CCLK_LP] = clk; /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, @@ -1378,142 +1088,44 @@ static void __init tegra30_super_clk_init(void) CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clk_register_clkdev(clk, "sclk", NULL); - clks[sclk] = clk; - - /* HCLK */ - clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, - clk_base + SYSTEM_CLK_RATE, 4, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, - clk_base + SYSTEM_CLK_RATE, 7, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "hclk", NULL); - clks[hclk] = clk; - - /* PCLK */ - clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, - clk_base + SYSTEM_CLK_RATE, 0, 2, 0, - &sysrate_lock); - clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, - clk_base + SYSTEM_CLK_RATE, 3, - CLK_GATE_SET_TO_DISABLE, &sysrate_lock); - clk_register_clkdev(clk, "pclk", NULL); - clks[pclk] = clk; + clks[TEGRA30_CLK_SCLK] = clk; /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "twd", NULL); - clks[twd] = clk; + clks[TEGRA30_CLK_TWD] = clk; + + tegra_super_clk_gen4_init(clk_base, pmc_base, tegra30_clks, NULL); } static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", "clk_m" }; static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; -static const char *i2s0_parents[] = { "pll_a_out0", "audio0_2x", "pll_p", - "clk_m" }; -static const char *i2s1_parents[] = { "pll_a_out0", "audio1_2x", "pll_p", - "clk_m" }; -static const char *i2s2_parents[] = { "pll_a_out0", "audio2_2x", "pll_p", - "clk_m" }; -static const char *i2s3_parents[] = { "pll_a_out0", "audio3_2x", "pll_p", - "clk_m" }; -static const char *i2s4_parents[] = { "pll_a_out0", "audio4_2x", "pll_p", - "clk_m" }; static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", "clk_m" }; -static const char *spdif_in_parents[] = { "pll_p", "pll_c", "pll_m" }; -static const char *mux_pllpc_clk32k_clkm[] = { "pll_p", "pll_c", "clk_32k", - "clk_m" }; -static const char *mux_pllpc_clkm_clk32k[] = { "pll_p", "pll_c", "clk_m", - "clk_32k" }; static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; -static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", - "clk_m" }; -static const char *mux_pllp_clkm[] = { "pll_p", "unused", "unused", "clk_m" }; static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", "pll_d2_out0", "clk_m" }; -static const char *mux_plla_clk32k_pllp_clkm_plle[] = { "pll_a_out0", - "clk_32k", "pll_p", - "clk_m", "pll_e" }; static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", "pll_d2_out0" }; +static const char *pwm_parents[] = { "pll_p", "pll_c", "clk_32k", "clk_m" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { - TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), - TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), - TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), - TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), - TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), - TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), - TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), - TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, 0, d_audio), - TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, &periph_v_regs, 0, dam0), - TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, &periph_v_regs, 0, dam1), - TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, &periph_v_regs, 0, dam2), - TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, 0, hda), - TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, 0, hda2codec_2x), - TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), - TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), - TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), - TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), - TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), - TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), - TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata_oob), - TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata), - TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, TEGRA_PERIPH_ON_APB, ndflash), - TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), - TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), - TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite), - TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), - TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), - TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), - TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), - TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), - TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), - TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), - TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), - TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), - TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), - TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), - TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, &periph_v_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d2), - TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), - TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, 0, se), - TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect), - TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), - TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), - TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), - TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), - TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), - TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), - TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), - TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), - TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), - TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), - TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), - TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), - TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), - TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2c4), - TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c5), - TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), - TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), - TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), - TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), - TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte), - TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), - TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), - TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), - TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), - TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, 0, pwm), + TEGRA_INIT_DATA_MUX("spdif_out", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_SPDIF_OUT), + TEGRA_INIT_DATA_MUX("d_audio", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, 0, TEGRA30_CLK_D_AUDIO), + TEGRA_INIT_DATA_MUX("dam0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, TEGRA30_CLK_DAM0), + TEGRA_INIT_DATA_MUX("dam1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, TEGRA30_CLK_DAM1), + TEGRA_INIT_DATA_MUX("dam2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, TEGRA30_CLK_DAM2), + TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, TEGRA30_CLK_GR3D2), + TEGRA_INIT_DATA_INT("se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, TEGRA30_CLK_SE), + TEGRA_INIT_DATA_MUX8("hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA30_CLK_HDMI), + TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_PWM), }; static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { - TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1), - TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2), - TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, &periph_u_regs, 0, dsib), + TEGRA_INIT_DATA_NODIV("dsib", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, TEGRA30_CLK_DSIB), }; static void __init tegra30_periph_clk_init(void) @@ -1522,170 +1134,20 @@ static void __init tegra30_periph_clk_init(void) struct clk *clk; int i; - /* apbdma */ - clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, - &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-apbdma"); - clks[apbdma] = clk; - - /* rtc */ - clk = tegra_clk_register_periph_gate("rtc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 4, &periph_l_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "rtc-tegra"); - clks[rtc] = clk; - - /* timer */ - clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, - 5, &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "timer"); - clks[timer] = clk; - - /* kbc */ - clk = tegra_clk_register_periph_gate("kbc", "clk_32k", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 36, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-kbc"); - clks[kbc] = clk; - - /* csus */ - clk = tegra_clk_register_periph_gate("csus", "clk_m", - TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, - clk_base, 0, 92, &periph_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csus", "tengra_camera"); - clks[csus] = clk; - - /* vcp */ - clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, - &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "vcp", "tegra-avp"); - clks[vcp] = clk; - - /* bsea */ - clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, - 62, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsea", "tegra-avp"); - clks[bsea] = clk; - - /* bsev */ - clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, - 63, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "bsev", "tegra-aes"); - clks[bsev] = clk; - - /* usbd */ - clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, - 22, &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); - clks[usbd] = clk; - - /* usb2 */ - clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, - 58, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.1"); - clks[usb2] = clk; - - /* usb3 */ - clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, - 59, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra-ehci.2"); - clks[usb3] = clk; - /* dsia */ clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, - 0, 48, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "dsia", "tegradc.0"); - clks[dsia] = clk; - - /* csi */ - clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, - 0, 52, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "csi", "tegra_camera"); - clks[csi] = clk; - - /* isp */ - clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, - &periph_l_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "isp", "tegra_camera"); - clks[isp] = clk; + 0, 48, periph_clk_enb_refcnt); + clks[TEGRA30_CLK_DSIA] = clk; /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, - 70, &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pcie", "tegra-pcie"); - clks[pcie] = clk; + 70, periph_clk_enb_refcnt); + clks[TEGRA30_CLK_PCIE] = clk; /* afi */ clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, - &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "afi", "tegra-pcie"); - clks[afi] = clk; - - /* pciex */ - clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, - 74, &periph_u_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "pciex", "tegra-pcie"); - clks[pciex] = clk; - - /* kfuse */ - clk = tegra_clk_register_periph_gate("kfuse", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 40, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "kfuse-tegra"); - clks[kfuse] = clk; - - /* fuse */ - clk = tegra_clk_register_periph_gate("fuse", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, &periph_h_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "fuse", "fuse-tegra"); - clks[fuse] = clk; - - /* fuse_burn */ - clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 39, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); - clks[fuse_burn] = clk; - - /* apbif */ - clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0, - clk_base, 0, 107, &periph_v_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "apbif", "tegra30-ahub"); - clks[apbif] = clk; - - /* hda2hdmi */ - clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 128, &periph_w_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); - clks[hda2hdmi] = clk; - - /* sata_cold */ - clk = tegra_clk_register_periph_gate("sata_cold", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 129, &periph_w_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "tegra_sata_cold"); - clks[sata_cold] = clk; - - /* dtv */ - clk = tegra_clk_register_periph_gate("dtv", "clk_m", - TEGRA_PERIPH_ON_APB, - clk_base, 0, 79, &periph_u_regs, - periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "dtv"); - clks[dtv] = clk; + clks[TEGRA30_CLK_AFI] = clk; /* emc */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, @@ -1694,84 +1156,37 @@ static void __init tegra30_periph_clk_init(void) clk_base + CLK_SOURCE_EMC, 30, 2, 0, NULL); clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, &periph_h_regs, periph_clk_enb_refcnt); - clk_register_clkdev(clk, "emc", NULL); - clks[emc] = clk; + 57, periph_clk_enb_refcnt); + clks[TEGRA30_CLK_EMC] = clk; + + /* cml0 */ + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, + 0, 0, &cml_lock); + clks[TEGRA30_CLK_CML0] = clk; + + /* cml1 */ + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, + 1, 0, &cml_lock); + clks[TEGRA30_CLK_CML1] = clk; for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; - clk = tegra_clk_register_periph(data->name, data->parent_names, + clk = tegra_clk_register_periph(data->name, data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset, data->flags); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { data = &tegra_periph_nodiv_clk_list[i]; clk = tegra_clk_register_periph_nodiv(data->name, - data->parent_names, + data->p.parent_names, data->num_parents, &data->periph, clk_base, data->offset); - clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } -} - -static void __init tegra30_fixed_clk_init(void) -{ - struct clk *clk; - - /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); - clk_register_clkdev(clk, "clk_32k", NULL); - clks[clk_32k] = clk; - /* clk_m_div2 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", - CLK_SET_RATE_PARENT, 1, 2); - clk_register_clkdev(clk, "clk_m_div2", NULL); - clks[clk_m_div2] = clk; - - /* clk_m_div4 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", - CLK_SET_RATE_PARENT, 1, 4); - clk_register_clkdev(clk, "clk_m_div4", NULL); - clks[clk_m_div4] = clk; - - /* cml0 */ - clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, - 0, 0, &cml_lock); - clk_register_clkdev(clk, "cml0", NULL); - clks[cml0] = clk; - - /* cml1 */ - clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, - 1, 0, &cml_lock); - clk_register_clkdev(clk, "cml1", NULL); - clks[cml1] = clk; -} - -static void __init tegra30_osc_clk_init(void) -{ - struct clk *clk; - unsigned int pll_ref_div; - - tegra30_clk_measure_input_freq(); - - /* clk_m */ - clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, - input_freq); - clk_register_clkdev(clk, "clk_m", NULL); - clks[clk_m] = clk; - - /* pll_ref */ - pll_ref_div = tegra30_get_pll_ref_div(); - clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", - CLK_SET_RATE_PARENT, 1, pll_ref_div); - clk_register_clkdev(clk, "pll_ref", NULL); - clks[pll_ref] = clk; + tegra_periph_clk_init(clk_base, pmc_base, tegra30_clks, &pll_p_params); } /* Tegra30 CPU clock and reset control functions */ @@ -1913,48 +1328,49 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {uarta, pll_p, 408000000, 0}, - {uartb, pll_p, 408000000, 0}, - {uartc, pll_p, 408000000, 0}, - {uartd, pll_p, 408000000, 0}, - {uarte, pll_p, 408000000, 0}, - {pll_a, clk_max, 564480000, 1}, - {pll_a_out0, clk_max, 11289600, 1}, - {extern1, pll_a_out0, 0, 1}, - {clk_out_1_mux, extern1, 0, 0}, - {clk_out_1, clk_max, 0, 1}, - {blink, clk_max, 0, 1}, - {i2s0, pll_a_out0, 11289600, 0}, - {i2s1, pll_a_out0, 11289600, 0}, - {i2s2, pll_a_out0, 11289600, 0}, - {i2s3, pll_a_out0, 11289600, 0}, - {i2s4, pll_a_out0, 11289600, 0}, - {sdmmc1, pll_p, 48000000, 0}, - {sdmmc2, pll_p, 48000000, 0}, - {sdmmc3, pll_p, 48000000, 0}, - {pll_m, clk_max, 0, 1}, - {pclk, clk_max, 0, 1}, - {csite, clk_max, 0, 1}, - {emc, clk_max, 0, 1}, - {mselect, clk_max, 0, 1}, - {sbc1, pll_p, 100000000, 0}, - {sbc2, pll_p, 100000000, 0}, - {sbc3, pll_p, 100000000, 0}, - {sbc4, pll_p, 100000000, 0}, - {sbc5, pll_p, 100000000, 0}, - {sbc6, pll_p, 100000000, 0}, - {host1x, pll_c, 150000000, 0}, - {disp1, pll_p, 600000000, 0}, - {disp2, pll_p, 600000000, 0}, - {twd, clk_max, 0, 1}, - {gr2d, pll_c, 300000000, 0}, - {gr3d, pll_c, 300000000, 0}, - {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ + {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 408000000, 0}, + {TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1}, + {TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1}, + {TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1}, + {TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0}, + {TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S3, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_I2S4, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, + {TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0}, + {TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC3, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0}, + {TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0}, + {TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0}, + {TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0}, + {TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1}, + {TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0}, + {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ }; static void __init tegra30_clock_apply_init_table(void) { - tegra_init_from_table(init_table, clks, clk_max); + tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); } /* @@ -1963,19 +1379,18 @@ static void __init tegra30_clock_apply_init_table(void) * table under two names. */ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { - TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), - TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), - TEGRA_CLK_DUPLICATE(bsev, "tegra-avp", "bsev"), - TEGRA_CLK_DUPLICATE(bsev, "nvavp", "bsev"), - TEGRA_CLK_DUPLICATE(vde, "tegra-aes", "vde"), - TEGRA_CLK_DUPLICATE(bsea, "tegra-aes", "bsea"), - TEGRA_CLK_DUPLICATE(bsea, "nvavp", "bsea"), - TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), - TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), - TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), - TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), - TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "utmip-pad", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-ehci.0", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-otg", NULL), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "tegra-avp", "bsev"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "nvavp", "bsev"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VDE, "tegra-aes", "vde"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "tegra-aes", "bsea"), + 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_VCP, "nvavp", "vcp"), + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ }; static const struct of_device_id pmc_match[] __initconst = { @@ -1986,7 +1401,6 @@ static const struct of_device_id pmc_match[] __initconst = { static void __init tegra30_clock_init(struct device_node *np) { struct device_node *node; - int i; clk_base = of_iomap(np, 0); if (!clk_base) { @@ -2006,29 +1420,27 @@ static void __init tegra30_clock_init(struct device_node *np) BUG(); } - tegra30_osc_clk_init(); - tegra30_fixed_clk_init(); + clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX, + TEGRA30_CLK_PERIPH_BANKS); + if (!clks) + return; + + if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq, + ARRAY_SIZE(tegra30_input_freq), &input_freq, NULL) < 0) + return; + + + tegra_fixed_clk_init(tegra30_clks); tegra30_pll_init(); tegra30_super_clk_init(); tegra30_periph_clk_init(); - tegra30_audio_clk_init(); - tegra30_pmc_clk_init(); - - for (i = 0; i < ARRAY_SIZE(clks); i++) { - if (IS_ERR(clks[i])) { - pr_err("Tegra30 clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); - BUG(); - } - if (!clks[i]) - clks[i] = ERR_PTR(-EINVAL); - } + tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params); + tegra_pmc_clk_init(pmc_base, tegra30_clks); - tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); + tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra30_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 86581ac..c0a7d77 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -18,13 +18,175 @@ #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" +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_X 0x280 +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_H 0x328 +#define CLK_OUT_ENB_CLR_H 0x32c +#define CLK_OUT_ENB_SET_U 0x330 +#define CLK_OUT_ENB_CLR_U 0x334 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_SET_W 0x448 +#define CLK_OUT_ENB_CLR_W 0x44c +#define CLK_OUT_ENB_SET_X 0x284 +#define CLK_OUT_ENB_CLR_X 0x288 + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DFLL_DVCO 0x2F4 +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_X 0x28C +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_H 0x308 +#define RST_DEVICES_CLR_H 0x30c +#define RST_DEVICES_SET_U 0x310 +#define RST_DEVICES_CLR_U 0x314 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_SET_W 0x438 +#define RST_DEVICES_CLR_W 0x43c +#define RST_DEVICES_SET_X 0x290 +#define RST_DEVICES_CLR_X 0x294 + /* Global data of Tegra CPU CAR ops */ static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; +int *periph_clk_enb_refcnt; +static int periph_banks; +static struct clk **clks; +static int clk_num; +static struct clk_onecell_data clk_data; + +static struct tegra_clk_periph_regs periph_regs[] = { + [0] = { + .enb_reg = CLK_OUT_ENB_L, + .enb_set_reg = CLK_OUT_ENB_SET_L, + .enb_clr_reg = CLK_OUT_ENB_CLR_L, + .rst_reg = RST_DEVICES_L, + .rst_set_reg = RST_DEVICES_SET_L, + .rst_clr_reg = RST_DEVICES_CLR_L, + }, + [1] = { + .enb_reg = CLK_OUT_ENB_H, + .enb_set_reg = CLK_OUT_ENB_SET_H, + .enb_clr_reg = CLK_OUT_ENB_CLR_H, + .rst_reg = RST_DEVICES_H, + .rst_set_reg = RST_DEVICES_SET_H, + .rst_clr_reg = RST_DEVICES_CLR_H, + }, + [2] = { + .enb_reg = CLK_OUT_ENB_U, + .enb_set_reg = CLK_OUT_ENB_SET_U, + .enb_clr_reg = CLK_OUT_ENB_CLR_U, + .rst_reg = RST_DEVICES_U, + .rst_set_reg = RST_DEVICES_SET_U, + .rst_clr_reg = RST_DEVICES_CLR_U, + }, + [3] = { + .enb_reg = CLK_OUT_ENB_V, + .enb_set_reg = CLK_OUT_ENB_SET_V, + .enb_clr_reg = CLK_OUT_ENB_CLR_V, + .rst_reg = RST_DEVICES_V, + .rst_set_reg = RST_DEVICES_SET_V, + .rst_clr_reg = RST_DEVICES_CLR_V, + }, + [4] = { + .enb_reg = CLK_OUT_ENB_W, + .enb_set_reg = CLK_OUT_ENB_SET_W, + .enb_clr_reg = CLK_OUT_ENB_CLR_W, + .rst_reg = RST_DEVICES_W, + .rst_set_reg = RST_DEVICES_SET_W, + .rst_clr_reg = RST_DEVICES_CLR_W, + }, + [5] = { + .enb_reg = CLK_OUT_ENB_X, + .enb_set_reg = CLK_OUT_ENB_SET_X, + .enb_clr_reg = CLK_OUT_ENB_CLR_X, + .rst_reg = RST_DEVICES_X, + .rst_set_reg = RST_DEVICES_SET_X, + .rst_clr_reg = RST_DEVICES_CLR_X, + }, +}; + +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; + + if (reg_bank < periph_banks) + return &periph_regs[reg_bank]; + else { + WARN_ON(1); + return NULL; + } +} + +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; + + periph_clk_enb_refcnt = kzalloc(32 * banks * + sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); + if (!periph_clk_enb_refcnt) + return NULL; + + periph_banks = banks; + + clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL); + if (!clks) + kfree(periph_clk_enb_refcnt); + + clk_num = num; + + return clks; +} + void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, struct clk *clks[], int clk_max) { @@ -74,6 +236,58 @@ 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; + + for (i = 0; i < clk_num; i++) { + if (IS_ERR(clks[i])) { + pr_err + ("Tegra clk %d: register failed with %ld\n", + i, PTR_ERR(clks[i])); + } + if (!clks[i]) + clks[i] = ERR_PTR(-EINVAL); + } + + 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) +{ + int i; + + for (i = 0; i < num; i++, dev_clks++) + clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id, + dev_clks->dev_id); +} + +struct clk ** __init tegra_lookup_dt_id(int clk_id, + struct tegra_clk *tegra_clk) +{ + if (tegra_clk[clk_id].present) + return &clks[tegra_clk[clk_id].dt_id]; + else + return NULL; +} + tegra_clk_apply_init_table_func tegra_clk_apply_init_table; void __init tegra_clocks_apply_init_table(void) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 07cfacd..16ec8d6 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -37,6 +37,8 @@ struct tegra_clk_sync_source { container_of(_hw, struct tegra_clk_sync_source, hw) extern const struct clk_ops tegra_clk_sync_source_ops; +extern int *periph_clk_enb_refcnt; + struct clk *tegra_clk_register_sync_source(const char *name, unsigned long fixed_rate, unsigned long max_rate); @@ -188,12 +190,15 @@ struct tegra_clk_pll_params { u32 ext_misc_reg[3]; u32 pmc_divnm_reg; u32 pmc_divp_reg; + u32 flags; int stepa_shift; int stepb_shift; int lock_delay; int max_p; struct pdiv_map *pdiv_tohw; struct div_nmp *div_nmp; + struct tegra_clk_pll_freq_table *freq_table; + unsigned long fixed_rate; }; /** @@ -233,10 +238,7 @@ struct tegra_clk_pll { struct clk_hw hw; void __iomem *clk_base; void __iomem *pmc; - u32 flags; - unsigned long fixed_rate; spinlock_t *lock; - struct tegra_clk_pll_freq_table *freq_table; struct tegra_clk_pll_params *params; }; @@ -258,56 +260,49 @@ extern const struct clk_ops tegra_clk_pll_ops; extern const struct clk_ops tegra_clk_plle_ops; struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); + unsigned long flags, struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, - unsigned long flags, unsigned long fixed_rate, + unsigned long flags, struct tegra_clk_pll_params *pll_params, - u32 pll_flags, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock, unsigned long parent_rate); struct clk *tegra_clk_register_plle_tegra114(const char *name, const char *parent_name, void __iomem *clk_base, unsigned long flags, - unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, - struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); +struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + /** * struct tegra_clk_pll_out - PLL divider down clock * @@ -395,13 +390,13 @@ struct tegra_clk_periph_gate { #define TEGRA_PERIPH_MANUAL_RESET BIT(1) #define TEGRA_PERIPH_ON_APB BIT(2) #define TEGRA_PERIPH_WAR_1005168 BIT(3) +#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, - unsigned long flags, int clk_num, - struct tegra_clk_periph_regs *pregs, int *enable_refcnt); + unsigned long flags, int clk_num, int *enable_refcnt); /** * struct clk-periph - peripheral clock @@ -443,26 +438,26 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ _div_shift, _div_width, _div_frac_width, \ - _div_flags, _clk_num, _enb_refcnt, _regs, \ - _gate_flags, _table) \ + _div_flags, _clk_num,\ + _gate_flags, _table, _lock) \ { \ .mux = { \ .flags = _mux_flags, \ .shift = _mux_shift, \ .mask = _mux_mask, \ .table = _table, \ + .lock = _lock, \ }, \ .divider = { \ .flags = _div_flags, \ .shift = _div_shift, \ .width = _div_width, \ .frac_width = _div_frac_width, \ + .lock = _lock, \ }, \ .gate = { \ .flags = _gate_flags, \ .clk_num = _clk_num, \ - .enable_refcnt = _enb_refcnt, \ - .regs = _regs, \ }, \ .mux_ops = &clk_mux_ops, \ .div_ops = &tegra_clk_frac_div_ops, \ @@ -472,7 +467,10 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, struct tegra_periph_init_data { const char *name; int clk_id; - const char **parent_names; + union { + const char **parent_names; + const char *parent_name; + } p; int num_parents; struct tegra_clk_periph periph; u32 offset; @@ -483,20 +481,19 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_mask, _mux_flags, _div_shift, \ - _div_width, _div_frac_width, _div_flags, _regs, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ - _flags) \ + _div_width, _div_frac_width, _div_flags, \ + _clk_num, _gate_flags, _clk_id, _table, \ + _flags, _lock) \ { \ .name = _name, \ .clk_id = _clk_id, \ - .parent_names = _parent_names, \ + .p.parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \ _mux_flags, _div_shift, \ _div_width, _div_frac_width, \ _div_flags, _clk_num, \ - _enb_refcnt, _regs, \ - _gate_flags, _table), \ + _gate_flags, _table, _lock), \ .offset = _offset, \ .con_id = _con_id, \ .dev_id = _dev_id, \ @@ -505,13 +502,13 @@ struct tegra_periph_init_data { #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_width, _mux_flags, _div_shift, \ - _div_width, _div_frac_width, _div_flags, _regs, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ + _div_width, _div_frac_width, _div_flags, \ + _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \ - _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ - NULL, 0) + _clk_num, _gate_flags, _clk_id,\ + NULL, 0, NULL) /** * struct clk_super_mux - super clock @@ -581,12 +578,49 @@ struct tegra_clk_duplicate { }, \ } +struct tegra_clk { + int dt_id; + bool present; +}; + +struct tegra_devclk { + int dt_id; + char *dev_id; + char *con_id; +}; + void tegra_init_from_table(struct tegra_clk_init_table *tbl, struct clk *clks[], int clk_max); 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(void __iomem *clk_base, int num, int periph_banks); + +struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); + +void tegra_add_of_provider(struct device_node *np); +void tegra_register_devclks(struct tegra_devclk *dev_clks, int num); + +void tegra_audio_clk_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); + +void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); + +void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks); +void tegra_fixed_clk_init(struct tegra_clk *tegra_clks); +int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks, + unsigned long *input_freqs, int num, + unsigned long *osc_freq, + unsigned long *pll_ref_freq); +void tegra_super_clk_gen4_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); + void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ea806bd..24095ff 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -535,11 +535,41 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan) } EXPORT_SYMBOL_GPL(dma_get_slave_channel); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) +{ + dma_cap_mask_t mask; + struct dma_chan *chan; + int err; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* lock against __dma_request_channel */ + mutex_lock(&dma_list_mutex); + + chan = private_candidate(&mask, device, NULL, NULL); + if (chan) { + err = dma_chan_get(chan); + if (err) { + pr_debug("%s: failed to get %s: (%d)\n", + __func__, dma_chan_name(chan), err); + chan = NULL; + } + } + + mutex_unlock(&dma_list_mutex); + + return chan; +} +EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); + /** * __dma_request_channel - try to allocate an exclusive channel * @mask: capabilities that the channel must satisfy * @fn: optional callback to disposition available channels * @fn_param: opaque parameter to pass to dma_filter_fn + * + * Returns pointer to appropriate DMA channel on success or NULL. */ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param) @@ -591,18 +621,43 @@ EXPORT_SYMBOL_GPL(__dma_request_channel); * dma_request_slave_channel - try to allocate an exclusive slave channel * @dev: pointer to client device structure * @name: slave channel name + * + * Returns pointer to appropriate DMA channel on success or an error pointer. */ -struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) +struct dma_chan *dma_request_slave_channel_reason(struct device *dev, + const char *name) { + struct dma_chan *chan; + /* If device-tree is present get slave info from here */ if (dev->of_node) return of_dma_request_slave_channel(dev->of_node, name); /* If device was enumerated by ACPI get slave info from here */ - if (ACPI_HANDLE(dev)) - return acpi_dma_request_slave_chan_by_name(dev, name); + if (ACPI_HANDLE(dev)) { + chan = acpi_dma_request_slave_chan_by_name(dev, name); + if (chan) + return chan; + } - return NULL; + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason); + +/** + * dma_request_slave_channel - try to allocate an exclusive slave channel + * @dev: pointer to client device structure + * @name: slave channel name + * + * Returns pointer to appropriate DMA channel on success or NULL. + */ +struct dma_chan *dma_request_slave_channel(struct device *dev, + const char *name) +{ + struct dma_chan *ch = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(ch)) + return NULL; + return ch; } EXPORT_SYMBOL_GPL(dma_request_slave_channel); diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index 8869500..c6a01ea 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -893,33 +893,17 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { struct mmp_pdma_device *d = ofdma->of_dma_data; - struct dma_chan *chan, *candidate; + struct dma_chan *chan; + struct mmp_pdma_chan *c; -retry: - candidate = NULL; - - /* walk the list of channels registered with the current instance and - * find one that is currently unused */ - list_for_each_entry(chan, &d->device.channels, device_node) - if (chan->client_count == 0) { - candidate = chan; - break; - } - - if (!candidate) + chan = dma_get_any_slave_channel(&d->device); + if (!chan) return NULL; - /* dma_get_slave_channel will return NULL if we lost a race between - * the lookup and the reservation */ - chan = dma_get_slave_channel(candidate); - - if (chan) { - struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan); - c->drcmr = dma_spec->args[0]; - return chan; - } + c = to_mmp_pdma_chan(chan); + c->drcmr = dma_spec->args[0]; - goto retry; + return chan; } static int mmp_pdma_probe(struct platform_device *op) diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index 0b88dd3..e8fe9dc 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -143,7 +143,7 @@ static int of_dma_match_channel(struct device_node *np, const char *name, * @np: device node to get DMA request from * @name: name of desired channel * - * Returns pointer to appropriate dma channel on success or NULL on error. + * Returns pointer to appropriate DMA channel on success or an error pointer. */ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name) @@ -152,17 +152,18 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, struct of_dma *ofdma; struct dma_chan *chan; int count, i; + int ret_no_channel = -ENODEV; if (!np || !name) { pr_err("%s: not enough information provided\n", __func__); - return NULL; + return ERR_PTR(-ENODEV); } count = of_property_count_strings(np, "dma-names"); if (count < 0) { pr_err("%s: dma-names property of node '%s' missing or empty\n", __func__, np->full_name); - return NULL; + return ERR_PTR(-ENODEV); } for (i = 0; i < count; i++) { @@ -172,10 +173,12 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, mutex_lock(&of_dma_lock); ofdma = of_dma_find_controller(&dma_spec); - if (ofdma) + if (ofdma) { chan = ofdma->of_dma_xlate(&dma_spec, ofdma); - else + } else { + ret_no_channel = -EPROBE_DEFER; chan = NULL; + } mutex_unlock(&of_dma_lock); @@ -185,7 +188,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, return chan; } - return NULL; + return ERR_PTR(ret_no_channel); } /** diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 73654e3..d11bb36 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1,7 +1,7 @@ /* * 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]; diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 8961ba6..8db9b3b 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -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 diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index ae1cb31..cd7f1e4 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -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; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 7da0b92..266aae0 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -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; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 4cec8f5..0cbb24b 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -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"); diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 0cd9bc2..7f6253e 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -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; diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index e661ede..9704537 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -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) diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879..9757a58 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -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 diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0afbbbc..0175041 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -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); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index eb1f1ef..9fc66e8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -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. diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index aaecfb3..c860498 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -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); diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 4dc8e81..e6f382b 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -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); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index e66715b..a728bb8 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -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); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 49ea76b..986870593 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -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; diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index e880518..e271375 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -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; diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index dfe79cc..d5c2a28 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -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; diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index b9fd039..6f7e23d 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -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)) { diff --git a/include/dt-bindings/clock/tegra114-car.h b/include/dt-bindings/clock/tegra114-car.h index 614aec4..6d0d8d8 100644 --- a/include/dt-bindings/clock/tegra114-car.h +++ b/include/dt-bindings/clock/tegra114-car.h @@ -37,10 +37,10 @@ #define TEGRA114_CLK_I2S2 18 #define TEGRA114_CLK_EPP 19 /* 20 (register bit affects vi and vi_sensor) */ -#define TEGRA114_CLK_GR_2D 21 +#define TEGRA114_CLK_GR2D 21 #define TEGRA114_CLK_USBD 22 #define TEGRA114_CLK_ISP 23 -#define TEGRA114_CLK_GR_3D 24 +#define TEGRA114_CLK_GR3D 24 /* 25 */ #define TEGRA114_CLK_DISP2 26 #define TEGRA114_CLK_DISP1 27 @@ -289,8 +289,8 @@ #define TEGRA114_CLK_PCLK 261 #define TEGRA114_CLK_CCLK_G 262 #define TEGRA114_CLK_CCLK_LP 263 -/* 264 */ -/* 265 */ +#define TEGRA114_CLK_DFLL_REF 264 +#define TEGRA114_CLK_DFLL_SOC 265 /* 266 */ /* 267 */ /* 268 */ diff --git a/include/dt-bindings/clock/tegra124-car.h b/include/dt-bindings/clock/tegra124-car.h new file mode 100644 index 0000000..a1116a3 --- /dev/null +++ b/include/dt-bindings/clock/tegra124-car.h @@ -0,0 +1,341 @@ +/* + * This header provides constants for binding nvidia,tegra124-car. + * + * The first 192 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + * registers. These IDs often match those in the CAR's RST_DEVICES registers, + * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + * this case, those clocks are assigned IDs above 185 in order to highlight + * this issue. Implementations that interpret these clock IDs as bit values + * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + * explicitly handle these special cases. + * + * The balance of the clocks controlled by the CAR are assigned IDs of 185 and + * above. + */ + +#ifndef _DT_BINDINGS_CLOCK_TEGRA124_CAR_H +#define _DT_BINDINGS_CLOCK_TEGRA124_CAR_H + +/* 0 */ +/* 1 */ +/* 2 */ +#define TEGRA124_CLK_ISPB 3 +#define TEGRA124_CLK_RTC 4 +#define TEGRA124_CLK_TIMER 5 +#define TEGRA124_CLK_UARTA 6 +/* 7 (register bit affects uartb and vfir) */ +/* 8 */ +#define TEGRA124_CLK_SDMMC2 9 +/* 10 (register bit affects spdif_in and spdif_out) */ +#define TEGRA124_CLK_I2S1 11 +#define TEGRA124_CLK_I2C1 12 +#define TEGRA124_CLK_NDFLASH 13 +#define TEGRA124_CLK_SDMMC1 14 +#define TEGRA124_CLK_SDMMC4 15 +/* 16 */ +#define TEGRA124_CLK_PWM 17 +#define TEGRA124_CLK_I2S2 18 +/* 20 (register bit affects vi and vi_sensor) */ +#define TEGRA124_CLK_GR_2D 21 +#define TEGRA124_CLK_USBD 22 +#define TEGRA124_CLK_ISP 23 +#define TEGRA124_CLK_GR_3D 24 +/* 25 */ +#define TEGRA124_CLK_DISP2 26 +#define TEGRA124_CLK_DISP1 27 +#define TEGRA124_CLK_HOST1X 28 +#define TEGRA124_CLK_VCP 29 +#define TEGRA124_CLK_I2S0 30 +/* 31 */ + +/* 32 */ +/* 33 */ +#define TEGRA124_CLK_APBDMA 34 +/* 35 */ +#define TEGRA124_CLK_KBC 36 +/* 37 */ +/* 38 */ +/* 39 (register bit affects fuse and fuse_burn) */ +#define TEGRA124_CLK_KFUSE 40 +#define TEGRA124_CLK_SBC1 41 +#define TEGRA124_CLK_NOR 42 +/* 43 */ +#define TEGRA124_CLK_SBC2 44 +/* 45 */ +#define TEGRA124_CLK_SBC3 46 +#define TEGRA124_CLK_I2C5 47 +#define TEGRA124_CLK_DSIA 48 +/* 49 */ +#define TEGRA124_CLK_MIPI 50 +#define TEGRA124_CLK_HDMI 51 +#define TEGRA124_CLK_CSI 52 +/* 53 */ +#define TEGRA124_CLK_I2C2 54 +#define TEGRA124_CLK_UARTC 55 +#define TEGRA124_CLK_MIPI_CAL 56 +#define TEGRA124_CLK_EMC 57 +#define TEGRA124_CLK_USB2 58 +#define TEGRA124_CLK_USB3 59 +/* 60 */ +#define TEGRA124_CLK_VDE 61 +#define TEGRA124_CLK_BSEA 62 +#define TEGRA124_CLK_BSEV 63 + +/* 64 */ +#define TEGRA124_CLK_UARTD 65 +#define TEGRA124_CLK_UARTE 66 +#define TEGRA124_CLK_I2C3 67 +#define TEGRA124_CLK_SBC4 68 +#define TEGRA124_CLK_SDMMC3 69 +#define TEGRA124_CLK_PCIE 70 +#define TEGRA124_CLK_OWR 71 +#define TEGRA124_CLK_AFI 72 +#define TEGRA124_CLK_CSITE 73 +/* 74 */ +/* 75 */ +#define TEGRA124_CLK_LA 76 +#define TEGRA124_CLK_TRACE 77 +#define TEGRA124_CLK_SOC_THERM 78 +#define TEGRA124_CLK_DTV 79 +#define TEGRA124_CLK_NDSPEED 80 +#define TEGRA124_CLK_I2CSLOW 81 +#define TEGRA124_CLK_DSIB 82 +#define TEGRA124_CLK_TSEC 83 +/* 84 */ +/* 85 */ +/* 86 */ +/* 87 */ +/* 88 */ +#define TEGRA124_CLK_XUSB_HOST 89 +/* 90 */ +#define TEGRA124_CLK_MSENC 91 +#define TEGRA124_CLK_CSUS 92 +/* 93 */ +/* 94 */ +/* 95 (bit affects xusb_dev and xusb_dev_src) */ + +/* 96 */ +/* 97 */ +/* 98 */ +#define TEGRA124_CLK_MSELECT 99 +#define TEGRA124_CLK_TSENSOR 100 +#define TEGRA124_CLK_I2S3 101 +#define TEGRA124_CLK_I2S4 102 +#define TEGRA124_CLK_I2C4 103 +#define TEGRA124_CLK_SBC5 104 +#define TEGRA124_CLK_SBC6 105 +#define TEGRA124_CLK_D_AUDIO 106 +#define TEGRA124_CLK_APBIF 107 +#define TEGRA124_CLK_DAM0 108 +#define TEGRA124_CLK_DAM1 109 +#define TEGRA124_CLK_DAM2 110 +#define TEGRA124_CLK_HDA2CODEC_2X 111 +/* 112 */ +#define TEGRA124_CLK_AUDIO0_2X 113 +#define TEGRA124_CLK_AUDIO1_2X 114 +#define TEGRA124_CLK_AUDIO2_2X 115 +#define TEGRA124_CLK_AUDIO3_2X 116 +#define TEGRA124_CLK_AUDIO4_2X 117 +#define TEGRA124_CLK_SPDIF_2X 118 +#define TEGRA124_CLK_ACTMON 119 +#define TEGRA124_CLK_EXTERN1 120 +#define TEGRA124_CLK_EXTERN2 121 +#define TEGRA124_CLK_EXTERN3 122 +#define TEGRA124_CLK_SATA_OOB 123 +#define TEGRA124_CLK_SATA 124 +#define TEGRA124_CLK_HDA 125 +/* 126 */ +#define TEGRA124_CLK_SE 127 + +#define TEGRA124_CLK_HDA2HDMI 128 +#define TEGRA124_CLK_SATA_COLD 129 +/* 130 */ +/* 131 */ +/* 132 */ +/* 133 */ +/* 134 */ +/* 135 */ +/* 136 */ +/* 137 */ +/* 138 */ +/* 139 */ +/* 140 */ +/* 141 */ +/* 142 */ +/* 143 (bit affects xusb_falcon_src, xusb_fs_src, */ +/* xusb_host_src and xusb_ss_src) */ +#define TEGRA124_CLK_CILAB 144 +#define TEGRA124_CLK_CILCD 145 +#define TEGRA124_CLK_CILE 146 +#define TEGRA124_CLK_DSIALP 147 +#define TEGRA124_CLK_DSIBLP 148 +#define TEGRA124_CLK_ENTROPY 149 +#define TEGRA124_CLK_DDS 150 +/* 151 */ +#define TEGRA124_CLK_DP2 152 +#define TEGRA124_CLK_AMX 153 +#define TEGRA124_CLK_ADX 154 +/* 155 (bit affects dfll_ref and dfll_soc) */ +#define TEGRA124_CLK_XUSB_SS 156 +/* 157 */ +/* 158 */ +/* 159 */ + +/* 160 */ +/* 161 */ +/* 162 */ +/* 163 */ +/* 164 */ +/* 165 */ +#define TEGRA124_CLK_I2C6 166 +/* 167 */ +/* 168 */ +/* 169 */ +/* 170 */ +#define TEGRA124_CLK_VIM2_CLK 171 +/* 172 */ +/* 173 */ +/* 174 */ +/* 175 */ +#define TEGRA124_CLK_HDMI_AUDIO 176 +#define TEGRA124_CLK_CLK72MHZ 177 +#define TEGRA124_CLK_VIC03 178 +/* 179 */ +#define TEGRA124_CLK_ADX1 180 +#define TEGRA124_CLK_DPAUX 181 +#define TEGRA124_CLK_SOR0 182 +/* 183 */ +#define TEGRA124_CLK_GPU 184 +#define TEGRA124_CLK_AMX1 185 +/* 186 */ +/* 187 */ +/* 188 */ +/* 189 */ +/* 190 */ +/* 191 */ +#define TEGRA124_CLK_UARTB 192 +#define TEGRA124_CLK_VFIR 193 +#define TEGRA124_CLK_SPDIF_IN 194 +#define TEGRA124_CLK_SPDIF_OUT 195 +#define TEGRA124_CLK_VI 196 +#define TEGRA124_CLK_VI_SENSOR 197 +#define TEGRA124_CLK_FUSE 198 +#define TEGRA124_CLK_FUSE_BURN 199 +#define TEGRA124_CLK_CLK_32K 200 +#define TEGRA124_CLK_CLK_M 201 +#define TEGRA124_CLK_CLK_M_DIV2 202 +#define TEGRA124_CLK_CLK_M_DIV4 203 +#define TEGRA124_CLK_PLL_REF 204 +#define TEGRA124_CLK_PLL_C 205 +#define TEGRA124_CLK_PLL_C_OUT1 206 +#define TEGRA124_CLK_PLL_C2 207 +#define TEGRA124_CLK_PLL_C3 208 +#define TEGRA124_CLK_PLL_M 209 +#define TEGRA124_CLK_PLL_M_OUT1 210 +#define TEGRA124_CLK_PLL_P 211 +#define TEGRA124_CLK_PLL_P_OUT1 212 +#define TEGRA124_CLK_PLL_P_OUT2 213 +#define TEGRA124_CLK_PLL_P_OUT3 214 +#define TEGRA124_CLK_PLL_P_OUT4 215 +#define TEGRA124_CLK_PLL_A 216 +#define TEGRA124_CLK_PLL_A_OUT0 217 +#define TEGRA124_CLK_PLL_D 218 +#define TEGRA124_CLK_PLL_D_OUT0 219 +#define TEGRA124_CLK_PLL_D2 220 +#define TEGRA124_CLK_PLL_D2_OUT0 221 +#define TEGRA124_CLK_PLL_U 222 +#define TEGRA124_CLK_PLL_U_480M 223 + +#define TEGRA124_CLK_PLL_U_60M 224 +#define TEGRA124_CLK_PLL_U_48M 225 +#define TEGRA124_CLK_PLL_U_12M 226 +#define TEGRA124_CLK_PLL_X 227 +#define TEGRA124_CLK_PLL_X_OUT0 228 +#define TEGRA124_CLK_PLL_RE_VCO 229 +#define TEGRA124_CLK_PLL_RE_OUT 230 +#define TEGRA124_CLK_PLL_E 231 +#define TEGRA124_CLK_SPDIF_IN_SYNC 232 +#define TEGRA124_CLK_I2S0_SYNC 233 +#define TEGRA124_CLK_I2S1_SYNC 234 +#define TEGRA124_CLK_I2S2_SYNC 235 +#define TEGRA124_CLK_I2S3_SYNC 236 +#define TEGRA124_CLK_I2S4_SYNC 237 +#define TEGRA124_CLK_VIMCLK_SYNC 238 +#define TEGRA124_CLK_AUDIO0 239 +#define TEGRA124_CLK_AUDIO1 240 +#define TEGRA124_CLK_AUDIO2 241 +#define TEGRA124_CLK_AUDIO3 242 +#define TEGRA124_CLK_AUDIO4 243 +#define TEGRA124_CLK_SPDIF 244 +#define TEGRA124_CLK_CLK_OUT_1 245 +#define TEGRA124_CLK_CLK_OUT_2 246 +#define TEGRA124_CLK_CLK_OUT_3 247 +#define TEGRA124_CLK_BLINK 248 +/* 249 */ +/* 250 */ +/* 251 */ +#define TEGRA124_CLK_XUSB_HOST_SRC 252 +#define TEGRA124_CLK_XUSB_FALCON_SRC 253 +#define TEGRA124_CLK_XUSB_FS_SRC 254 +#define TEGRA124_CLK_XUSB_SS_SRC 255 + +#define TEGRA124_CLK_XUSB_DEV_SRC 256 +#define TEGRA124_CLK_XUSB_DEV 257 +#define TEGRA124_CLK_XUSB_HS_SRC 258 +#define TEGRA124_CLK_SCLK 259 +#define TEGRA124_CLK_HCLK 260 +#define TEGRA124_CLK_PCLK 261 +#define TEGRA124_CLK_CCLK_G 262 +#define TEGRA124_CLK_CCLK_LP 263 +#define TEGRA124_CLK_DFLL_REF 264 +#define TEGRA124_CLK_DFLL_SOC 265 +#define TEGRA124_CLK_VI_SENSOR2 266 +#define TEGRA124_CLK_PLL_P_OUT5 267 +#define TEGRA124_CLK_CML0 268 +#define TEGRA124_CLK_CML1 269 +#define TEGRA124_CLK_PLL_C4 270 +#define TEGRA124_CLK_PLL_DP 271 +#define TEGRA124_CLK_PLL_E_MUX 272 +/* 273 */ +/* 274 */ +/* 275 */ +/* 276 */ +/* 277 */ +/* 278 */ +/* 279 */ +/* 280 */ +/* 281 */ +/* 282 */ +/* 283 */ +/* 284 */ +/* 285 */ +/* 286 */ +/* 287 */ + +/* 288 */ +/* 289 */ +/* 290 */ +/* 291 */ +/* 292 */ +/* 293 */ +/* 294 */ +/* 295 */ +/* 296 */ +/* 297 */ +/* 298 */ +/* 299 */ +#define TEGRA124_CLK_AUDIO0_MUX 300 +#define TEGRA124_CLK_AUDIO1_MUX 301 +#define TEGRA124_CLK_AUDIO2_MUX 302 +#define TEGRA124_CLK_AUDIO3_MUX 303 +#define TEGRA124_CLK_AUDIO4_MUX 304 +#define TEGRA124_CLK_SPDIF_MUX 305 +#define TEGRA124_CLK_CLK_OUT_1_MUX 306 +#define TEGRA124_CLK_CLK_OUT_2_MUX 307 +#define TEGRA124_CLK_CLK_OUT_3_MUX 308 +#define TEGRA124_CLK_DSIA_MUX 309 +#define TEGRA124_CLK_DSIB_MUX 310 +#define TEGRA124_CLK_SOR0_LVDS 311 +#define TEGRA124_CLK_CLK_MAX 312 + +#endif /* _DT_BINDINGS_CLOCK_TEGRA124_CAR_H */ diff --git a/include/dt-bindings/clock/tegra20-car.h b/include/dt-bindings/clock/tegra20-car.h index a1ae9a8..9406207 100644 --- a/include/dt-bindings/clock/tegra20-car.h +++ b/include/dt-bindings/clock/tegra20-car.h @@ -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 */ diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h index e40fae8..889e49b 100644 --- a/include/dt-bindings/clock/tegra30-car.h +++ b/include/dt-bindings/clock/tegra30-car.h @@ -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 */ @@ -260,6 +260,14 @@ /* 298 */ /* 299 */ #define TEGRA30_CLK_CLK_OUT_1_MUX 300 -#define TEGRA30_CLK_CLK_MAX 301 +#define TEGRA30_CLK_CLK_OUT_2_MUX 301 +#define TEGRA30_CLK_CLK_OUT_3_MUX 302 +#define TEGRA30_CLK_AUDIO0_MUX 303 +#define TEGRA30_CLK_AUDIO1_MUX 304 +#define TEGRA30_CLK_AUDIO2_MUX 305 +#define TEGRA30_CLK_AUDIO3_MUX 306 +#define TEGRA30_CLK_AUDIO4_MUX 307 +#define TEGRA30_CLK_SPDIF_MUX 308 +#define TEGRA30_CLK_CLK_MAX 309 #endif /* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */ diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 23a0cee..3ca9fca 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -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_ */ diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 41cf0c3..bae1568 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -22,6 +22,7 @@ #define LINUX_DMAENGINE_H #include <linux/device.h> +#include <linux/err.h> #include <linux/uio.h> #include <linux/bug.h> #include <linux/scatterlist.h> @@ -1040,6 +1041,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); +struct dma_chan *dma_request_slave_channel_reason(struct device *dev, + const char *name); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); void dma_release_channel(struct dma_chan *chan); #else @@ -1063,6 +1066,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, { return NULL; } +static inline struct dma_chan *dma_request_slave_channel_reason( + struct device *dev, const char *name) +{ + return ERR_PTR(-ENODEV); +} static inline struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) { @@ -1079,6 +1087,7 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ diff --git a/include/linux/tegra-powergate.h b/include/linux/tegra-powergate.h index fd44983..afe442d 100644 --- a/include/linux/tegra-powergate.h +++ b/include/linux/tegra-powergate.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; } diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 1501731..eb73a3a 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -114,6 +114,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data( * @compat_filter_fn: Will be used as the filter function when requesting a * channel for platforms which do not use devicetree. The filter parameter * will be the DAI's DMA data. + * @dma_dev: If set, request DMA channel on this device rather than the DAI + * device. + * @chan_names: If set, these custom DMA channel names will be requested at + * registration time. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM. * @prealloc_buffer_size: Size of the preallocated audio buffer. * @@ -130,6 +134,8 @@ struct snd_dmaengine_pcm_config { struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream); dma_filter_fn compat_filter_fn; + struct device *dma_dev; + const char *chan_names[SNDRV_PCM_STREAM_LAST + 1]; const struct snd_pcm_hardware *pcm_hardware; unsigned int prealloc_buffer_size; @@ -140,6 +146,10 @@ int snd_dmaengine_pcm_register(struct device *dev, unsigned int flags); void snd_dmaengine_pcm_unregister(struct device *dev); +int devm_snd_dmaengine_pcm_register(struct device *dev, + const struct snd_dmaengine_pcm_config *config, + unsigned int flags); + int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 3449c1e..7ac745d 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <sound/soc.h> +#include <sound/dmaengine_pcm.h> static void devm_component_release(struct device *dev, void *res) { @@ -84,3 +85,43 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) return ret; } EXPORT_SYMBOL_GPL(devm_snd_soc_register_card); + +#ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM + +static void devm_dmaengine_pcm_release(struct device *dev, void *res) +{ + snd_dmaengine_pcm_unregister(*(struct device **)res); +} + +/** + * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration + * @dev: The parent device for the PCM device + * @config: Platform specific PCM configuration + * @flags: Platform specific quirks + * + * Register a dmaengine based PCM device with automatic unregistration when the + * device is unregistered. + */ +int devm_snd_dmaengine_pcm_register(struct device *dev, + const struct snd_dmaengine_pcm_config *config, unsigned int flags) +{ + struct device **ptr; + int ret; + + ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = snd_dmaengine_pcm_register(dev, config, flags); + if (ret == 0) { + *ptr = dev; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register); + +#endif diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index cbc9c96..7483922 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -137,6 +137,9 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea hw.buffer_bytes_max = SIZE_MAX; hw.fifo_size = dma_data->fifo_size; + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) + hw.info |= SNDRV_PCM_INFO_BATCH; + ret = dma_get_slave_caps(chan, &dma_caps); if (ret == 0) { if (dma_caps.cmd_pause) @@ -284,24 +287,67 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { [SNDRV_PCM_STREAM_CAPTURE] = "rx", }; -static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, - struct device *dev) +static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, + struct device *dev, const struct snd_dmaengine_pcm_config *config) { unsigned int i; + const char *name; + struct dma_chan *chan; if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || !dev->of_node) - return; + return 0; + + if (config->dma_dev) { + /* + * If this warning is seen, it probably means that your Linux + * device structure does not match your HW device structure. + * It would be best to refactor the Linux device structure to + * correctly match the HW structure. + */ + dev_warn(dev, "DMA channels sourced from device %s", + dev_name(config->dma_dev)); + dev = config->dma_dev; + } - if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) { - pcm->chan[0] = dma_request_slave_channel(dev, "rx-tx"); - pcm->chan[1] = pcm->chan[0]; - } else { - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { - pcm->chan[i] = dma_request_slave_channel(dev, - dmaengine_pcm_dma_channel_names[i]); + for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; + i++) { + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + name = "rx-tx"; + else + name = dmaengine_pcm_dma_channel_names[i]; + if (config->chan_names[i]) + name = config->chan_names[i]; + chan = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(chan)) { + if (PTR_ERR(chan) == -EPROBE_DEFER) + return -EPROBE_DEFER; + pcm->chan[i] = NULL; + } else { + pcm->chan[i] = chan; } + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + break; + } + + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + pcm->chan[1] = pcm->chan[0]; + + return 0; +} + +static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm) +{ + unsigned int i; + + for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; + i++) { + if (!pcm->chan[i]) + continue; + dma_release_channel(pcm->chan[i]); + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + break; } } @@ -315,6 +361,7 @@ int snd_dmaengine_pcm_register(struct device *dev, const struct snd_dmaengine_pcm_config *config, unsigned int flags) { struct dmaengine_pcm *pcm; + int ret; pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); if (!pcm) @@ -323,14 +370,25 @@ int snd_dmaengine_pcm_register(struct device *dev, pcm->config = config; pcm->flags = flags; - dmaengine_pcm_request_chan_of(pcm, dev); + ret = dmaengine_pcm_request_chan_of(pcm, dev, config); + if (ret) + goto err_free_dma; if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) - return snd_soc_add_platform(dev, &pcm->platform, + ret = snd_soc_add_platform(dev, &pcm->platform, &dmaengine_no_residue_pcm_platform); else - return snd_soc_add_platform(dev, &pcm->platform, + ret = snd_soc_add_platform(dev, &pcm->platform, &dmaengine_pcm_platform); + if (ret) + goto err_free_dma; + + return 0; + +err_free_dma: + dmaengine_pcm_release_chan(pcm); + kfree(pcm); + return ret; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register); @@ -345,7 +403,6 @@ void snd_dmaengine_pcm_unregister(struct device *dev) { struct snd_soc_platform *platform; struct dmaengine_pcm *pcm; - unsigned int i; platform = snd_soc_lookup_platform(dev); if (!platform) @@ -353,15 +410,8 @@ void snd_dmaengine_pcm_unregister(struct device *dev) pcm = soc_platform_to_pcm(platform); - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { - if (pcm->chan[i]) { - dma_release_channel(pcm->chan[i]); - if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) - break; - } - } - snd_soc_remove_platform(platform); + dmaengine_pcm_release_chan(pcm); kfree(pcm); } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister); diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 8fc653c..896292b 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -1,6 +1,8 @@ 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 diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index ae27bcd..d8b98d7 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -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) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 364bf6a9..1dc869c 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -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)) { diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 3115433..d6f4c99 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -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"); diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index d67321d..fd7ba75 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -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; diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 231a785..362e8f7 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -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; diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 4d0b0a3..774fc6a 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -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 diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 7b2d23b..7ce5c33 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -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); diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h index 68ad901..7883dec 100644 --- a/sound/soc/tegra/tegra_pcm.h +++ b/sound/soc/tegra/tegra_pcm.h @@ -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 |