as root before you can use this. You'll probably also want to
get the user-space microcode_ctl utility to use with this.
-Powertweak
-----------
-
-If you are running v0.1.17 or earlier, you should upgrade to
-version v0.99.0 or higher. Running old versions may cause problems
-with programs using shared memory.
-
udev
----
udev is a userspace application for populating /dev dynamically with
------------------
o <http://www.urbanmyth.org/microcode/>
-Powertweak
-----------
-o <http://powertweak.sourceforge.net/>
-
udev
----
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
</sect1>
<sect1><title>Wait queues and Wake events</title>
!Iinclude/linux/wait.h
-!Ekernel/wait.c
+!Ekernel/sched/wait.c
</sect1>
<sect1><title>High-resolution timers</title>
!Iinclude/linux/ktime.h
- core-module: the root node to the Integrator platforms must have
a core-module with regs and the compatible string
"arm,core-module-integrator"
+- external-bus-interface: the root node to the Integrator platforms
+ must have an external bus interface with regs and the
+ compatible-string "arm,external-bus-interface"
Required properties for the core module:
- regs: the location and size of the core module registers, one
reg = <0x10000000 0x200>;
};
+ ebi@12000000 {
+ compatible = "arm,external-bus-interface";
+ reg = <0x12000000 0x100>;
+ };
+
syscon {
compatible = "arm,integrator-ap-syscon";
reg = <0x11000000 0x100>;
Required properties:
- compatible: Should be "atmel,<chip>-aic"
+ <chip> can be "at91rm9200" or "sama5d3"
- interrupt-controller: Identifies the node as an interrupt controller.
- interrupt-parent: For single AIC system, it is an empty property.
- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
};
RAMC SDRAM/DDR Controller required properties:
-- compatible: Should be "atmel,at91sam9260-sdramc",
+- compatible: Should be "atmel,at91rm9200-sdramc",
+ "atmel,at91sam9260-sdramc",
"atmel,at91sam9g45-ddramc",
- reg: Should contain registers location and length
For at91sam9263 and at91sam9g45 you must specify 2 entries.
--- /dev/null
+MOXA ART device tree bindings
+
+Boards with the MOXA ART SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "moxa,moxart";
+
+Boards:
+
+- UC-7112-LX: embedded computer
+ compatible = "moxa,moxart-uc-7112-lx", "moxa,moxart"
Required properties:
- compatible : Should be "ti,omap3-mpu" for OMAP3
Should be "ti,omap4-mpu" for OMAP4
+ Should be "ti,omap5-mpu" for OMAP5
- ti,hwmods: "mpu"
Examples:
+- For an OMAP5 SMP system:
+
+mpu {
+ compatible = "ti,omap5-mpu";
+ ti,hwmods = "mpu"
+};
+
- For an OMAP4 SMP system:
mpu {
Required properties:
- compatible : should be one of
+ "arm,armv8-pmuv3"
"arm,cortex-a15-pmu"
"arm,cortex-a9-pmu"
"arm,cortex-a8-pmu"
/* NTC thermistor is a hwmon device */
ncp15wb473@0 {
compatible = "ntc,ncp15wb473";
- pullup-uV = <1800000>;
+ pullup-uv = <1800000>;
pullup-ohm = <47000>;
pulldown-ohm = <0>;
io-channels = <&adc 4>;
SAMSUNG S5P/Exynos SoC series System Registers (SYSREG)
Properties:
- - name : should be 'sysreg';
- compatible : should contain "samsung,<chip name>-sysreg", "syscon";
For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon";
- reg : offset and length of the register set.
+
+Example:
+ syscon@10010000 {
+ compatible = "samsung,exynos4-sysreg", "syscon";
+ reg = <0x10010000 0x400>;
+ };
- 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).
--- /dev/null
+Device Tree Clock bindings for arch-at91
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+ "atmel,at91rm9200-pmc" or
+ "atmel,at91sam9g45-pmc" or
+ "atmel,at91sam9n12-pmc" or
+ "atmel,at91sam9x5-pmc" or
+ "atmel,sama5d3-pmc":
+ at91 PMC (Power Management Controller)
+ All at91 specific clocks (clocks defined below) must be child
+ node of the PMC node.
+
+ "atmel,at91rm9200-clk-main":
+ at91 main oscillator
+
+ "atmel,at91rm9200-clk-master" or
+ "atmel,at91sam9x5-clk-master":
+ at91 master clock
+
+ "atmel,at91sam9x5-clk-peripheral" or
+ "atmel,at91rm9200-clk-peripheral":
+ at91 peripheral clocks
+
+ "atmel,at91rm9200-clk-pll" or
+ "atmel,at91sam9g45-clk-pll" or
+ "atmel,at91sam9g20-clk-pllb" or
+ "atmel,sama5d3-clk-pll":
+ at91 pll clocks
+
+ "atmel,at91sam9x5-clk-plldiv":
+ at91 plla divisor
+
+ "atmel,at91rm9200-clk-programmable" or
+ "atmel,at91sam9g45-clk-programmable" or
+ "atmel,at91sam9x5-clk-programmable":
+ at91 programmable clocks
+
+ "atmel,at91sam9x5-clk-smd":
+ at91 SMD (Soft Modem) clock
+
+ "atmel,at91rm9200-clk-system":
+ at91 system clocks
+
+ "atmel,at91rm9200-clk-usb" or
+ "atmel,at91sam9x5-clk-usb" or
+ "atmel,at91sam9n12-clk-usb":
+ at91 usb clock
+
+ "atmel,at91sam9x5-clk-utmi":
+ at91 utmi clock
+
+Required properties for PMC node:
+- reg : defines the IO memory reserved for the PMC.
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- interrupts : shall be set to PMC interrupt line.
+- interrupt-controller : tell that the PMC is an interrupt controller.
+- #interrupt-cells : must be set to 1. The first cell encodes the interrupt id,
+ and reflect the bit position in the PMC_ER/DR/SR registers.
+ You can use the dt macros defined in dt-bindings/clk/at91.h.
+ 0 (AT91_PMC_MOSCS) -> main oscillator ready
+ 1 (AT91_PMC_LOCKA) -> PLL A ready
+ 2 (AT91_PMC_LOCKB) -> PLL B ready
+ 3 (AT91_PMC_MCKRDY) -> master clock ready
+ 6 (AT91_PMC_LOCKU) -> UTMI PLL clock ready
+ 8 .. 15 (AT91_PMC_PCKRDY(id)) -> programmable clock ready
+ 16 (AT91_PMC_MOSCSELS) -> main oscillator selected
+ 17 (AT91_PMC_MOSCRCS) -> RC main oscillator stabilized
+ 18 (AT91_PMC_CFDEV) -> clock failure detected
+
+For example:
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,sama5d3-pmc";
+ interrupts = <1 4 7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ /* put at91 clocks here */
+ };
+
+Required properties for main clock:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<0>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks (optional if clock-frequency is provided) : shall be the slow clock
+ phandle. This clock is used to calculate the main clock rate if
+ "clock-frequency" is not provided.
+- clock-frequency : the main oscillator frequency.Prefer the use of
+ "clock-frequency" over automatic clock rate calculation.
+
+For example:
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ interrupt-parent = <&pmc>;
+ interrupts = <0>;
+ #clock-cells = <0>;
+ clocks = <&ck32k>;
+ clock-frequency = <18432000>;
+ };
+
+Required properties for master clock:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<3>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the master clock sources (see atmel datasheet) phandles.
+ e.g. "<&ck32k>, <&main>, <&plla>, <&pllb>".
+- atmel,clk-output-range : minimum and maximum clock frequency (two u32
+ fields).
+ e.g. output = <0 133000000>; <=> 0 to 133MHz.
+- atmel,clk-divisors : master clock divisors table (four u32 fields).
+ 0 <=> reserved value.
+ e.g. divisors = <1 2 4 6>;
+- atmel,master-clk-have-div3-pres : some SoC use the reserved value 7 in the
+ PRES field as CLOCK_DIV3 (e.g sam9x5).
+
+For example:
+ mck: mck {
+ compatible = "atmel,at91rm9200-clk-master";
+ interrupt-parent = <&pmc>;
+ interrupts = <3>;
+ #clock-cells = <0>;
+ atmel,clk-output-range = <0 133000000>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+Required properties for peripheral clocks:
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- clocks : shall be the master clock phandle.
+ e.g. clocks = <&mck>;
+- name: device tree node describing a specific system clock.
+ * #clock-cells : from common clock binding; shall be set to 0.
+ * reg: peripheral id. See Atmel's datasheets to get a full
+ list of peripheral ids.
+ * atmel,clk-output-range : minimum and maximum clock frequency
+ (two u32 fields). Only valid on at91sam9x5-clk-peripheral
+ compatible IPs.
+
+For example:
+ periph: periphck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #size-cells = <0>;
+ #address-cells = <1>;
+ clocks = <&mck>;
+
+ ssc0_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ usart0_clk {
+ #clock-cells = <0>;
+ reg = <3>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+ };
+
+
+Required properties for pll clocks:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<1>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the main clock phandle.
+- reg : pll id.
+ 0 -> PLL A
+ 1 -> PLL B
+- atmel,clk-input-range : minimum and maximum source clock frequency (two u32
+ fields).
+ e.g. input = <1 32000000>; <=> 1 to 32MHz.
+- #atmel,pll-clk-output-range-cells : number of cells reserved for pll output
+ range description. Sould be set to 2, 3
+ or 4.
+ * 1st and 2nd cells represent the frequency range (min-max).
+ * 3rd cell is optional and represents the OUT field value for the given
+ range.
+ * 4th cell is optional and represents the ICPLL field (PLLICPR
+ register)
+- atmel,pll-clk-output-ranges : pll output frequency ranges + optional parameter
+ depending on #atmel,pll-output-range-cells
+ property value.
+
+For example:
+ plla: pllack {
+ compatible = "atmel,at91sam9g45-clk-pll";
+ interrupt-parent = <&pmc>;
+ interrupts = <1>;
+ #clock-cells = <0>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <2000000 32000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <74500000 800000000 0 0
+ 69500000 750000000 1 0
+ 64500000 700000000 2 0
+ 59500000 650000000 3 0
+ 54500000 600000000 0 1
+ 49500000 550000000 1 1
+ 44500000 500000000 2 1
+ 40000000 450000000 3 1>;
+ };
+
+Required properties for plldiv clocks (plldiv = pll / 2):
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the plla clock phandle.
+
+The pll divisor is equal to 2 and cannot be changed.
+
+For example:
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+Required properties for programmable clocks:
+- interrupt-parent : must reference the PMC node.
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- clocks : shall be the programmable clock source phandles.
+ e.g. clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+- name: device tree node describing a specific prog clock.
+ * #clock-cells : from common clock binding; shall be set to 0.
+ * reg : programmable clock id (register offset from PCKx
+ register).
+ * interrupts : shall be set to "<(8 + id)>".
+
+For example:
+ prog: progck {
+ compatible = "atmel,at91sam9g45-clk-programmable";
+ #size-cells = <0>;
+ #address-cells = <1>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <8>;
+ };
+
+ prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <9>;
+ };
+ };
+
+
+Required properties for smd clock:
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the smd clock source phandles.
+ e.g. clocks = <&plladiv>, <&utmi>;
+
+For example:
+ smd: smdck {
+ compatible = "atmel,at91sam9x5-clk-smd";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+Required properties for system clocks:
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- name: device tree node describing a specific system clock.
+ * #clock-cells : from common clock binding; shall be set to 0.
+ * reg: system clock id (bit position in SCER/SCDR/SCSR registers).
+ See Atmel's datasheet to get a full list of system clock ids.
+
+For example:
+ system: systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+ };
+
+
+Required properties for usb clock:
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the smd clock source phandles.
+ e.g. clocks = <&pllb>;
+- atmel,clk-divisors (only available for "atmel,at91rm9200-clk-usb"):
+ usb clock divisor table.
+ e.g. divisors = <1 2 4 0>;
+
+For example:
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91rm9200-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&pllb>;
+ atmel,clk-divisors = <1 2 4 0>;
+ };
+
+
+Required properties for utmi clock:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<AT91_PMC_LOCKU IRQ_TYPE_LEVEL_HIGH>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the main clock source phandle.
+
+For example:
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKU IRQ_TYPE_LEVEL_HIGH>;
+ #clock-cells = <0>;
+ clocks = <&main>;
+ };
Required Properties:
-- comptible: should be one of the following.
+- compatible: should be one of the following.
- "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
- "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
Required Properties:
-- comptible: should be one of the following.
+- compatible: should be one of the following.
- "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
- reg: physical base address of the controller and length of memory mapped
Required Properties:
-- comptible: should be one of the following.
+- compatible: should be one of the following.
- "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
- reg: physical base address of the controller and length of memory mapped
Required Properties:
-- comptible: should be "samsung,exynos5440-clock".
+- compatible: should be "samsung,exynos5440-clock".
- reg: physical base address of the controller and length of memory mapped
region.
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:
compatible = "nvidia,tegra114-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
usb@c5004000 {
--- /dev/null
+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>;
+ };
+};
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:
compatible = "nvidia,tegra20-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
usb@c5004000 {
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:
compatible = "nvidia,tegra30-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
usb@c5004000 {
--- /dev/null
+* Renesas CPG DIV6 Clock
+
+The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
+Generator (CPG). They clock input is divided by a configurable factor from 1
+to 64.
+
+Required Properties:
+
+ - compatible: Must be one of the following
+ - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
+ - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks
+ - "renesas,cpg-div6-clock" for generic DIV6 clocks
+ - reg: Base address and length of the memory resource used by the DIV6 clock
+ - clocks: Reference to the parent clock
+ - #clock-cells: Must be 0
+ - clock-output-names: The name of the clock as a free-form string
+
+
+Example
+-------
+
+ sd2_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
--- /dev/null
+* Renesas CPG Module Stop (MSTP) Clocks
+
+The CPG can gate SoC device clocks. The gates are organized in groups of up to
+32 gates.
+
+This device tree binding describes a single 32 gate clocks group per node.
+Clocks are referenced by user nodes by the MSTP node phandle and the clock
+index in the group, from 0 to 31.
+
+Required Properties:
+
+ - compatible: Must be one of the following
+ - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
+ - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
+ - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
+ - reg: Base address and length of the I/O mapped registers used by the MSTP
+ clocks. The first register is the clock control register and is mandatory.
+ The second register is the clock status register and is optional when not
+ implemented in hardware.
+ - clocks: Reference to the parent clocks, one per output clock. The parents
+ must appear in the same order as the output clocks.
+ - #clock-cells: Must be 1
+ - clock-output-names: The name of the clocks as free-form strings
+ - renesas,indices: Indices of the gate clocks into the group (0 to 31)
+
+The clocks, clock-output-names and renesas,indices properties contain one
+entry per gate clock. The MSTP groups are sparsely populated. Unimplemented
+gate clocks must not be declared.
+
+
+Example
+-------
+
+ #include <dt-bindings/clock/r8a7790-clock.h>
+
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+ <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+ <&mmc0_clk>;
+ #clock-cells = <1>;
+ clock-output-names =
+ "tpu0", "mmcif1", "sdhi3", "sdhi2",
+ "sdhi1", "sdhi0", "mmcif0";
+ renesas,clock-indices = <
+ R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+ R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+ R8A7790_CLK_MMCIF0
+ >;
+ };
--- /dev/null
+* Renesas R-Car Gen2 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+ - compatible: Must be one of
+ - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
+ - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
+ - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
+
+ - reg: Base address and length of the memory resource used by the CPG
+
+ - clocks: Reference to the parent clock
+ - #clock-cells: Must be 1
+ - clock-output-names: The names of the clocks. Supported clocks are "main",
+ "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
+
+
+Example
+-------
+
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7790-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0, "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "sd1", "z";
+ };
- 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:
0 149 0x04
0 150 0x04
0 151 0x04 >;
+ clocks = <&tegra_car 34>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
};
Every GPIO controller node must have #gpio-cells property defined,
this information will be used to translate gpio-specifiers.
+See bindings/gpio/gpio.txt for details of how to specify GPIO
+information for devices.
+
+The GPIO module usually is connected to the SoC's internal interrupt
+controller, see bindings/interrupt-controller/interrupts.txt (the
+interrupt client nodes section) for details how to specify this GPIO
+module's interrupt.
+
+The GPIO module may serve as another interrupt controller (cascaded to
+the SoC's internal interrupt controller). See the interrupt controller
+nodes section in bindings/interrupt-controller/interrupts.txt for
+details.
Required properties:
-- compatible : "fsl,<CHIP>-gpio" followed by "fsl,mpc8349-gpio" for
- 83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx.
-- #gpio-cells : Should be two. The first cell is the pin number and the
- second cell is used to specify optional parameters (currently unused).
- - interrupts : Interrupt mapping for GPIO IRQ.
- - interrupt-parent : Phandle for the interrupt controller that
- services interrupts for this device.
-- gpio-controller : Marks the port as GPIO controller.
+- compatible: "fsl,<chip>-gpio" followed by "fsl,mpc8349-gpio"
+ for 83xx, "fsl,mpc8572-gpio" for 85xx, or
+ "fsl,mpc8610-gpio" for 86xx.
+- #gpio-cells: Should be two. The first cell is the pin number
+ and the second cell is used to specify optional
+ parameters (currently unused).
+- interrupt-parent: Phandle for the interrupt controller that
+ services interrupts for this device.
+- interrupts: Interrupt mapping for GPIO IRQ.
+- gpio-controller: Marks the port as GPIO controller.
+
+Optional properties:
+- interrupt-controller: Empty boolean property which marks the GPIO
+ module as an IRQ controller.
+- #interrupt-cells: Should be two. Defines the number of integer
+ cells required to specify an interrupt within
+ this interrupt controller. The first cell
+ defines the pin number, the second cell
+ defines additional flags (trigger type,
+ trigger polarity). Note that the available
+ set of trigger conditions supported by the
+ GPIO module depends on the actual SoC.
Example of gpio-controller nodes for a MPC8347 SoC:
#gpio-cells = <2>;
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
reg = <0xc00 0x100>;
- interrupts = <74 0x8>;
interrupt-parent = <&ipic>;
+ interrupts = <74 0x8>;
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
};
gpio2: gpio-controller@d00 {
#gpio-cells = <2>;
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
reg = <0xd00 0x100>;
- interrupts = <75 0x8>;
interrupt-parent = <&ipic>;
+ interrupts = <75 0x8>;
gpio-controller;
};
-See booting-without-of.txt for details of how to specify GPIO
-information for devices.
-
-To use GPIO pins as interrupt sources for peripherals, specify the
-GPIO controller as the interrupt parent and define GPIO number +
-trigger mode using the interrupts property, which is defined like
-this:
-
-interrupts = <number trigger>, where:
- - number: GPIO pin (0..31)
- - trigger: trigger mode:
- 2 = trigger on falling edge
- 3 = trigger on both edges
-
-Example of device using this is:
+Example of a peripheral using the GPIO module as an IRQ controller:
funkyfpga@0 {
compatible = "funky-fpga";
...
- interrupts = <4 3>;
interrupt-parent = <&gpio1>;
+ interrupts = <4 3>;
};
- #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:
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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:
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>;
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";
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";
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";
};
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";
};
};
I2C for OMAP platforms
Required properties :
-- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c"
+- compatible : Must be "ti,omap2420-i2c", "ti,omap2430-i2c", "ti,omap3-i2c"
+ or "ti,omap4-i2c"
- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
- #address-cells = <1>;
- #size-cells = <0>;
- 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:
#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";
};
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:
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 */
specific extensions.
- "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
specific extensions.
+ - "samsung,exynos5420-dw-mshc": for controllers with Samsung Exynos5420
+ specific extensions.
* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
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
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 */
--- /dev/null
+* TI MMC host controller for OMAP1 and 2420
+
+The MMC Host Controller on TI OMAP1 and 2420 family provides
+an interface for MMC, SD, and SDIO types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the omap mmc driver.
+
+Note that this driver will not work with omap2430 or later omaps,
+please see the omap hsmmc driver for the current omaps.
+
+Required properties:
+- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
+- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
+ instance starting 1
+
+Examples:
+
+ msdi1: mmc@4809c000 {
+ compatible = "ti,omap2420-mmc";
+ ti,hwmods = "msdi1";
+ reg = <0x4809c000 0x80>;
+ interrupts = <83>;
+ dmas = <&sdma 61 &sdma 62>;
+ dma-names = "tx", "rx";
+ };
+
+* TI MMC host controller for OMAP1 and 2420
+
+The MMC Host Controller on TI OMAP1 and 2420 family provides
+an interface for MMC, SD, and SDIO types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the omap mmc driver.
+
+Note that this driver will not work with omap2430 or later omaps,
+please see the omap hsmmc driver for the current omaps.
+
+Required properties:
+- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
+- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
+ instance starting 1
+
+Examples:
+
+ msdi1: mmc@4809c000 {
+ compatible = "ti,omap2420-mmc";
+ ti,hwmods = "msdi1";
+ reg = <0x4809c000 0x80>;
+ interrupts = <83>;
+ dmas = <&sdma 61 &sdma 62>;
+ dma-names = "tx", "rx";
+ };
+
only if property "phy-reset-gpios" is available. Missing the property
will have the duration be 1 millisecond. Numbers greater than 1000 are
invalid and 1 millisecond will be used instead.
+- phy-supply: regulator that powers the Ethernet PHY.
Example:
phy-mode = "mii";
phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
local-mac-address = [00 04 9F 01 1B B9];
+ phy-supply = <®_fec_supply>;
};
- 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
- 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.
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 {
--- /dev/null
+* Freescale IMX25 IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+CONFIG bits definition:
+PAD_CTL_HYS (1 << 8)
+PAD_CTL_PKE (1 << 7)
+PAD_CTL_PUE (1 << 6)
+PAD_CTL_PUS_100K_DOWN (0 << 4)
+PAD_CTL_PUS_47K_UP (1 << 4)
+PAD_CTL_PUS_100K_UP (2 << 4)
+PAD_CTL_PUS_22K_UP (3 << 4)
+PAD_CTL_ODE_CMOS (0 << 3)
+PAD_CTL_ODE_OPENDRAIN (1 << 3)
+PAD_CTL_DSE_NOMINAL (0 << 1)
+PAD_CTL_DSE_HIGH (1 << 1)
+PAD_CTL_DSE_MAX (2 << 1)
+PAD_CTL_SRE_FAST (1 << 0)
+PAD_CTL_SRE_SLOW (0 << 0)
+
+Refer to imx25-pinfunc.h in device tree source folder for all available
+imx25 PIN_FUNC_ID.
CONFIG can be 0 or 1, meaning Pullup disable/enable.
+The iomux controller has gpio child nodes which are embedded in the iomux
+control registers. They have to be defined as child nodes of the iomux device
+node. If gpio subnodes are defined "#address-cells", "#size-cells" and "ranges"
+properties for the iomux device node are required.
Example:
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio1: gpio@10015000 {
+ ...
+ };
+
+ ...
uart {
pinctrl_uart1: uart-1 {
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio1: gpio@10015000 {
+ ...
+ };
+
+ ...
uart {
pinctrl_uart1: uart-1 {
--- /dev/null
+Qualcomm MSM8x74 TLMM block
+
+Required properties:
+- compatible: "qcom,msm8x74-pinctrl"
+- reg: Should be the base address and length of the TLMM block.
+- interrupts: Should be the parent IRQ of the TLMM block.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be two.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells : Should be two.
+ The first cell is the gpio pin number and the
+ second cell is used for optional parameters.
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Qualcomm's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+ pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength.
+
+Non-empty subnodes must specify the 'pins' property.
+Note that not all properties are valid for all pins.
+
+
+Valid values for qcom,pins are:
+ gpio0-gpio145
+ Supports mux, bias and drive-strength
+
+ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
+ Supports bias and drive-strength
+
+Valid values for qcom,function are:
+ blsp_i2c2, blsp_i2c6, blsp_i2c11, blsp_spi1, blsp_uart2, blsp_uart8, slimbus
+
+ (Note that this is not yet the complete list of functions)
+
+
+
+Example:
+
+ msmgpio: pinctrl@fd510000 {
+ compatible = "qcom,msm8x74-pinctrl";
+ reg = <0xfd510000 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 208 0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_default>;
+
+ uart2_default: uart2_default {
+ mux {
+ qcom,pins = "gpio4", "gpio5";
+ qcom,function = "blsp_uart2";
+ };
+
+ tx {
+ qcom,pins = "gpio4";
+ drive-strength = <4>;
+ bias-disable;
+ };
+
+ rx {
+ qcom,pins = "gpio5";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
- #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden
otherwise. Should be 3.
+ - interrupts-extended: Specify the interrupts associated with external
+ IRQ pins. This property is mandatory when the PFC handles GPIOs and
+ forbidden otherwise. When specified, it must contain one interrupt per
+ external IRQ, sorted by external IRQ number.
+
The PFC node also acts as a container for pin configuration nodes. Please refer
to pinctrl-bindings.txt in this directory for the definition of the term "pin
configuration node" and for the common pinctrl bindings used by client devices.
<0xe605801c 0x1c>;
gpio-controller;
#gpio-cells = <2>;
+ interrupts-extended =
+ <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
+ <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
+ <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
+ <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
+ <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
+ <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
+ <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
+ <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
};
Example 2: A GPIO LED node that references a GPIO
- 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:
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
+ clocks = <&tegra_car 17>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
};
--- /dev/null
+Qualcomm MSM pseudo random number generator.
+
+Required properties:
+
+- compatible : should be "qcom,prng"
+- reg : specifies base physical address and size of the registers map
+- clocks : phandle to clock-controller plus clock-specifier pair
+- clock-names : "core" clocks all registers, FIFO and circuits in PRNG IP block
+
+Example:
+
+ rng@f9bff000 {
+ compatible = "qcom,prng";
+ reg = <0xf9bff000 0x200>;
+ clocks = <&clock GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ };
- 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:
compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
+ clocks = <&tegra_car 4>;
};
- 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
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";
};
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,
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,
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,
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,
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,
- 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";
};
- 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:
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";
};
- 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>.
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>;
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";
};
- 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
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";
};
- 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
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";
};
-
- 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
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";
};
-
+++ /dev/null
-NVIDIA Tegra 2 SPI device
-
-Required properties:
-- compatible : should be "nvidia,tegra20-spi".
-- gpios : should specify GPIOs used for chipselect.
- 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:
0 1 0x04
0 41 0x04
0 42 0x04>;
+ clocks = <&tegra_car 132>;
};
- 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";
0 42 0x04
0 121 0x04
0 122 0x04>;
+ clocks = <&tegra_car 214>;
};
7: ..
i: Local Timer Interrupt n
-Example 1: In this example, the system uses only the first global timer
- interrupt generated by MCT and the remaining three global timer
- interrupts are unused. Two local timer interrupts have been
- specified.
+ For MCT block that uses a per-processor interrupt for local timers, such
+ as ones compatible with "samsung,exynos4412-mct", only one local timer
+ interrupt might be specified, meaning that all local timers use the same
+ per processor interrupt.
+
+Example 1: In this example, the IP contains two local timers, using separate
+ interrupts, so two local timer interrupts have been specified,
+ in addition to four global timer interrupts.
mct@10050000 {
compatible = "samsung,exynos4210-mct";
reg = <0x10050000 0x800>;
- interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>,
+ interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>,
<0 42 0>, <0 48 0>;
};
-Example 2: In this example, the MCT global and local timer interrupts are
- connected to two separate interrupt controllers. Hence, an
- interrupt-map is created to map the interrupts to the respective
- interrupt controllers.
+Example 2: In this example, the timer interrupts are connected to two separate
+ interrupt controllers. Hence, an interrupt-map is created to map
+ the interrupts to the respective interrupt controllers.
mct@101C0000 {
compatible = "samsung,exynos4210-mct";
reg = <0x101C0000 0x800>;
- interrupt-controller;
- #interrups-cells = <2>;
interrupt-parent = <&mct_map>;
- interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
- <4 0>, <5 0>;
+ interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
mct_map: mct-map {
- #interrupt-cells = <2>;
+ #interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
- interrupt-map = <0x0 0 &combiner 23 3>,
- <0x4 0 &gic 0 120 0>,
- <0x5 0 &gic 0 121 0>;
+ interrupt-map = <0 &gic 0 57 0>,
+ <1 &gic 0 69 0>,
+ <2 &combiner 12 6>,
+ <3 &combiner 12 7>,
+ <4 &gic 0 42 0>,
+ <5 &gic 0 48 0>;
};
};
+
+Example 3: In this example, the IP contains four local timers, but using
+ a per-processor interrupt to handle them. Either all the local
+ timer interrupts can be specified, with the same interrupt specifier
+ value or just the first one.
+
+ mct@10050000 {
+ compatible = "samsung,exynos4412-mct";
+ reg = <0x10050000 0x800>;
+
+ /* Both ways are possible in this case. Either: */
+ interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>,
+ <0 42 0>;
+ /* or: */
+ interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>,
+ <0 42 0>, <0 42 0>, <0 42 0>, <0 42 0>;
+ };
--- /dev/null
+TI Keystone USB PHY
+
+Required properties:
+ - compatible: should be "ti,keystone-usbphy".
+ - #address-cells, #size-cells : should be '1' if the device has sub-nodes
+ with 'reg' property.
+ - reg : Address and length of the usb phy control register set.
+
+The main purpose of this PHY driver is to enable the USB PHY reference clock
+gate on the Keystone SOC for both the USB2 and USB3 PHY. Otherwise it is just
+an NOP PHY driver. Hence this node is referenced as both the usb2 and usb3
+phy node in the USB Glue layer driver node.
+
+usb_phy: usb_phy@2620738 {
+ compatible = "ti,keystone-usbphy";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2620738 32>;
+ status = "disabled";
+};
--- /dev/null
+TI Keystone Soc USB Controller
+
+DWC3 GLUE
+
+Required properties:
+ - compatible: should be "ti,keystone-dwc3".
+ - #address-cells, #size-cells : should be '1' if the device has sub-nodes
+ with 'reg' property.
+ - reg : Address and length of the register set for the USB subsystem on
+ the SOC.
+ - interrupts : The irq number of this device that is used to interrupt the
+ MPU.
+ - ranges: allows valid 1:1 translation between child's address space and
+ parent's address space.
+ - clocks: Clock IDs array as required by the controller.
+ - clock-names: names of clocks correseponding to IDs in the clock property.
+
+Sub-nodes:
+The dwc3 core should be added as subnode to Keystone DWC3 glue.
+- dwc3 :
+ The binding details of dwc3 can be found in:
+ Documentation/devicetree/bindings/usb/dwc3.txt
+
+Example:
+ usb: usb@2680000 {
+ compatible = "ti,keystone-dwc3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2680000 0x10000>;
+ clocks = <&clkusb>;
+ clock-names = "usb";
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ ranges;
+ status = "disabled";
+
+ dwc3@2690000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x2690000 0x70000>;
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ usb-phy = <&usb_phy>, <&usb_phy>;
+ };
+ };
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
fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+gmt Global Mixed-mode Technology, Inc.
hisilicon Hisilicon Limited.
hp Hewlett Packard
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
img Imagination Technologies Ltd.
intercontrol Inter Control Group
+lg LG Corporation
linux Linux-specific binding
lsi LSI Corp. (LSI Logic)
marvell Marvell Technology Group Ltd.
--- /dev/null
+00-INDEX
+ - This file
+gpio.txt
+ - Introduction to GPIOs and their kernel interfaces
+consumer.txt
+ - How to obtain and use GPIOs in a driver
+driver.txt
+ - How to write a GPIO driver
+board.txt
+ - How to assign GPIOs to a consumer device and a function
+sysfs.txt
+ - Information about the GPIO sysfs interface
+gpio-legacy.txt
+ - Historical documentation of the deprecated GPIO integer interface
--- /dev/null
+GPIO Mappings
+=============
+
+This document explains how GPIOs can be assigned to given devices and functions.
+Note that it only applies to the new descriptor-based interface. For a
+description of the deprecated integer-based GPIO interface please refer to
+gpio-legacy.txt (actually, there is no real mapping possible with the old
+interface; you just fetch an integer from somewhere and request the
+corresponding GPIO.
+
+Platforms that make use of GPIOs must select ARCH_REQUIRE_GPIOLIB (if GPIO usage
+is mandatory) or ARCH_WANT_OPTIONAL_GPIOLIB (if GPIO support can be omitted) in
+their Kconfig. Then, how GPIOs are mapped depends on what the platform uses to
+describe its hardware layout. Currently, mappings can be defined through device
+tree, ACPI, and platform data.
+
+Device Tree
+-----------
+GPIOs can easily be mapped to devices and functions in the device tree. The
+exact way to do it depends on the GPIO controller providing the GPIOs, see the
+device tree bindings for your controller.
+
+GPIOs mappings are defined in the consumer device's node, in a property named
+<function>-gpios, where <function> is the function the driver will request
+through gpiod_get(). For example:
+
+ foo_device {
+ compatible = "acme,foo";
+ ...
+ led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */
+ <&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
+ <&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
+
+ power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
+ };
+
+This property will make GPIOs 15, 16 and 17 available to the driver under the
+"led" function, and GPIO 1 as the "power" GPIO:
+
+ struct gpio_desc *red, *green, *blue, *power;
+
+ red = gpiod_get_index(dev, "led", 0);
+ green = gpiod_get_index(dev, "led", 1);
+ blue = gpiod_get_index(dev, "led", 2);
+
+ power = gpiod_get(dev, "power");
+
+The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
+gpiod_is_active_low(power) will be true).
+
+ACPI
+----
+ACPI does not support function names for GPIOs. Therefore, only the "idx"
+argument of gpiod_get_index() is useful to discriminate between GPIOs assigned
+to a device. The "con_id" argument can still be set for debugging purposes (it
+will appear under error messages as well as debug and sysfs nodes).
+
+Platform Data
+-------------
+Finally, GPIOs can be bound to devices and functions using platform data. Board
+files that desire to do so need to include the following header:
+
+ #include <linux/gpio/driver.h>
+
+GPIOs are mapped by the means of tables of lookups, containing instances of the
+gpiod_lookup structure. Two macros are defined to help declaring such mappings:
+
+ GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
+ GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
+
+where
+
+ - chip_label is the label of the gpiod_chip instance providing the GPIO
+ - chip_hwnum is the hardware number of the GPIO within the chip
+ - dev_id is the identifier of the device that will make use of this GPIO. If
+ NULL, the GPIO will be available to all devices.
+ - con_id is the name of the GPIO function from the device point of view. It
+ can be NULL.
+ - idx is the index of the GPIO within the function.
+ - flags is defined to specify the following properties:
+ * GPIOF_ACTIVE_LOW - to configure the GPIO as active-low
+ * GPIOF_OPEN_DRAIN - GPIO pin is open drain type.
+ * GPIOF_OPEN_SOURCE - GPIO pin is open source type.
+
+In the future, these flags might be extended to support more properties.
+
+Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
+
+A lookup table can then be defined as follows:
+
+ struct gpiod_lookup gpios_table[] = {
+ GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW),
+ };
+
+And the table can be added by the board code as follows:
+
+ gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table));
+
+The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
+
+ struct gpio_desc *red, *green, *blue, *power;
+
+ red = gpiod_get_index(dev, "led", 0);
+ green = gpiod_get_index(dev, "led", 1);
+ blue = gpiod_get_index(dev, "led", 2);
+
+ power = gpiod_get(dev, "power");
+ gpiod_direction_output(power, 1);
+
+Since the "power" GPIO is mapped as active-low, its actual signal will be 0
+after this code. Contrary to the legacy integer GPIO interface, the active-low
+property is handled during mapping and is thus transparent to GPIO consumers.
--- /dev/null
+GPIO Descriptor Consumer Interface
+==================================
+
+This document describes the consumer interface of the GPIO framework. Note that
+it describes the new descriptor-based interface. For a description of the
+deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
+
+
+Guidelines for GPIOs consumers
+==============================
+
+Drivers that can't work without standard GPIO calls should have Kconfig entries
+that depend on GPIOLIB. The functions that allow a driver to obtain and use
+GPIOs are available by including the following file:
+
+ #include <linux/gpio/consumer.h>
+
+All the functions that work with the descriptor-based GPIO interface are
+prefixed with gpiod_. The gpio_ prefix is used for the legacy interface. No
+other function in the kernel should use these prefixes.
+
+
+Obtaining and Disposing GPIOs
+=============================
+
+With the descriptor-based interface, GPIOs are identified with an opaque,
+non-forgeable handler that must be obtained through a call to one of the
+gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
+device that will use the GPIO and the function the requested GPIO is supposed to
+fulfill:
+
+ struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
+
+If a function is implemented by using several GPIOs together (e.g. a simple LED
+device that displays digits), an additional index argument can be specified:
+
+ struct gpio_desc *gpiod_get_index(struct device *dev,
+ const char *con_id, unsigned int idx)
+
+Both functions return either a valid GPIO descriptor, or an error code checkable
+with IS_ERR(). They will never return a NULL pointer.
+
+Device-managed variants of these functions are also defined:
+
+ struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
+
+ struct gpio_desc *devm_gpiod_get_index(struct device *dev,
+ const char *con_id,
+ unsigned int idx)
+
+A GPIO descriptor can be disposed of using the gpiod_put() function:
+
+ void gpiod_put(struct gpio_desc *desc)
+
+It is strictly forbidden to use a descriptor after calling this function. The
+device-managed variant is, unsurprisingly:
+
+ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
+
+
+Using GPIOs
+===========
+
+Setting Direction
+-----------------
+The first thing a driver must do with a GPIO is setting its direction. This is
+done by invoking one of the gpiod_direction_*() functions:
+
+ int gpiod_direction_input(struct gpio_desc *desc)
+ int gpiod_direction_output(struct gpio_desc *desc, int value)
+
+The return value is zero for success, else a negative errno. It should be
+checked, since the get/set calls don't return errors and since misconfiguration
+is possible. You should normally issue these calls from a task context. However,
+for spinlock-safe GPIOs it is OK to use them before tasking is enabled, as part
+of early board setup.
+
+For output GPIOs, the value provided becomes the initial output value. This
+helps avoid signal glitching during system startup.
+
+A driver can also query the current direction of a GPIO:
+
+ int gpiod_get_direction(const struct gpio_desc *desc)
+
+This function will return either GPIOF_DIR_IN or GPIOF_DIR_OUT.
+
+Be aware that there is no default direction for GPIOs. Therefore, **using a GPIO
+without setting its direction first is illegal and will result in undefined
+behavior!**
+
+
+Spinlock-Safe GPIO Access
+-------------------------
+Most GPIO controllers can be accessed with memory read/write instructions. Those
+don't need to sleep, and can safely be done from inside hard (non-threaded) IRQ
+handlers and similar contexts.
+
+Use the following calls to access GPIOs from an atomic context:
+
+ int gpiod_get_value(const struct gpio_desc *desc);
+ void gpiod_set_value(struct gpio_desc *desc, int value);
+
+The values are boolean, zero for low, nonzero for high. When reading the value
+of an output pin, the value returned should be what's seen on the pin. That
+won't always match the specified output value, because of issues including
+open-drain signaling and output latencies.
+
+The get/set calls do not return errors because "invalid GPIO" should have been
+reported earlier from gpiod_direction_*(). However, note that not all platforms
+can read the value of output pins; those that can't should always return zero.
+Also, using these calls for GPIOs that can't safely be accessed without sleeping
+(see below) is an error.
+
+
+GPIO Access That May Sleep
+--------------------------
+Some GPIO controllers must be accessed using message based buses like I2C or
+SPI. Commands to read or write those GPIO values require waiting to get to the
+head of a queue to transmit a command and get its response. This requires
+sleeping, which can't be done from inside IRQ handlers.
+
+Platforms that support this type of GPIO distinguish them from other GPIOs by
+returning nonzero from this call:
+
+ int gpiod_cansleep(const struct gpio_desc *desc)
+
+To access such GPIOs, a different set of accessors is defined:
+
+ int gpiod_get_value_cansleep(const struct gpio_desc *desc)
+ void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
+
+Accessing such GPIOs requires a context which may sleep, for example a threaded
+IRQ handler, and those accessors must be used instead of spinlock-safe
+accessors without the cansleep() name suffix.
+
+Other than the fact that these accessors might sleep, and will work on GPIOs
+that can't be accessed from hardIRQ handlers, these calls act the same as the
+spinlock-safe calls.
+
+
+Active-low State and Raw GPIO Values
+------------------------------------
+Device drivers like to manage the logical state of a GPIO, i.e. the value their
+device will actually receive, no matter what lies between it and the GPIO line.
+In some cases, it might make sense to control the actual GPIO line value. The
+following set of calls ignore the active-low property of a GPIO and work on the
+raw line value:
+
+ int gpiod_get_raw_value(const struct gpio_desc *desc)
+ void gpiod_set_raw_value(struct gpio_desc *desc, int value)
+ int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
+ void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
+
+The active-low state of a GPIO can also be queried using the following call:
+
+ int gpiod_is_active_low(const struct gpio_desc *desc)
+
+Note that these functions should only be used with great moderation ; a driver
+should not have to care about the physical line level.
+
+GPIOs mapped to IRQs
+--------------------
+GPIO lines can quite often be used as IRQs. You can get the IRQ number
+corresponding to a given GPIO using the following call:
+
+ int gpiod_to_irq(const struct gpio_desc *desc)
+
+It will return an IRQ number, or an negative errno code if the mapping can't be
+done (most likely because that particular GPIO cannot be used as IRQ). It is an
+unchecked error to use a GPIO that wasn't set up as an input using
+gpiod_direction_input(), or to use an IRQ number that didn't originally come
+from gpiod_to_irq(). gpiod_to_irq() is not allowed to sleep.
+
+Non-error values returned from gpiod_to_irq() can be passed to request_irq() or
+free_irq(). They will often be stored into IRQ resources for platform devices,
+by the board-specific initialization code. Note that IRQ trigger options are
+part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup
+capabilities.
+
+
+Interacting With the Legacy GPIO Subsystem
+==========================================
+Many kernel subsystems still handle GPIOs using the legacy integer-based
+interface. Although it is strongly encouraged to upgrade them to the safer
+descriptor-based API, the following two functions allow you to convert a GPIO
+descriptor into the GPIO integer namespace and vice-versa:
+
+ int desc_to_gpio(const struct gpio_desc *desc)
+ struct gpio_desc *gpio_to_desc(unsigned gpio)
+
+The GPIO number returned by desc_to_gpio() can be safely used as long as the
+GPIO descriptor has not been freed. All the same, a GPIO number passed to
+gpio_to_desc() must have been properly acquired, and usage of the returned GPIO
+descriptor is only possible after the GPIO number has been released.
+
+Freeing a GPIO obtained by one API with the other API is forbidden and an
+unchecked error.
--- /dev/null
+GPIO Descriptor Driver Interface
+================================
+
+This document serves as a guide for GPIO chip drivers writers. Note that it
+describes the new descriptor-based interface. For a description of the
+deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
+
+Each GPIO controller driver needs to include the following header, which defines
+the structures used to define a GPIO driver:
+
+ #include <linux/gpio/driver.h>
+
+
+Internal Representation of GPIOs
+================================
+
+Inside a GPIO driver, individual GPIOs are identified by their hardware number,
+which is a unique number between 0 and n, n being the number of GPIOs managed by
+the chip. This number is purely internal: the hardware number of a particular
+GPIO descriptor is never made visible outside of the driver.
+
+On top of this internal number, each GPIO also need to have a global number in
+the integer GPIO namespace so that it can be used with the legacy GPIO
+interface. Each chip must thus have a "base" number (which can be automatically
+assigned), and for each GPIO the global number will be (base + hardware number).
+Although the integer representation is considered deprecated, it still has many
+users and thus needs to be maintained.
+
+So for example one platform could use numbers 32-159 for GPIOs, with a
+controller defining 128 GPIOs at a "base" of 32 ; while another platform uses
+numbers 0..63 with one set of GPIO controllers, 64-79 with another type of GPIO
+controller, and on one particular board 80-95 with an FPGA. The numbers need not
+be contiguous; either of those platforms could also use numbers 2000-2063 to
+identify GPIOs in a bank of I2C GPIO expanders.
+
+
+Controller Drivers: gpio_chip
+=============================
+
+In the gpiolib framework each GPIO controller is packaged as a "struct
+gpio_chip" (see linux/gpio/driver.h for its complete definition) with members
+common to each controller of that type:
+
+ - methods to establish GPIO direction
+ - methods used to access GPIO values
+ - method to return the IRQ number associated to a given GPIO
+ - flag saying whether calls to its methods may sleep
+ - optional debugfs dump method (showing extra state like pullup config)
+ - optional base number (will be automatically assigned if omitted)
+ - label for diagnostics and GPIOs mapping using platform data
+
+The code implementing a gpio_chip should support multiple instances of the
+controller, possibly using the driver model. That code will configure each
+gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be rare;
+use gpiochip_remove() when it is unavoidable.
+
+Most often a gpio_chip is part of an instance-specific structure with state not
+exposed by the GPIO interfaces, such as addressing, power management, and more.
+Chips such as codecs will have complex non-GPIO state.
+
+Any debugfs dump method should normally ignore signals which haven't been
+requested as GPIOs. They can use gpiochip_is_requested(), which returns either
+NULL or the label associated with that GPIO when it was requested.
+
+Locking IRQ usage
+-----------------
+Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
+to mark the GPIO as being used as an IRQ:
+
+ int gpiod_lock_as_irq(struct gpio_desc *desc)
+
+This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
+is released:
+
+ void gpiod_unlock_as_irq(struct gpio_desc *desc)
--- /dev/null
+GPIO Interfaces
+===============
+
+The documents in this directory give detailed instructions on how to access
+GPIOs in drivers, and how to write a driver for a device that provides GPIOs
+itself.
+
+Due to the history of GPIO interfaces in the kernel, there are two different
+ways to obtain and use GPIOs:
+
+ - The descriptor-based interface is the preferred way to manipulate GPIOs,
+and is described by all the files in this directory excepted gpio-legacy.txt.
+ - The legacy integer-based interface which is considered deprecated (but still
+usable for compatibility reasons) is documented in gpio-legacy.txt.
+
+The remainder of this document applies to the new descriptor-based interface.
+gpio-legacy.txt contains the same information applied to the legacy
+integer-based interface.
+
+
+What is a GPIO?
+===============
+
+A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
+digital signal. They are provided from many kinds of chip, and are familiar
+to Linux developers working with embedded and custom hardware. Each GPIO
+represents a bit connected to a particular pin, or "ball" on Ball Grid Array
+(BGA) packages. Board schematics show which external hardware connects to
+which GPIOs. Drivers can be written generically, so that board setup code
+passes such pin configuration data to drivers.
+
+System-on-Chip (SOC) processors heavily rely on GPIOs. In some cases, every
+non-dedicated pin can be configured as a GPIO; and most chips have at least
+several dozen of them. Programmable logic devices (like FPGAs) can easily
+provide GPIOs; multifunction chips like power managers, and audio codecs
+often have a few such pins to help with pin scarcity on SOCs; and there are
+also "GPIO Expander" chips that connect using the I2C or SPI serial buses.
+Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
+firmware knowing how they're used).
+
+The exact capabilities of GPIOs vary between systems. Common options:
+
+ - Output values are writable (high=1, low=0). Some chips also have
+ options about how that value is driven, so that for example only one
+ value might be driven, supporting "wire-OR" and similar schemes for the
+ other value (notably, "open drain" signaling).
+
+ - Input values are likewise readable (1, 0). Some chips support readback
+ of pins configured as "output", which is very useful in such "wire-OR"
+ cases (to support bidirectional signaling). GPIO controllers may have
+ input de-glitch/debounce logic, sometimes with software controls.
+
+ - Inputs can often be used as IRQ signals, often edge triggered but
+ sometimes level triggered. Such IRQs may be configurable as system
+ wakeup events, to wake the system from a low power state.
+
+ - Usually a GPIO will be configurable as either input or output, as needed
+ by different product boards; single direction ones exist too.
+
+ - Most GPIOs can be accessed while holding spinlocks, but those accessed
+ through a serial bus normally can't. Some systems support both types.
+
+On a given board each GPIO is used for one specific purpose like monitoring
+MMC/SD card insertion/removal, detecting card write-protect status, driving
+a LED, configuring a transceiver, bit-banging a serial bus, poking a hardware
+watchdog, sensing a switch, and so on.
+
+
+Common GPIO Properties
+======================
+
+These properties are met through all the other documents of the GPIO interface
+and it is useful to understand them, especially if you need to define GPIO
+mappings.
+
+Active-High and Active-Low
+--------------------------
+It is natural to assume that a GPIO is "active" when its output signal is 1
+("high"), and inactive when it is 0 ("low"). However in practice the signal of a
+GPIO may be inverted before is reaches its destination, or a device could decide
+to have different conventions about what "active" means. Such decisions should
+be transparent to device drivers, therefore it is possible to define a GPIO as
+being either active-high ("1" means "active", the default) or active-low ("0"
+means "active") so that drivers only need to worry about the logical signal and
+not about what happens at the line level.
+
+Open Drain and Open Source
+--------------------------
+Sometimes shared signals need to use "open drain" (where only the low signal
+level is actually driven), or "open source" (where only the high signal level is
+driven) signaling. That term applies to CMOS transistors; "open collector" is
+used for TTL. A pullup or pulldown resistor causes the high or low signal level.
+This is sometimes called a "wire-AND"; or more practically, from the negative
+logic (low=true) perspective this is a "wire-OR".
+
+One common example of an open drain signal is a shared active-low IRQ line.
+Also, bidirectional data bus signals sometimes use open drain signals.
+
+Some GPIO controllers directly support open drain and open source outputs; many
+don't. When you need open drain signaling but your hardware doesn't directly
+support it, there's a common idiom you can use to emulate it with any GPIO pin
+that can be used as either an input or an output:
+
+ LOW: gpiod_direction_output(gpio, 0) ... this drives the signal and overrides
+ the pullup.
+
+ HIGH: gpiod_direction_input(gpio) ... this turns off the output, so the pullup
+ (or some other device) controls the signal.
+
+The same logic can be applied to emulate open source signaling, by driving the
+high signal and configuring the GPIO as input for low. This open drain/open
+source emulation can be handled transparently by the GPIO framework.
+
+If you are "driving" the signal high but gpiod_get_value(gpio) reports a low
+value (after the appropriate rise time passes), you know some other component is
+driving the shared signal low. That's not necessarily an error. As one common
+example, that's how I2C clocks are stretched: a slave that needs a slower clock
+delays the rising edge of SCK, and the I2C master adjusts its signaling rate
+accordingly.
--- /dev/null
+GPIO Sysfs Interface for Userspace
+==================================
+
+Platforms which use the "gpiolib" implementors framework may choose to
+configure a sysfs user interface to GPIOs. This is different from the
+debugfs interface, since it provides control over GPIO direction and
+value instead of just showing a gpio state summary. Plus, it could be
+present on production systems without debugging support.
+
+Given appropriate hardware documentation for the system, userspace could
+know for example that GPIO #23 controls the write protect line used to
+protect boot loader segments in flash memory. System upgrade procedures
+may need to temporarily remove that protection, first importing a GPIO,
+then changing its output state, then updating the code before re-enabling
+the write protection. In normal use, GPIO #23 would never be touched,
+and the kernel would have no need to know about it.
+
+Again depending on appropriate hardware documentation, on some systems
+userspace GPIO can be used to determine system configuration data that
+standard kernels won't know about. And for some tasks, simple userspace
+GPIO drivers could be all that the system really needs.
+
+Note that standard kernel drivers exist for common "LEDs and Buttons"
+GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those
+instead of talking directly to the GPIOs; they integrate with kernel
+frameworks better than your userspace code could.
+
+
+Paths in Sysfs
+--------------
+There are three kinds of entry in /sys/class/gpio:
+
+ - Control interfaces used to get userspace control over GPIOs;
+
+ - GPIOs themselves; and
+
+ - GPIO controllers ("gpio_chip" instances).
+
+That's in addition to standard files including the "device" symlink.
+
+The control interfaces are write-only:
+
+ /sys/class/gpio/
+
+ "export" ... Userspace may ask the kernel to export control of
+ a GPIO to userspace by writing its number to this file.
+
+ Example: "echo 19 > export" will create a "gpio19" node
+ for GPIO #19, if that's not requested by kernel code.
+
+ "unexport" ... Reverses the effect of exporting to userspace.
+
+ Example: "echo 19 > unexport" will remove a "gpio19"
+ node exported using the "export" file.
+
+GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
+and have the following read/write attributes:
+
+ /sys/class/gpio/gpioN/
+
+ "direction" ... reads as either "in" or "out". This value may
+ normally be written. Writing as "out" defaults to
+ initializing the value as low. To ensure glitch free
+ operation, values "low" and "high" may be written to
+ configure the GPIO as an output with that initial value.
+
+ Note that this attribute *will not exist* if the kernel
+ doesn't support changing the direction of a GPIO, or
+ it was exported by kernel code that didn't explicitly
+ allow userspace to reconfigure this GPIO's direction.
+
+ "value" ... reads as either 0 (low) or 1 (high). If the GPIO
+ is configured as an output, this value may be written;
+ any nonzero value is treated as high.
+
+ If the pin can be configured as interrupt-generating interrupt
+ and if it has been configured to generate interrupts (see the
+ description of "edge"), you can poll(2) on that file and
+ poll(2) will return whenever the interrupt was triggered. If
+ you use poll(2), set the events POLLPRI and POLLERR. If you
+ use select(2), set the file descriptor in exceptfds. After
+ poll(2) returns, either lseek(2) to the beginning of the sysfs
+ file and read the new value or close the file and re-open it
+ to read the value.
+
+ "edge" ... reads as either "none", "rising", "falling", or
+ "both". Write these strings to select the signal edge(s)
+ that will make poll(2) on the "value" file return.
+
+ This file exists only if the pin can be configured as an
+ interrupt generating input pin.
+
+ "active_low" ... reads as either 0 (false) or 1 (true). Write
+ any nonzero value to invert the value attribute both
+ for reading and writing. Existing and subsequent
+ poll(2) support configuration via the edge attribute
+ for "rising" and "falling" edges will follow this
+ setting.
+
+GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
+controller implementing GPIOs starting at #42) and have the following
+read-only attributes:
+
+ /sys/class/gpio/gpiochipN/
+
+ "base" ... same as N, the first GPIO managed by this chip
+
+ "label" ... provided for diagnostics (not always unique)
+
+ "ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)
+
+Board documentation should in most cases cover what GPIOs are used for
+what purposes. However, those numbers are not always stable; GPIOs on
+a daughtercard might be different depending on the base board being used,
+or other cards in the stack. In such cases, you may need to use the
+gpiochip nodes (possibly in conjunction with schematics) to determine
+the correct GPIO number to use for a given signal.
+
+
+Exporting from Kernel code
+--------------------------
+Kernel code can explicitly manage exports of GPIOs which have already been
+requested using gpio_request():
+
+ /* export the GPIO to userspace */
+ int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
+
+ /* reverse gpio_export() */
+ void gpiod_unexport(struct gpio_desc *desc);
+
+ /* create a sysfs link to an exported GPIO node */
+ int gpiod_export_link(struct device *dev, const char *name,
+ struct gpio_desc *desc);
+
+ /* change the polarity of a GPIO node in sysfs */
+ int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value);
+
+After a kernel driver requests a GPIO, it may only be made available in
+the sysfs interface by gpiod_export(). The driver can control whether the
+signal direction may change. This helps drivers prevent userspace code
+from accidentally clobbering important system state.
+
+This explicit exporting can help with debugging (by making some kinds
+of experiments easier), or can provide an always-there interface that's
+suitable for documenting as part of a board support package.
+
+After the GPIO has been exported, gpiod_export_link() allows creating
+symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
+use this to provide the interface under their own device in sysfs with
+a descriptive name.
+
+Drivers can use gpiod_sysfs_set_active_low() to hide GPIO line polarity
+differences between boards from user space. Polarity change can be done both
+before and after gpiod_export(), and previously enabled poll(2) support for
+either rising or falling edge will be reconfigured to follow this setting.
F: drivers/gpio/gpio-bt8xx.c
BTRFS FILE SYSTEM
-M: Chris Mason <chris.mason@fusionio.com>
+M: Chris Mason <clm@fb.com>
+M: Josef Bacik <jbacik@fb.com>
L: linux-btrfs@vger.kernel.org
W: http://btrfs.wiki.kernel.org/
Q: http://patchwork.kernel.org/project/linux-btrfs/list/
S: Maintained
F: drivers/usb/chipidea/
+CHROME HARDWARE PLATFORM SUPPORT
+M: Olof Johansson <olof@lixom.net>
+S: Maintained
+F: drivers/platform/chrome/
+
CISCO VIC ETHERNET NIC DRIVER
M: Christian Benvenuti <benve@cisco.com>
M: Sujith Sankar <ssujith@cisco.com>
S: Maintained
F: drivers/net/usb/hso.c
+HSR NETWORK PROTOCOL
+M: Arvid Brodin <arvid.brodin@alten.se>
+L: netdev@vger.kernel.org
+S: Maintained
+F: net/hsr/
+
HTCPEN TOUCHSCREEN DRIVER
M: Pau Oliva Fora <pof@eslack.org>
L: linux-input@vger.kernel.org
F: Documentation/lockdep*.txt
F: Documentation/lockstat.txt
F: include/linux/lockdep.h
-F: kernel/lockdep*
+F: kernel/locking/
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
M: "Richard Russon (FlatCap)" <ldm@flatcap.org>
F: include/linux/platform_data/pn544.h
NFS, SUNRPC, AND LOCKD CLIENTS
-M: Trond Myklebust <Trond.Myklebust@netapp.com>
+M: Trond Myklebust <trond.myklebust@primarydata.com>
L: linux-nfs@vger.kernel.org
W: http://client.linux-nfs.org
-T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git
+T: git git://git.linux-nfs.org/projects/trondmy/linux-nfs.git
S: Maintained
F: fs/lockd/
F: fs/nfs/
M: Rob Herring <rob.herring@calxeda.com>
M: Pawel Moll <pawel.moll@arm.com>
M: Mark Rutland <mark.rutland@arm.com>
-M: Stephen Warren <swarren@wwwdotorg.org>
M: Ian Campbell <ijc+devicetree@hellion.org.uk>
+M: Kumar Gala <galak@codeaurora.org>
L: devicetree@vger.kernel.org
S: Maintained
F: Documentation/devicetree/
F: kernel/sched/
F: include/linux/sched.h
F: include/uapi/linux/sched.h
-F: kernel/wait.c
F: include/linux/wait.h
SCORE ARCHITECTURE
VERSION = 3
PATCHLEVEL = 13
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
NAME = One Giant Leap for Frogkind
# *DOCUMENTATION*
stack and controls some vital subsystems
(clock and power control, etc).
-config ARCH_SHMOBILE
- bool "Renesas SH-Mobile / R-Mobile"
+config ARCH_SHMOBILE_LEGACY
+ bool "Renesas SH-Mobile / R-Mobile (non-multiplatform)"
+ select ARCH_SHMOBILE
select ARM_PATCH_PHYS_VIRT
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select PM_GENERIC_DOMAINS if PM
select SPARSE_IRQ
help
- Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
+ Support for Renesas's SH-Mobile and R-Mobile ARM platforms using
+ a non-multiplatform kernel.
config ARCH_RPC
bool "RiscPC"
default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \
ARCH_S5PV210 || ARCH_EXYNOS4
default AT91_TIMER_HZ if ARCH_AT91
- default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
+ default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE_LEGACY
default 0
choice
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
- int "Maximum zone order" if ARCH_SHMOBILE
- range 11 64 if ARCH_SHMOBILE
+ int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
+ range 11 64 if ARCH_SHMOBILE_LEGACY
default "12" if SOC_AM33XX
default "9" if SA1111
default "11"
machine-$(CONFIG_ARCH_S5PV210) += s5pv210
machine-$(CONFIG_ARCH_SA1100) += sa1100
machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
-machine-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile
machine-$(CONFIG_ARCH_SIRF) += prima2
machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
endif
endif
-ifeq ($(CONFIG_ARCH_SHMOBILE),y)
+ifeq ($(CONFIG_ARCH_SHMOBILE_LEGACY),y)
OBJS += head-shmobile.o
endif
dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
# sam9x5
dtb-$(CONFIG_ARCH_AT91) += at91-ariag25.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91-cosino_mega2560.dtb
dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb
dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb
dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb
+
dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \
exynos4412-odroidx.dtb \
exynos4412-origen.dtb \
exynos4412-smdk4412.dtb \
+ exynos4412-tiny4412.dtb \
exynos4412-trats2.dtb \
exynos5250-arndale.dtb \
exynos5250-smdk5250.dtb \
exynos5250-snow.dtb \
+ exynos5420-arndale-octa.dtb \
exynos5420-smdk5420.dtb \
exynos5440-sd5v1.dtb \
exynos5440-ssdk5440.dtb
kirkwood-iomega_ix2_200.dtb \
kirkwood-is2.dtb \
kirkwood-km_kirkwood.dtb \
+ kirkwood-laplug.dtb \
kirkwood-lschlv2.dtb \
kirkwood-lsxhl.dtb \
kirkwood-mplcec4.dtb \
kirkwood-mv88f6281gtw-ge.dtb \
kirkwood-netgear_readynas_duo_v2.dtb \
+ kirkwood-netgear_readynas_nv+_v2.dtb \
kirkwood-ns2.dtb \
kirkwood-ns2lite.dtb \
kirkwood-ns2max.dtb \
kirkwood-ts219-6281.dtb \
kirkwood-ts219-6282.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
armada-xp-axpwifiap.dtb \
armada-xp-db.dtb \
armada-xp-gp.dtb \
+ armada-xp-netgear-rn2120.dtb \
armada-xp-matrix.dtb \
armada-xp-openblocks-ax3-4.dtb
dtb-$(CONFIG_ARCH_MXC) += \
dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \
s3c6410-smdk6410.dtb
-dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
+dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += emev2-kzm9d.dtb \
r7s72100-genmai.dtb \
r8a7740-armadillo800eva.dtb \
r8a7778-bockw.dtb \
sun4i-a10-hackberry.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a13-olinuxino.dtb \
+ sun5i-a13-olinuxino-micro.dtb \
sun6i-a31-colombus.dtb \
sun7i-a20-cubieboard2.dtb \
sun7i-a20-cubietruck.dtb \
/ {
model = "IGEP COM AM335x on AQUILA Expansion";
compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
+
+ hdmi {
+ compatible = "ti,tilcdc,slave";
+ i2c = <&i2c0>;
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_pins>;
+ pinctrl-1 = <&nxp_hdmi_off_pins>;
+ status = "okay";
+ };
+
+ leds_base {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_base_pins>;
+
+ compatible = "gpio-leds";
+
+ led@0 {
+ label = "base:red:user";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* gpio1_21 */
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "base:green:user";
+ gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; /* gpio2_0 */
+ default-state = "off";
+ };
+ };
+};
+
+&am33xx_pinmux {
+ nxp_hdmi_pins: pinmux_nxp_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ 0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */
+ 0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */
+ 0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */
+ 0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */
+ 0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */
+ 0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */
+ 0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */
+ 0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */
+ 0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */
+ 0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */
+ 0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */
+ 0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */
+ 0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */
+ 0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */
+ 0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */
+ 0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */
+ 0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */
+ 0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */
+ 0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */
+ 0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en */
+ >;
+ };
+ nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ >;
+ };
+
+ leds_base_pins: pinmux_leds_base_pins {
+ pinctrl-single,pins = <
+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ 0x88 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */
+ >;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+&i2c0 {
+ eeprom: eeprom@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
};
pinctrl-0 = <&uart0_pins>;
};
+&usb {
+ status = "okay";
+
+ control@44e10000 {
+ status = "okay";
+ };
+
+ usb-phy@47401300 {
+ status = "okay";
+ };
+
+ usb-phy@47401b00 {
+ status = "okay";
+ };
+
+ usb@47401000 {
+ status = "okay";
+ };
+
+ usb@47401800 {
+ status = "okay";
+ dr_mode = "host";
+ };
+
+ dma-controller@07402000 {
+ status = "okay";
+ };
+};
+
#include "tps65910.dtsi"
&tps {
nand-on-flash-bbt;
status = "okay";
- at91bootstrap@0 {
- label = "at91bootstrap";
- reg = <0x0 0x8000>;
- };
-
- barebox@8000 {
+ barebox@0 {
label = "barebox";
- reg = <0x8000 0x40000>;
- };
-
- bareboxenv@48000 {
- label = "bareboxenv";
- reg = <0x48000 0x8000>;
- };
-
- user_block@0x50000 {
- label = "user_block";
- reg = <0x50000 0xb0000>;
+ reg = <0x0 0x58000>;
};
- kernel@100000 {
- label = "kernel";
- reg = <0x100000 0x1b0000>;
+ u_boot_env@58000 {
+ label = "u_boot_env";
+ reg = <0x58000 0x8000>;
};
- root@2b0000 {
- label = "root";
- reg = <0x2b0000 0x1D50000>;
+ ubi@60000 {
+ label = "ubi";
+ reg = <0x60000 0x1FA0000>;
};
};
spi-max-frequency = <50000000>;
};
};
+ };
- pcie-controller {
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * both standard PCIe slots and mini-PCIe
+ * slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
status = "okay";
- /*
- * The two PCIe units are accessible through
- * both standard PCIe slots and mini-PCIe
- * slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
};
};
};
green_pwr_led {
label = "mirabox:green:pwr";
gpios = <&gpio1 31 1>;
- linux,default-trigger = "heartbeat";
+ default-state = "keep";
};
blue_stat_led {
label = "mirabox:blue:stat";
gpios = <&gpio2 0 1>;
- linux,default-trigger = "cpu0";
+ default-state = "off";
};
green_stat_led {
reg = <0x25>;
};
};
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x400000>;
+ };
+ partition@400000 {
+ label = "Linux";
+ reg = <0x400000 0x400000>;
+ };
+ partition@800000 {
+ label = "Filesystem";
+ reg = <0x800000 0x3f800000>;
+ };
+ };
};
};
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
#include "armada-370.dtsi"
/ {
marvell,pins = "mpp57";
marvell,function = "gpio";
};
+
sata1_led_pin: sata1-led-pin {
marvell,pins = "mpp15";
marvell,function = "gpio";
marvell,function = "gpio";
};
+ backup_button_pin: backup-button-pin {
+ marvell,pins = "mpp58";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp62";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp6";
+ marvell,function = "gpio";
+ };
+
poweroff: poweroff {
marvell,pins = "mpp8";
marvell,function = "gpio";
};
mdio {
- phy0: ethernet-phy@0 {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
reg = <0>;
};
};
clock-frequency = <100000>;
status = "okay";
+ isl12057: isl12057@68 {
+ compatible = "isl,isl12057";
+ reg = <0x68>;
+ };
+
g762: g762@3e {
compatible = "gmt,g762";
reg = <0x3e>;
pwm_polarity = <0>;
};
};
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
+ };
};
};
clocks {
- #address-cells = <1>;
- #size-cells = <0>;
-
- g762_clk: fixedclk {
+ g762_clk: g762-oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <8192>;
};
};
- gpio_leds {
+ gpio-leds {
compatible = "gpio-leds";
- pinctrl-0 = < &power_led_pin
- &sata1_led_pin
- &sata2_led_pin
- &backup_led_pin >;
+ pinctrl-0 = <&power_led_pin
+ &sata1_led_pin
+ &sata2_led_pin
+ &backup_led_pin>;
pinctrl-names = "default";
- blue_power_led {
+ blue-power-led {
label = "rn102:blue:pwr";
- gpios = <&gpio1 25 1>; /* GPIO 57 Active Low */
- linux,default-trigger = "heartbeat";
+ gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
- green_sata1_led {
+ green-sata1-led {
label = "rn102:green:sata1";
- gpios = <&gpio0 15 1>; /* GPIO 15 Active Low */
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- green_sata2_led {
+ green-sata2-led {
label = "rn102:green:sata2";
- gpios = <&gpio0 14 1>; /* GPIO 14 Active Low */
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- green_backup_led {
+ green-backup-led {
label = "rn102:green:backup";
- gpios = <&gpio1 24 1>; /* GPIO 56 Active Low */
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
default-state = "on";
};
};
- gpio_keys {
+ gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
+ pinctrl-0 = <&power_button_pin
+ &reset_button_pin
+ &backup_button_pin>;
+ pinctrl-names = "default";
- button@1 {
+ power-button {
label = "Power Button";
- linux,code = <116>; /* KEY_POWER */
- gpios = <&gpio1 30 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
};
- button@2 {
+ reset-button {
label = "Reset Button";
- linux,code = <0x198>; /* KEY_RESTART */
- gpios = <&gpio0 6 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
- button@3 {
+ backup-button {
label = "Backup Button";
- linux,code = <133>; /* KEY_COPY */
- gpios = <&gpio1 26 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
};
};
- gpio_poweroff {
+ gpio-poweroff {
compatible = "gpio-poweroff";
pinctrl-0 = <&poweroff>;
pinctrl-names = "default";
- gpios = <&gpio0 8 1>;
+ gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
};
-
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
#include "armada-370.dtsi"
/ {
marvell,function = "gpio";
};
- backup_key_pin: backup-key-pin {
+ backup_button_pin: backup-button-pin {
marvell,pins = "mpp52";
marvell,function = "gpio";
};
- power_key_pin: power-key-pin {
+ power_button_pin: power-button-pin {
marvell,pins = "mpp62";
marvell,function = "gpio";
};
marvell,function = "gpio";
};
- reset_key_pin: reset-key-pin {
+ reset_button_pin: reset-button-pin {
marvell,pins = "mpp65";
marvell,function = "gpio";
};
};
mdio {
- phy0: ethernet-phy@0 {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
reg = <0>;
};
- phy1: ethernet-phy@1 {
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
reg = <1>;
};
};
clock-frequency = <100000>;
status = "okay";
+ isl12057: isl12057@68 {
+ compatible = "isl,isl12057";
+ reg = <0x68>;
+ };
+
g762: g762@3e {
compatible = "gmt,g762";
reg = <0x3e>;
fan_startv = <1>;
pwm_polarity = <0>;
};
+
+ pca9554: pca9554@23 {
+ compatible = "nxp,pca9554";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x23>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
};
};
};
clocks {
- #address-cells = <1>;
- #size-cells = <0>;
-
- g762_clk: fixedclk {
+ g762_clk: g762-oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <8192>;
};
};
- gpio_leds {
+ gpio-leds {
compatible = "gpio-leds";
pinctrl-0 = <&backup_led_pin &power_led_pin>;
pinctrl-names = "default";
- blue_backup_led {
+ blue-backup-led {
label = "rn104:blue:backup";
- gpios = <&gpio1 31 0>; /* GPIO 63 Active High */
+ gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- blue_power_led {
+ blue-power-led {
label = "rn104:blue:pwr";
- gpios = <&gpio2 0 1>; /* GPIO 64 Active Low */
+ gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
linux,default-trigger = "keep";
};
+
+ blue-sata1-led {
+ label = "rn104:blue:sata1";
+ gpios = <&pca9554 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata2-led {
+ label = "rn104:blue:sata2";
+ gpios = <&pca9554 1 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata3-led {
+ label = "rn104:blue:sata3";
+ gpios = <&pca9554 2 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue-sata4-led {
+ label = "rn104:blue:sata4";
+ gpios = <&pca9554 3 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
};
- gpio_keys {
+ gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-0 = <&backup_key_pin
- &power_key_pin
- &reset_key_pin>;
+ pinctrl-0 = <&backup_button_pin
+ &power_button_pin
+ &reset_button_pin>;
pinctrl-names = "default";
- button@1 {
+ backup-button {
label = "Backup Button";
- linux,code = <133>; /* KEY_COPY */
- gpios = <&gpio1 20 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
};
- button@2 {
+ power-button {
label = "Power Button";
- linux,code = <116>; /* KEY_POWER */
- gpios = <&gpio1 30 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
};
- button@3 {
+ reset-button {
label = "Reset Button";
- linux,code = <0x198>; /* KEY_RESTART */
- gpios = <&gpio2 1 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
};
};
- gpio_poweroff {
+ gpio-poweroff {
compatible = "gpio-poweroff";
pinctrl-0 = <&poweroff>;
pinctrl-names = "default";
- gpios = <&gpio1 28 1>;
+ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
};
};
gpios = <&gpio0 6 1>;
};
};
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+ };
};
};
};
#size-cells = <1>;
ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
- mbusc: mbus-controller@20000 {
- compatible = "marvell,mbus-controller";
- reg = <0x20000 0x100>, <0x20180 0x20>;
+ rtc@10300 {
+ compatible = "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <50>;
};
- mpic: interrupt-controller@20000 {
- compatible = "marvell,mpic";
- #interrupt-cells = <1>;
- #size-cells = <1>;
- interrupt-controller;
- msi-controller;
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10600 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <30>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
};
- coherency-fabric@20200 {
- compatible = "marvell,coherency-fabric";
- reg = <0x20200 0xb0>, <0x21810 0x1c>;
+ spi1: spi@10680 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10680 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <92>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <31>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
};
serial@12000 {
clock-output-names = "nand";
};
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ mpic: interrupt-controller@20000 {
+ compatible = "marvell,mpic";
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ msi-controller;
+ };
+
+ coherency-fabric@20200 {
+ compatible = "marvell,coherency-fabric";
+ reg = <0x20200 0xb0>, <0x21010 0x1c>;
+ };
+
timer@20300 {
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
};
- sata@a0000 {
- compatible = "marvell,orion-sata";
- reg = <0xa0000 0x5000>;
- interrupts = <55>;
- clocks = <&gateclk 15>, <&gateclk 30>;
- clock-names = "0", "1";
+ usb@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x500>;
+ interrupts = <45>;
status = "disabled";
};
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,orion-mdio";
- reg = <0x72004 0x4>;
+ usb@51000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x51000 0x500>;
+ interrupts = <46>;
+ status = "disabled";
};
eth0: ethernet@70000 {
status = "disabled";
};
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x72004 0x4>;
+ };
+
eth1: ethernet@74000 {
compatible = "marvell,armada-370-neta";
reg = <0x74000 0x4000>;
status = "disabled";
};
- i2c0: i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <31>;
- timeout-ms = <1000>;
- clocks = <&coreclk 0>;
+ sata@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x5000>;
+ interrupts = <55>;
+ clocks = <&gateclk 15>, <&gateclk 30>;
+ clock-names = "0", "1";
status = "disabled";
};
- i2c1: i2c@11100 {
- compatible = "marvell,mv64xxx-i2c";
+ nand@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
#address-cells = <1>;
- #size-cells = <0>;
- interrupts = <32>;
- timeout-ms = <1000>;
- clocks = <&coreclk 0>;
+ #size-cells = <1>;
+ interrupts = <113>;
+ clocks = <&coredivclk 0>;
status = "disabled";
};
- rtc@10300 {
- compatible = "marvell,orion-rtc";
- reg = <0x10300 0x20>;
- interrupts = <50>;
- };
-
mvsdio@d4000 {
compatible = "marvell,orion-sdio";
reg = <0xd4000 0x200>;
cap-mmc-highspeed;
status = "disabled";
};
-
- usb@50000 {
- compatible = "marvell,orion-ehci";
- reg = <0x50000 0x500>;
- interrupts = <45>;
- status = "disabled";
- };
-
- usb@51000 {
- compatible = "marvell,orion-ehci";
- reg = <0x51000 0x500>;
- interrupts = <46>;
- status = "disabled";
- };
-
- spi0: spi@10600 {
- compatible = "marvell,orion-spi";
- reg = <0x10600 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- interrupts = <30>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- spi1: spi@10680 {
- compatible = "marvell,orion-spi";
- reg = <0x10680 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- interrupts = <92>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
};
};
};
internal-regs {
- system-controller@18200 {
- compatible = "marvell,armada-370-xp-system-controller";
- reg = <0x18200 0x100>;
- };
-
L2: l2-cache {
compatible = "marvell,aurora-outer-cache";
reg = <0x08000 0x1000>;
wt-override;
};
- interrupt-controller@20000 {
- reg = <0x20a00 0x1d0>, <0x21870 0x58>;
+ i2c0: i2c@11000 {
+ reg = <0x11000 0x20>;
+ };
+
+ i2c1: i2c@11100 {
+ reg = <0x11100 0x20>;
+ };
+
+ system-controller@18200 {
+ compatible = "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x100>;
};
pinctrl {
interrupts = <91>;
};
- timer@20300 {
- compatible = "marvell,armada-370-timer";
- clocks = <&coreclk 2>;
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-370-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
};
coreclk: mvebu-sar@18230 {
#clock-cells = <1>;
};
- gateclk: clock-gating-control@18220 {
- compatible = "marvell,armada-370-gating-clock";
- reg = <0x18220 0x4>;
+ thermal@18300 {
+ compatible = "marvell,armada370-thermal";
+ reg = <0x18300 0x4
+ 0x18304 0x4>;
+ status = "okay";
+ };
+
+ interrupt-controller@20000 {
+ reg = <0x20a00 0x1d0>, <0x21870 0x58>;
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-370-timer";
+ clocks = <&coreclk 2>;
+ };
+
+ usb@50000 {
+ clocks = <&coreclk 0>;
+ };
+
+ usb@51000 {
clocks = <&coreclk 0>;
- #clock-cells = <1>;
};
xor@60800 {
dmacap,memset;
};
};
-
- i2c0: i2c@11000 {
- reg = <0x11000 0x20>;
- };
-
- i2c1: i2c@11100 {
- reg = <0x11100 0x20>;
- };
-
- usb@50000 {
- clocks = <&coreclk 0>;
- };
-
- usb@51000 {
- clocks = <&coreclk 0>;
- };
-
- thermal@18300 {
- compatible = "marvell,armada370-thermal";
- reg = <0x18300 0x4
- 0x18304 0x4>;
- status = "okay";
- };
};
};
};
spi-max-frequency = <108000000>;
};
};
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ };
};
};
};
/*
* MV78230 has 2 PCIe units Gen2.0: One unit can be
* configured as x4 or quad x1 lanes. One unit is
- * x4/x1.
+ * x1 only.
*/
pcie-controller {
compatible = "marvell,armada-xp-pcie";
ranges =
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
- 0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
- 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
- 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
+ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
pcie@1,0 {
device_type = "pci";
status = "disabled";
};
- pcie@9,0 {
+ pcie@5,0 {
device_type = "pci";
- assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
- reg = <0x4800 0 0 0 0>;
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
- 0x81000000 0 0 0x81000000 0x9 0 1 0>;
+ ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+ 0x81000000 0 0 0x81000000 0x5 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &mpic 99>;
- marvell,pcie-port = <2>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
marvell,pcie-lane = <0>;
- clocks = <&gateclk 26>;
+ clocks = <&gateclk 9>;
status = "disabled";
};
};
/*
* MV78260 has 3 PCIe units Gen2.0: Two units can be
* configured as x4 or quad x1 lanes. One unit is
- * x4/x1.
+ * x4 only.
*/
pcie-controller {
compatible = "marvell,armada-xp-pcie";
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
- 0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */
+ 0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
+ 0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
+ 0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
- 0x82000000 0x9 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
- 0x81000000 0x9 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
- 0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
- 0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
+
+ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
+ 0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
+ 0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
+ 0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
+ 0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
+ 0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
+ 0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
+
+ 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
+ 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
pcie@1,0 {
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
- 0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+ 0x81000000 0 0 0x81000000 0x2 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 59>;
marvell,pcie-port = <0>;
status = "disabled";
};
- pcie@9,0 {
+ pcie@5,0 {
device_type = "pci";
- assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
- reg = <0x4800 0 0 0 0>;
+ assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
- 0x81000000 0 0 0x81000000 0x9 0 1 0>;
+ ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+ 0x81000000 0 0 0x81000000 0x5 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &mpic 99>;
- marvell,pcie-port = <2>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
marvell,pcie-lane = <0>;
- clocks = <&gateclk 26>;
+ clocks = <&gateclk 9>;
status = "disabled";
};
- pcie@10,0 {
+ pcie@6,0 {
device_type = "pci";
- assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
- reg = <0x5000 0 0 0 0>;
+ assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
+ reg = <0x3000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
- 0x81000000 0 0 0x81000000 0xa 0 1 0>;
+ ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
+ 0x81000000 0 0 0x81000000 0x6 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &mpic 103>;
- marvell,pcie-port = <3>;
+ interrupt-map = <0 0 0 0 &mpic 63>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+
+ pcie@7,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
+ reg = <0x3800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
+ 0x81000000 0 0 0x81000000 0x7 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 64>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 11>;
+ status = "disabled";
+ };
+
+ pcie@8,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
+ reg = <0x4000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
+ 0x81000000 0 0 0x81000000 0x8 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 65>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 12>;
+ status = "disabled";
+ };
+
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+ 0x81000000 0 0 0x81000000 0x9 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
marvell,pcie-lane = <0>;
- clocks = <&gateclk 27>;
+ clocks = <&gateclk 26>;
status = "disabled";
};
};
--- /dev/null
+/*
+ * Device Tree file for NETGEAR ReadyNAS 2120
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS 2120";
+ compatible = "netgear,readynas-2120", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x80000000>; /* 2GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to first Marvell 88SE9170 SATA controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to second Marvell 88SE9170 SATA controller */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Connected to Fresco Logic FL1009 USB 3.0 controller */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ pinctrl {
+ poweroff: poweroff {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ power_button_pin: power-button-pin {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+
+ reset_button_pin: reset-button-pin {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ sata1_led_pin: sata1-led-pin {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ sata2_led_pin: sata2-led-pin {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ sata3_led_pin: sata3-led-pin {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ sata4_led_pin: sata4-led-pin {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ sata1_power_pin: sata1-power-pin {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ sata2_power_pin: sata2-power-pin {
+ marvell,pins = "mpp25";
+ marvell,function = "gpio";
+ };
+
+ sata3_power_pin: sata3-power-pin {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+
+ sata4_power_pin: sata4-power-pin {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ sata1_pres_pin: sata1-pres-pin {
+ marvell,pins = "mpp32";
+ marvell,function = "gpio";
+ };
+
+ sata2_pres_pin: sata2-pres-pin {
+ marvell,pins = "mpp33";
+ marvell,function = "gpio";
+ };
+
+ sata3_pres_pin: sata3-pres-pin {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ sata4_pres_pin: sata4-pres-pin {
+ marvell,pins = "mpp35";
+ marvell,function = "gpio";
+ };
+
+ err_led_pin: err-led-pin {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+ };
+
+ serial@12000 {
+ clocks = <&coreclk 0>;
+ status = "okay";
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ /* Front USB 2.0 port */
+ usb@50000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ clock-frequency = <400000>;
+ status = "okay";
+
+ isl12057: isl12057@68 {
+ compatible = "isl,isl12057";
+ reg = <0x68>;
+ };
+
+ /* Controller for rear fan #1 of 3 (Protechnic
+ * MGT4012XB-O20, 8000RPM) near eSATA port */
+ g762_fan1: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Controller for rear (center) fan #2 of 3 */
+ g762_fan2: g762@48 {
+ compatible = "gmt,g762";
+ reg = <0x48>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Controller for rear fan #3 of 3 */
+ g762_fan3: g762@49 {
+ compatible = "gmt,g762";
+ reg = <0x49>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+
+ /* Temperature sensor */
+ g751: g751@4c {
+ compatible = "gmt,g751";
+ reg = <0x4c>;
+ };
+ };
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>; /* 1.5MB */
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>; /* 128KB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>; /* 6MB */
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x400000>; /* 4MB */
+ };
+
+ /* Last MB is for the BBT, i.e. not writable */
+ partition@c00000 {
+ label = "ubifs";
+ reg = <0x0c00000 0x7400000>; /* 116MB */
+ };
+ };
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&sata1_led_pin &sata2_led_pin &err_led_pin
+ &sata3_led_pin &sata4_led_pin>;
+ pinctrl-names = "default";
+
+ red-sata1-led {
+ label = "rn2120:red:sata1";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata2-led {
+ label = "rn2120:red:sata2";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata3-led {
+ label = "rn2120:red:sata3";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-sata4-led {
+ label = "rn2120:red:sata4";
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red-err-led {
+ label = "rn2120:red:err";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&power_button_pin &reset_button_pin>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+};
green_led {
label = "green_led";
gpios = <&gpio1 21 1>;
- default-state = "off";
- linux,default-trigger = "heartbeat";
+ default-state = "keep";
};
};
wt-override;
};
- interrupt-controller@20000 {
- reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
};
- armada-370-xp-pmsu@22000 {
- compatible = "marvell,armada-370-xp-pmsu";
- reg = <0x22100 0x430>, <0x20800 0x20>;
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
};
serial@12200 {
status = "disabled";
};
- timer@20300 {
- compatible = "marvell,armada-xp-timer";
- clocks = <&coreclk 2>, <&refclk>;
- clock-names = "nbclk", "fixed";
+ system-controller@18200 {
+ compatible = "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x500>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-xp-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
};
coreclk: mvebu-sar@18230 {
#clock-cells = <1>;
};
+ thermal@182b0 {
+ compatible = "marvell,armadaxp-thermal";
+ reg = <0x182b0 0x4
+ 0x184d0 0x4>;
+ status = "okay";
+ };
+
cpuclk: clock-complex@18700 {
#clock-cells = <1>;
compatible = "marvell,armada-xp-cpu-clock";
clocks = <&coreclk 1>;
};
- gateclk: clock-gating-control@18220 {
- compatible = "marvell,armada-xp-gating-clock";
- reg = <0x18220 0x4>;
- clocks = <&coreclk 0>;
- #clock-cells = <1>;
+ interrupt-controller@20000 {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
};
- system-controller@18200 {
- compatible = "marvell,armada-370-xp-system-controller";
- reg = <0x18200 0x500>;
+ timer@20300 {
+ compatible = "marvell,armada-xp-timer";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+ };
+
+ armada-370-xp-pmsu@22000 {
+ compatible = "marvell,armada-370-xp-pmsu";
+ reg = <0x22100 0x400>, <0x20800 0x20>;
};
eth2: ethernet@30000 {
status = "disabled";
};
+ usb@50000 {
+ clocks = <&gateclk 18>;
+ };
+
+ usb@51000 {
+ clocks = <&gateclk 19>;
+ };
+
+ usb@52000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x52000 0x500>;
+ interrupts = <47>;
+ clocks = <&gateclk 20>;
+ status = "disabled";
+ };
+
xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
dmacap,memset;
};
};
-
- i2c0: i2c@11000 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11000 0x100>;
- };
-
- i2c1: i2c@11100 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11100 0x100>;
- };
-
- usb@50000 {
- clocks = <&gateclk 18>;
- };
-
- usb@51000 {
- clocks = <&gateclk 19>;
- };
-
- usb@52000 {
- compatible = "marvell,orion-ehci";
- reg = <0x52000 0x500>;
- interrupts = <47>;
- clocks = <&gateclk 20>;
- status = "disabled";
- };
-
- thermal@182b0 {
- compatible = "marvell,armadaxp-thermal";
- reg = <0x182b0 0x4
- 0x184d0 0x4>;
- status = "okay";
- };
};
};
--- /dev/null
+/*
+ * at91-cosino.dtsi - Device Tree file for Cosino core module
+ *
+ * Copyright (C) 2013 - Rodolfo Giometti <giometti@linux.it>
+ * HCE Engineering
+ *
+ * Derived from at91sam9x5ek.dtsi by:
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91sam9g35.dtsi"
+
+/ {
+ model = "HCE Cosino core module";
+ compatible = "hce,cosino", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait";
+ };
+
+ memory {
+ reg = <0x20000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@f801c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ adc0: adc@f804c000 {
+ atmel,adc-clock-rate = <1000000>;
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD15 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc; /* Enable PMECC */
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ uboot@40000 {
+ label = "u-boot";
+ reg = <0x40000 0x80000>;
+ };
+
+ ubootenv@c0000 {
+ label = "U-Boot Env";
+ reg = <0xc0000 0x140000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+};
--- /dev/null
+/*
+ * at91-cosino_mega2560.dts - Device Tree file for Cosino board with
+ * Mega 2560 extension
+ *
+ * Copyright (C) 2013 - Rodolfo Giometti <giometti@linux.it>
+ * HCE Engineering
+ *
+ * Derived from at91sam9g35ek.dts by:
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+#include "at91-cosino.dtsi"
+
+/ {
+ model = "HCE Cosino Mega 2560";
+ compatible = "hce,cosino_mega2560", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ ahb {
+ apb {
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ adc0: adc@f804c000 {
+ atmel,adc-clock-rate = <1000000>;
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
+
+ tsadcc: tsadcc@f804c000 {
+ status = "okay";
+ };
+
+ rtc@fffffeb0 {
+ status = "okay";
+ };
+
+ usart1: serial@f8020000 {
+ status = "okay";
+ };
+
+ usart2: serial@f8024000 {
+ status = "okay";
+ };
+
+ usb2: gadget@f803c000 {
+ atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ mmc1: mmc@f000c000 {
+ pinctrl-0 = <
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ non-removable;
+ };
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <3>;
+ atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW */
+ &pioD 19 GPIO_ACTIVE_LOW
+ &pioD 20 GPIO_ACTIVE_LOW
+ >;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+};
AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA18 periph A */
};
- pinctrl_uart0_rts: uart0_rts-0 {
+ pinctrl_uart0_cts: uart0_cts-0 {
atmel,pins =
<AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA20 periph A */
};
- pinctrl_uart0_cts: uart0_cts-0 {
+ pinctrl_uart0_rts: uart0_rts-0 {
atmel,pins =
<AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA21 periph A */
};
ahb {
apb {
- dbgu: serial@fffff200 {
+ usb1: gadget@fffb0000 {
+ atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>;
+ atmel,pullup-gpio = <&pioD 5 GPIO_ACTIVE_HIGH>;
status = "okay";
};
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+
+ phy0: ethernet-phy {
+ interrupt-parent = <&pioC>;
+ interrupts = <4 IRQ_TYPE_EDGE_BOTH>;
+ };
+ };
+
usart1: serial@fffc4000 {
pinctrl-0 =
<&pinctrl_uart1
status = "okay";
};
- macb0: ethernet@fffbc000 {
- phy-mode = "rmii";
- status = "okay";
- };
-
- usb1: gadget@fffb0000 {
- atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>;
- status = "okay";
- };
-
spi0: spi@fffe0000 {
status = "okay";
cs-gpios = <&pioA 3 0>, <0>, <0>, <0>;
reg = <0>;
};
};
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
};
usb0: ohci@00300000 {
num-ports = <2>;
status = "okay";
};
+
+ nor_flash@10000000 {
+ compatible = "cfi-flash";
+ reg = <0x10000000 0x800000>;
+ linux,mtd-name = "physmap-flash.0";
+ bank-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ barebox@0 {
+ label = "barebox";
+ reg = <0x00000 0x40000>;
+ };
+
+ bareboxenv@40000 {
+ label = "bareboxenv";
+ reg = <0x40000 0x10000>;
+ };
+
+ kernel@50000 {
+ label = "kernel";
+ reg = <0x50000 0x300000>;
+ };
+
+ root@350000 {
+ label = "root";
+ reg = <0x350000 0x4B0000>;
+ };
+ };
};
leds {
i2c0 = &i2c0;
ssc0 = &ssc0;
ssc1 = &ssc1;
+ pwm0 = &pwm0;
};
cpus {
#address-cells = <0>;
};
};
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC1 periph A */
+ AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC2 periph A */
+ AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC3 periph A */
+ AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB9 periph B */
+ AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 periph A */
+ AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 periph A */
+ AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 periph A */
+ AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC9 periph A */
+ AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC10 periph A */
+ AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC11 periph A */
+ AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC14 periph A */
+ AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC15 periph A */
+ AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC16 periph A */
+ AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC12 periph B */
+ AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC18 periph A */
+ AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC19 periph A */
+ AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC22 periph A */
+ AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC23 periph A */
+ AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC24 periph A */
+ AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC17 periph B */
+ AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC26 periph A */
+ AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC27 periph A */
+ };
+ };
+
pioA: gpio@fffff200 {
compatible = "atmel,at91rm9200-gpio";
reg = <0xfffff200 0x200>;
pinctrl-0 = <&pinctrl_spi1>;
status = "disabled";
};
+
+ pwm0: pwm@fffb8000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xfffb8000 0x300>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ };
+
+ fb0: fb@0x00700000 {
+ compatible = "atmel,at91sam9263-lcdc";
+ reg = <0x00700000 0x1000>;
+ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ status = "disabled";
};
nand0: nand@40000000 {
};
};
+ fb0: fb@0x00700000 {
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <16>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <1>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <4965000>;
+ hactive = <240>;
+ vactive = <320>;
+ hback-porch = <1>;
+ hfront-porch = <33>;
+ vback-porch = <1>;
+ vfront-porch = <0>;
+ hsync-len = <5>;
+ vsync-len = <1>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+ };
+ };
+
nand0: nand@40000000 {
nand-bus-width = <8>;
nand-ecc-mode = "soft";
i2c1 = &i2c1;
ssc0 = &ssc0;
ssc1 = &ssc1;
+ pwm0 = &pwm0;
};
cpus {
#address-cells = <0>;
};
};
+ i2c0 {
+ pinctrl_i2c0: i2c0-0 {
+ atmel,pins =
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA21 periph A TWCK0 */
+ AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA20 periph A TWD0 */
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1: i2c1-0 {
+ atmel,pins =
+ <AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A TWCK1 */
+ AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A TWD1 */
+ };
+ };
+
usart0 {
pinctrl_usart0: usart0-0 {
atmel,pins =
};
};
+ fb {
+ pinctrl_fb: fb-0 {
+ atmel,pins =
+ <AT91_PIOE 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE0 periph A */
+ AT91_PIOE 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE2 periph A */
+ AT91_PIOE 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE3 periph A */
+ AT91_PIOE 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE4 periph A */
+ AT91_PIOE 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE5 periph A */
+ AT91_PIOE 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE6 periph A */
+ AT91_PIOE 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE7 periph A */
+ AT91_PIOE 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE8 periph A */
+ AT91_PIOE 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE9 periph A */
+ AT91_PIOE 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE10 periph A */
+ AT91_PIOE 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE11 periph A */
+ AT91_PIOE 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE12 periph A */
+ AT91_PIOE 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE13 periph A */
+ AT91_PIOE 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE14 periph A */
+ AT91_PIOE 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE15 periph A */
+ AT91_PIOE 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE16 periph A */
+ AT91_PIOE 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE17 periph A */
+ AT91_PIOE 18 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE18 periph A */
+ AT91_PIOE 19 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE19 periph A */
+ AT91_PIOE 20 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE20 periph A */
+ AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE21 periph A */
+ AT91_PIOE 22 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE22 periph A */
+ AT91_PIOE 23 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE23 periph A */
+ AT91_PIOE 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE24 periph A */
+ AT91_PIOE 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE25 periph A */
+ AT91_PIOE 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE26 periph A */
+ AT91_PIOE 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE27 periph A */
+ AT91_PIOE 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE28 periph A */
+ AT91_PIOE 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PE29 periph A */
+ AT91_PIOE 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PE30 periph A */
+ };
+ };
+
pioA: gpio@fffff200 {
compatible = "atmel,at91rm9200-gpio";
reg = <0xfffff200 0x200>;
compatible = "atmel,at91sam9g10-i2c";
reg = <0xfff84000 0x100>;
interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
compatible = "atmel,at91sam9g10-i2c";
reg = <0xfff88000 0x100>;
interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
};
+ pwm0: pwm@fffb8000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xfffb8000 0x300>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
mmc0: mmc@fff80000 {
compatible = "atmel,hsmci";
reg = <0xfff80000 0x600>;
interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>;
dma-names = "rxtx";
#address-cells = <1>;
compatible = "atmel,hsmci";
reg = <0xfffd0000 0x600>;
interrupts = <29 IRQ_TYPE_LEVEL_HIGH 0>;
+ pinctrl-names = "default";
dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>;
dma-names = "rxtx";
#address-cells = <1>;
};
};
+ fb0: fb@0x00500000 {
+ compatible = "atmel,at91sam9g45-lcdc";
+ reg = <0x00500000 0x1000>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fb>;
+ status = "disabled";
+ };
+
nand0: nand@40000000 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PD29 gpio WP pin pull up */
};
};
+
+ pwm0 {
+ pinctrl_pwm_leds: pwm-led {
+ atmel,pins =
+ <AT91_PIOD 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PD0 periph B */
+ AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PD31 periph B */
+ };
+ };
};
spi0: spi@fffa4000{
atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>;
status = "okay";
};
+
+ pwm0: pwm@fffb8000 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_leds>;
+ };
+ };
+
+ fb0: fb@0x00500000 {
+ display = <&display0>;
+ status = "okay";
+
+ display0: display {
+ bits-per-pixel = <32>;
+ atmel,lcdcon-backlight;
+ atmel,dmacon = <0x1>;
+ atmel,lcdcon2 = <0x80008002>;
+ atmel,guard-time = <9>;
+ atmel,lcd-wiring-mode = "RGB";
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hback-porch = <1>;
+ hfront-porch = <1>;
+ vback-porch = <40>;
+ vfront-porch = <1>;
+ hsync-len = <45>;
+ vsync-len = <1>;
+ };
+ };
+ };
};
nand0: nand@40000000 {
gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
d6 {
label = "d6";
- gpios = <&pioD 0 GPIO_ACTIVE_LOW>;
+ pwms = <&pwm0 3 5000 0>;
+ max-brightness = <255>;
linux,default-trigger = "nand-disk";
};
d7 {
label = "d7";
- gpios = <&pioD 31 GPIO_ACTIVE_LOW>;
+ pwms = <&pwm0 1 5000 0>;
+ max-brightness = <255>;
linux,default-trigger = "mmc0";
};
};
i2c0 = &i2c0;
i2c1 = &i2c1;
ssc0 = &ssc0;
+ pwm0 = &pwm0;
};
cpus {
#address-cells = <0>;
reg = <0xfffffe40 0x10>;
status = "disabled";
};
+
+ pwm0: pwm@f8034000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xf8034000 0x300>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
i2c1 = &i2c1;
i2c2 = &i2c2;
ssc0 = &ssc0;
+ pwm0 = &pwm0;
};
cpus {
#address-cells = <0>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
status = "disabled";
};
+
+ pwm0: pwm@f8034000 {
+ compatible = "atmel,at91sam9rl-pwm";
+ reg = <0xf8034000 0x300>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
#include <dt-bindings/interrupt-controller/irq.h>
/ {
+ aliases {
+ serial4 = &usart3;
+ };
+
ahb {
apb {
pinctrl@fffff400 {
&gpio {
pinctrl-names = "default";
- pinctrl-0 = <&alt0 &alt3>;
+ pinctrl-0 = <&gpioout &alt0 &alt3>;
+
+ gpioout: gpioout {
+ brcm,pins = <6>;
+ brcm,function = <1>; /* GPIO out */
+ };
alt0: alt0 {
- brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 14 15 40 45>;
+ brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>;
brcm,function = <4>; /* alt0 */
};
reg = <0x7e205000 0x1000>;
interrupts = <2 21>;
clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
status = "disabled";
};
reg = <0x7e804000 0x1000>;
interrupts = <2 21>;
clocks = <&clk_i2c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
status = "disabled";
};
clocks = <&clk_mmc>;
status = "disabled";
};
+
+ usb {
+ compatible = "brcm,bcm2835-usb";
+ reg = <0x7e980000 0x10000>;
+ interrupts = <1 9>;
+ };
};
clocks {
power {
label = "Power";
gpios = <&gpio0 18 1>;
- linux,default-trigger = "default-on";
+ default-state = "keep";
};
};
0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800 /* CESA SRAM 2k */
0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU SRAM 2k */
- mbusc: mbus-ctrl@20000 {
- compatible = "marvell,mbus-controller";
- reg = <0x20000 0x80>, <0x800100 0x8>;
- };
-
- timer: timer@20300 {
- compatible = "marvell,orion-timer";
- reg = <0x20300 0x20>;
- interrupt-parent = <&bridge_intc>;
- interrupts = <1>, <2>;
+ spi0: spi-ctrl@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <6>;
+ reg = <0x10600 0x28>;
clocks = <&core_clk 0>;
+ pinctrl-0 = <&pmx_spi0>;
+ pinctrl-names = "default";
+ status = "disabled";
};
- intc: main-interrupt-ctrl@20200 {
- compatible = "marvell,orion-intc";
- interrupt-controller;
- #interrupt-cells = <1>;
- reg = <0x20200 0x10>, <0x20210 0x10>;
- };
-
- bridge_intc: bridge-interrupt-ctrl@20110 {
- compatible = "marvell,orion-bridge-intc";
- interrupt-controller;
- #interrupt-cells = <1>;
- reg = <0x20110 0x8>;
- interrupts = <0>;
- marvell,#interrupts = <5>;
- };
-
- core_clk: core-clocks@d0214 {
- compatible = "marvell,dove-core-clock";
- reg = <0xd0214 0x4>;
- #clock-cells = <1>;
- };
-
- gate_clk: clock-gating-ctrl@d0038 {
- compatible = "marvell,dove-gating-clock";
- reg = <0xd0038 0x4>;
+ i2c0: i2c-ctrl@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <11>;
+ clock-frequency = <400000>;
+ timeout-ms = <1000>;
clocks = <&core_clk 0>;
- #clock-cells = <1>;
- };
-
- thermal: thermal-diode@d001c {
- compatible = "marvell,dove-thermal";
- reg = <0xd001c 0x0c>, <0xd005c 0x08>;
+ status = "disabled";
};
uart0: serial@12000 {
status = "disabled";
};
- gpio0: gpio-ctrl@d0400 {
- compatible = "marvell,orion-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- reg = <0xd0400 0x20>;
- ngpios = <32>;
+ spi1: spi-ctrl@14600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <5>;
+ reg = <0x14600 0x28>;
+ clocks = <&core_clk 0>;
+ status = "disabled";
+ };
+
+ mbusc: mbus-ctrl@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x80>, <0x800100 0x8>;
+ };
+
+ bridge_intc: bridge-interrupt-ctrl@20110 {
+ compatible = "marvell,orion-bridge-intc";
interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <12>, <13>, <14>, <60>;
+ #interrupt-cells = <1>;
+ reg = <0x20110 0x8>;
+ interrupts = <0>;
+ marvell,#interrupts = <5>;
};
- gpio1: gpio-ctrl@d0420 {
- compatible = "marvell,orion-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- reg = <0xd0420 0x20>;
- ngpios = <32>;
+ intc: main-interrupt-ctrl@20200 {
+ compatible = "marvell,orion-intc";
interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <61>;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x10>, <0x20210 0x10>;
};
- gpio2: gpio-ctrl@e8400 {
- compatible = "marvell,orion-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- reg = <0xe8400 0x0c>;
- ngpios = <8>;
+ timer: timer@20300 {
+ compatible = "marvell,orion-timer";
+ reg = <0x20300 0x20>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <1>, <2>;
+ clocks = <&core_clk 0>;
+ };
+
+ crypto: crypto-engine@30000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x30000 0x10000>,
+ <0xffffe000 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <31>;
+ clocks = <&gate_clk 15>;
+ status = "okay";
+ };
+
+ ehci0: usb-host@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <24>;
+ clocks = <&gate_clk 0>;
+ status = "okay";
+ };
+
+ ehci1: usb-host@51000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x51000 0x1000>;
+ interrupts = <25>;
+ clocks = <&gate_clk 1>;
+ status = "okay";
+ };
+
+ xor0: dma-engine@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60a00 0x100>;
+ clocks = <&gate_clk 23>;
+ status = "okay";
+
+ channel0 {
+ interrupts = <39>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+
+ channel1 {
+ interrupts = <40>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ };
+
+ xor1: dma-engine@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gate_clk 24>;
+ status = "okay";
+
+ channel0 {
+ interrupts = <42>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+
+ channel1 {
+ interrupts = <43>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ };
+
+ sdio1: sdio-host@90000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x90000 0x100>;
+ interrupts = <36>, <38>;
+ clocks = <&gate_clk 9>;
+ pinctrl-0 = <&pmx_sdio1>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ eth: ethernet-ctrl@72000 {
+ compatible = "marvell,orion-eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72000 0x4000>;
+ clocks = <&gate_clk 2>;
+ marvell,tx-checksum-limit = <1600>;
+ status = "disabled";
+
+ ethernet-port@0 {
+ device_type = "network";
+ compatible = "marvell,orion-eth-port";
+ reg = <0>;
+ interrupts = <29>;
+ /* overwrite MAC address in bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ phy-handle = <ðphy>;
+ };
+ };
+
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <30>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+
+ ethphy: ethernet-phy {
+ device_type = "ethernet-phy";
+ /* set phy address in board file */
+ };
+ };
+
+ sdio0: sdio-host@92000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x92000 0x100>;
+ interrupts = <35>, <37>;
+ clocks = <&gate_clk 8>;
+ pinctrl-0 = <&pmx_sdio0>;
+ pinctrl-names = "default";
+ status = "disabled";
+ };
+
+ sata0: sata-host@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x2400>;
+ interrupts = <62>;
+ clocks = <&gate_clk 3>;
+ phys = <&sata_phy0>;
+ phy-names = "port0";
+ nr-ports = <1>;
+ status = "disabled";
+ };
+
+ sata_phy0: sata-phy@a2000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0xa2000 0x0334>;
+ clocks = <&gate_clk 3>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
+
+ audio0: audio-controller@b0000 {
+ compatible = "marvell,dove-audio";
+ reg = <0xb0000 0x2210>;
+ interrupts = <19>, <20>;
+ clocks = <&gate_clk 12>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+
+ audio1: audio-controller@b4000 {
+ compatible = "marvell,dove-audio";
+ reg = <0xb4000 0x2210>;
+ interrupts = <21>, <22>;
+ clocks = <&gate_clk 13>;
+ clock-names = "internal";
+ status = "disabled";
+ };
+
+ thermal: thermal-diode@d001c {
+ compatible = "marvell,dove-thermal";
+ reg = <0xd001c 0x0c>, <0xd005c 0x08>;
+ };
+
+ gate_clk: clock-gating-ctrl@d0038 {
+ compatible = "marvell,dove-gating-clock";
+ reg = <0xd0038 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
+ pmu_intc: pmu-interrupt-ctrl@d0050 {
+ compatible = "marvell,dove-pmu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd0050 0x8>;
+ interrupts = <33>;
+ marvell,#interrupts = <7>;
};
pinctrl: pin-ctrl@d0200 {
};
};
- spi0: spi-ctrl@10600 {
- compatible = "marvell,orion-spi";
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- interrupts = <6>;
- reg = <0x10600 0x28>;
- clocks = <&core_clk 0>;
- pinctrl-0 = <&pmx_spi0>;
- pinctrl-names = "default";
- status = "disabled";
- };
-
- spi1: spi-ctrl@14600 {
- compatible = "marvell,orion-spi";
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- interrupts = <5>;
- reg = <0x14600 0x28>;
- clocks = <&core_clk 0>;
- status = "disabled";
- };
-
- i2c0: i2c-ctrl@11000 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0x11000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <11>;
- clock-frequency = <400000>;
- timeout-ms = <1000>;
- clocks = <&core_clk 0>;
- status = "disabled";
- };
-
- ehci0: usb-host@50000 {
- compatible = "marvell,orion-ehci";
- reg = <0x50000 0x1000>;
- interrupts = <24>;
- clocks = <&gate_clk 0>;
- status = "okay";
- };
-
- ehci1: usb-host@51000 {
- compatible = "marvell,orion-ehci";
- reg = <0x51000 0x1000>;
- interrupts = <25>;
- clocks = <&gate_clk 1>;
- status = "okay";
- };
-
- sdio0: sdio-host@92000 {
- compatible = "marvell,dove-sdhci";
- reg = <0x92000 0x100>;
- interrupts = <35>, <37>;
- clocks = <&gate_clk 8>;
- pinctrl-0 = <&pmx_sdio0>;
- pinctrl-names = "default";
- status = "disabled";
+ core_clk: core-clocks@d0214 {
+ compatible = "marvell,dove-core-clock";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
};
- sdio1: sdio-host@90000 {
- compatible = "marvell,dove-sdhci";
- reg = <0x90000 0x100>;
- interrupts = <36>, <38>;
- clocks = <&gate_clk 9>;
- pinctrl-0 = <&pmx_sdio1>;
- pinctrl-names = "default";
- status = "disabled";
+ gpio0: gpio-ctrl@d0400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0400 0x20>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <12>, <13>, <14>, <60>;
};
- sata0: sata-host@a0000 {
- compatible = "marvell,orion-sata";
- reg = <0xa0000 0x2400>;
- interrupts = <62>;
- clocks = <&gate_clk 3>;
- nr-ports = <1>;
- status = "disabled";
+ gpio1: gpio-ctrl@d0420 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0420 0x20>;
+ ngpios = <32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <61>;
};
rtc: real-time-clock@d8500 {
compatible = "marvell,orion-rtc";
reg = <0xd8500 0x20>;
+ interrupt-parent = <&pmu_intc>;
+ interrupts = <5>;
};
- crypto: crypto-engine@30000 {
- compatible = "marvell,orion-crypto";
- reg = <0x30000 0x10000>,
- <0xffffe000 0x800>;
- reg-names = "regs", "sram";
- interrupts = <31>;
- clocks = <&gate_clk 15>;
- status = "okay";
- };
-
- xor0: dma-engine@60800 {
- compatible = "marvell,orion-xor";
- reg = <0x60800 0x100
- 0x60a00 0x100>;
- clocks = <&gate_clk 23>;
- status = "okay";
-
- channel0 {
- interrupts = <39>;
- dmacap,memcpy;
- dmacap,xor;
- };
-
- channel1 {
- interrupts = <40>;
- dmacap,memcpy;
- dmacap,xor;
- };
- };
-
- xor1: dma-engine@60900 {
- compatible = "marvell,orion-xor";
- reg = <0x60900 0x100
- 0x60b00 0x100>;
- clocks = <&gate_clk 24>;
- status = "okay";
-
- channel0 {
- interrupts = <42>;
- dmacap,memcpy;
- dmacap,xor;
- };
-
- channel1 {
- interrupts = <43>;
- dmacap,memcpy;
- dmacap,xor;
- };
- };
-
- mdio: mdio-bus@72004 {
- compatible = "marvell,orion-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x72004 0x84>;
- interrupts = <30>;
- clocks = <&gate_clk 2>;
- status = "disabled";
-
- ethphy: ethernet-phy {
- device-type = "ethernet-phy";
- /* set phy address in board file */
- };
- };
-
- eth: ethernet-ctrl@72000 {
- compatible = "marvell,orion-eth";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x72000 0x4000>;
- clocks = <&gate_clk 2>;
- marvell,tx-checksum-limit = <1600>;
- status = "disabled";
-
- ethernet-port@0 {
- device_type = "network";
- compatible = "marvell,orion-eth-port";
- reg = <0>;
- interrupts = <29>;
- /* overwrite MAC address in bootloader */
- local-mac-address = [00 00 00 00 00 00];
- phy-handle = <ðphy>;
- };
- };
-
- audio0: audio-controller@b0000 {
- compatible = "marvell,dove-audio";
- reg = <0xb0000 0x2210>;
- interrupts = <19>, <20>;
- clocks = <&gate_clk 12>;
- clock-names = "internal";
- status = "disabled";
- };
-
- audio1: audio-controller@b4000 {
- compatible = "marvell,dove-audio";
- reg = <0xb4000 0x2210>;
- interrupts = <21>, <22>;
- clocks = <&gate_clk 13>;
- clock-names = "internal";
- status = "disabled";
+ gpio2: gpio-ctrl@e8400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xe8400 0x0c>;
+ ngpios = <8>;
};
};
};
*/
/dts-v1/;
-/include/ "emev2.dtsi"
+#include "emev2.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "EMEV2 KZM9D Board";
reg = <0x20000000 0x10000>;
phy-mode = "mii";
interrupt-parent = <&gpio0>;
- interrupts = <1 1>; /* active high */
+ interrupts = <1 IRQ_TYPE_EDGE_RISING>;
reg-io-width = <4>;
smsc,irq-active-high;
smsc,irq-push-pull;
vddvario-supply = <®_1p8v>;
vdd33a-supply = <®_3p3v>;
};
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-1";
+ linux,code = <KEY_1>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ button@2 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-2";
+ linux,code = <KEY_2>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ button@3 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-3";
+ linux,code = <KEY_3>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ };
+ button@4 {
+ debounce_interval = <50>;
+ wakeup = <1>;
+ label = "DSW2-4";
+ linux,code = <KEY_4>;
+ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
};
* kind, whether express or implied.
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
compatible = "renesas,emev2";
pmu {
compatible = "arm,cortex-a9-pmu";
- interrupts = <0 120 4>,
- <0 121 4>;
+ interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ smu@e0110000 {
+ compatible = "renesas,emev2-smu";
+ reg = <0xe0110000 0x10000>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ c32ki: c32ki {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ #clock-cells = <0>;
+ };
+ pll3_fo: pll3_fo {
+ compatible = "fixed-factor-clock";
+ clocks = <&c32ki>;
+ clock-div = <1>;
+ clock-mult = <7000>;
+ #clock-cells = <0>;
+ };
+ usia_u0_sclkdiv: usia_u0_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x610 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u1_sclkdiv: usib_u1_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x65c 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u2_sclkdiv: usib_u2_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x65c 16>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usib_u3_sclkdiv: usib_u3_sclkdiv {
+ compatible = "renesas,emev2-smu-clkdiv";
+ reg = <0x660 0>;
+ clocks = <&pll3_fo>;
+ #clock-cells = <0>;
+ };
+ usia_u0_sclk: usia_u0_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4a0 1>;
+ clocks = <&usia_u0_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u1_sclk: usib_u1_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4b8 1>;
+ clocks = <&usib_u1_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u2_sclk: usib_u2_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4bc 1>;
+ clocks = <&usib_u2_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ usib_u3_sclk: usib_u3_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x4c0 1>;
+ clocks = <&usib_u3_sclkdiv>;
+ #clock-cells = <0>;
+ };
+ sti_sclk: sti_sclk {
+ compatible = "renesas,emev2-smu-gclk";
+ reg = <0x528 1>;
+ clocks = <&c32ki>;
+ #clock-cells = <0>;
+ };
};
sti@e0180000 {
compatible = "renesas,em-sti";
reg = <0xe0180000 0x54>;
- interrupts = <0 125 0>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sti_sclk>;
+ clock-names = "sclk";
};
uart@e1020000 {
compatible = "renesas,em-uart";
reg = <0xe1020000 0x38>;
- interrupts = <0 8 0>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usia_u0_sclk>;
+ clock-names = "sclk";
};
uart@e1030000 {
compatible = "renesas,em-uart";
reg = <0xe1030000 0x38>;
- interrupts = <0 9 0>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u1_sclk>;
+ clock-names = "sclk";
};
uart@e1040000 {
compatible = "renesas,em-uart";
reg = <0xe1040000 0x38>;
- interrupts = <0 10 0>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u2_sclk>;
+ clock-names = "sclk";
};
uart@e1050000 {
compatible = "renesas,em-uart";
reg = <0xe1050000 0x38>;
- interrupts = <0 11 0>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usib_u3_sclk>;
+ clock-names = "sclk";
};
gpio0: gpio@e0050000 {
compatible = "renesas,em-gio";
reg = <0xe0050000 0x2c>, <0xe0050040 0x20>;
- interrupts = <0 67 0>, <0 68 0>;
+ interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>,
+ <0 68 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
gpio1: gpio@e0050080 {
compatible = "renesas,em-gio";
reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>;
- interrupts = <0 69 0>, <0 70 0>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>,
+ <0 70 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
gpio2: gpio@e0050100 {
compatible = "renesas,em-gio";
reg = <0xe0050100 0x2c>, <0xe0050140 0x20>;
- interrupts = <0 71 0>, <0 72 0>;
+ interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>,
+ <0 72 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
gpio3: gpio@e0050180 {
compatible = "renesas,em-gio";
reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>;
- interrupts = <0 73 0>, <0 74 0>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>,
+ <0 74 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
gpio4: gpio@e0050200 {
compatible = "renesas,em-gio";
reg = <0xe0050200 0x2c>, <0xe0050240 0x20>;
- interrupts = <0 75 0>, <0 76 0>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>,
+ <0 76 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <31>;
reg = <0x10023CE0 0x20>;
};
- gic:interrupt-controller@10490000 {
+ gic: interrupt-controller@10490000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x10490000 0x1000>, <0x10480000 0x100>;
};
- combiner:interrupt-controller@10440000 {
+ combiner: interrupt-controller@10440000 {
compatible = "samsung,exynos4210-combiner";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0x10440000 0x1000>;
};
- sys_reg: sysreg {
+ sys_reg: syscon@10010000 {
compatible = "samsung,exynos4-sysreg", "syscon";
reg = <0x10010000 0x400>;
};
display-timings {
native-mode = <&timing0>;
timing0: timing {
- clock-frequency = <50000>;
+ clock-frequency = <47500000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <64>;
reg = <0x10023CA0 0x20>;
};
- gic:interrupt-controller@10490000 {
+ gic: interrupt-controller@10490000 {
cpu-offset = <0x8000>;
};
- combiner:interrupt-controller@10440000 {
+ combiner: interrupt-controller@10440000 {
samsung,combiner-nr = <16>;
interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
<0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
mct@10050000 {
compatible = "samsung,exynos4210-mct";
reg = <0x10050000 0x800>;
- interrupt-controller;
- #interrups-cells = <2>;
interrupt-parent = <&mct_map>;
- interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
- <4 0>, <5 0>;
+ interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
clocks = <&clock 3>, <&clock 344>;
clock-names = "fin_pll", "mct";
mct_map: mct-map {
- #interrupt-cells = <2>;
+ #interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
- interrupt-map = <0x0 0 &gic 0 57 0>,
- <0x1 0 &gic 0 69 0>,
- <0x2 0 &combiner 12 6>,
- <0x3 0 &combiner 12 7>,
- <0x4 0 &gic 0 42 0>,
- <0x5 0 &gic 0 48 0>;
+ interrupt-map = <0 &gic 0 57 0>,
+ <1 &gic 0 69 0>,
+ <2 &combiner 12 6>,
+ <3 &combiner 12 7>,
+ <4 &gic 0 42 0>,
+ <5 &gic 0 48 0>;
};
};
/ {
compatible = "samsung,exynos4212";
- gic:interrupt-controller@10490000 {
+ gic: interrupt-controller@10490000 {
cpu-offset = <0x8000>;
};
<0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
<0 107 0>, <0 108 0>;
};
-
- mct@10050000 {
- compatible = "samsung,exynos4412-mct";
- reg = <0x10050000 0x800>;
- interrupt-controller;
- #interrups-cells = <2>;
- interrupt-parent = <&mct_map>;
- interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
- <4 0>, <5 0>;
-
- mct_map: mct-map {
- #interrupt-cells = <2>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = <0x0 0 &gic 0 57 0>,
- <0x1 0 &combiner 12 5>,
- <0x2 0 &combiner 12 6>,
- <0x3 0 &combiner 12 7>,
- <0x4 0 &gic 1 12 0>,
- <0x5 0 &gic 1 12 0>;
- };
- };
};
};
};
- mshc@12550000 {
- #address-cells = <1>;
- #size-cells = <0>;
+ mmc@12550000 {
pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
pinctrl-names = "default";
vmmc-supply = <&ldo20_reg &buck8_reg>;
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
status = "okay";
};
- mshc@12550000 {
- #address-cells = <1>;
- #size-cells = <0>;
+ mmc@12550000 {
pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
pinctrl-names = "default";
status = "okay";
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
display-timings {
native-mode = <&timing0>;
timing0: timing {
- clock-frequency = <50000>;
+ clock-frequency = <47500000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <64>;
--- /dev/null
+/*
+ * FriendlyARM's Exynos4412 based TINY4412 board device tree source
+ *
+ * Copyright (c) 2013 Alex Ling <kasimling@gmail.com>
+ *
+ * Device tree source file for FriendlyARM's TINY4412 board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+
+/ {
+ model = "FriendlyARM TINY4412 board based on Exynos4412";
+ compatible = "friendlyarm,tiny4412", "samsung,exynos4412";
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ label = "led1";
+ gpios = <&gpm4 0 1>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led2 {
+ label = "led2";
+ gpios = <&gpm4 1 1>;
+ default-state = "off";
+ };
+
+ led3 {
+ label = "led3";
+ gpios = <&gpm4 2 1>;
+ default-state = "off";
+ };
+
+ led4 {
+ label = "led4";
+ gpios = <&gpm4 3 1>;
+ default-state = "off";
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ rtc@10070000 {
+ status = "okay";
+ };
+
+ sdhci@12530000 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ serial@13800000 {
+ status = "okay";
+ };
+
+ serial@13810000 {
+ status = "okay";
+ };
+
+ serial@13820000 {
+ status = "okay";
+ };
+
+ serial@13830000 {
+ status = "okay";
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+};
};
};
- sdhci@12510000 {
- bus-width = <8>;
+ mmc@12550000 {
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
non-removable;
- pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
- pinctrl-names = "default";
+ card-detect-delay = <200>;
vmmc-supply = <&vemmc_reg>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <0>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+ pinctrl-names = "default";
status = "okay";
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ };
};
serial@13800000 {
/ {
compatible = "samsung,exynos4412";
- gic:interrupt-controller@10490000 {
+ gic: interrupt-controller@10490000 {
cpu-offset = <0x4000>;
};
<0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
};
- mct@10050000 {
- compatible = "samsung,exynos4412-mct";
- reg = <0x10050000 0x800>;
- interrupt-controller;
- #interrups-cells = <2>;
- interrupt-parent = <&mct_map>;
- interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
- <4 0>, <5 0>, <6 0>, <7 0>;
- clocks = <&clock 3>, <&clock 344>;
- clock-names = "fin_pll", "mct";
-
- mct_map: mct-map {
- #interrupt-cells = <2>;
- #address-cells = <0>;
- #size-cells = <0>;
- interrupt-map = <0x0 0 &gic 0 57 0>,
- <0x1 0 &combiner 12 5>,
- <0x2 0 &combiner 12 6>,
- <0x3 0 &combiner 12 7>,
- <0x4 0 &gic 1 12 0>,
- <0x5 0 &gic 1 12 0>,
- <0x6 0 &gic 1 12 0>,
- <0x7 0 &gic 1 12 0>;
- };
- };
-
- mshc@12550000 {
- compatible = "samsung,exynos4412-dw-mshc";
- reg = <0x12550000 0x1000>;
- interrupts = <0 77 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
};
pinctrl3 = &pinctrl_3;
fimc-lite0 = &fimc_lite_0;
fimc-lite1 = &fimc_lite_1;
+ mshc0 = &mshc_0;
};
pd_isp: isp-power-domain@10023CA0 {
#clock-cells = <1>;
};
+ mct@10050000 {
+ compatible = "samsung,exynos4412-mct";
+ reg = <0x10050000 0x800>;
+ interrupt-parent = <&mct_map>;
+ interrupts = <0>, <1>, <2>, <3>, <4>;
+ clocks = <&clock 3>, <&clock 344>;
+ clock-names = "fin_pll", "mct";
+
+ mct_map: mct-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &gic 0 57 0>,
+ <1 &combiner 12 5>,
+ <2 &combiner 12 6>,
+ <3 &combiner 12 7>,
+ <4 &gic 1 12 0>;
+ };
+ };
+
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,exynos4x12-pinctrl";
reg = <0x11400000 0x1000>;
};
};
};
+
+ mshc_0: mmc@12550000 {
+ compatible = "samsung,exynos4412-dw-mshc";
+ reg = <0x12550000 0x1000>;
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fifo-depth = <0x80>;
+ clocks = <&clock 301>, <&clock 149>;
+ clock-names = "biu", "ciu";
+ status = "disabled";
+ };
};
reg = <0x10000000 0x100>;
};
- combiner:interrupt-controller@10440000 {
+ combiner: interrupt-controller@10440000 {
compatible = "samsung,exynos4210-combiner";
#interrupt-cells = <2>;
interrupt-controller;
<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
};
- gic:interrupt-controller@10481000 {
+ gic: interrupt-controller@10481000 {
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
interrupts = <1 9 0xf04>;
};
- dwmmc_0: dwmmc0@12200000 {
- compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 75 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- dwmmc_1: dwmmc1@12210000 {
- compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 76 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- dwmmc_2: dwmmc2@12220000 {
- compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 77 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
serial@12C00000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C00000 0x100>;
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <20000>;
samsung,i2c-slave-addr = <0x66>;
+ status = "okay";
s5m8767_pmic@66 {
compatible = "samsung,s5m8767-pmic";
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
- regulator-min-microvolt = <925000>;
+ regulator-min-microvolt = <912500>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
buck7_reg: BUCK7 {
regulator-name = "PVDD_BUCK7";
regulator-always-on;
+ op_mode = <1>;
};
buck8_reg: BUCK8 {
regulator-name = "PVDD_BUCK8";
regulator-always-on;
+ op_mode = <1>;
};
buck9_reg: BUCK9 {
};
};
- i2c@12C70000 {
- status = "disabled";
- };
-
i2c@12C80000 {
+ status = "okay";
+
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
samsung,i2c-slave-addr = <0x50>;
};
i2c@12C90000 {
+ status = "okay";
+
wm1811a@1a {
+
compatible = "wlf,wm1811";
reg = <0x1a>;
};
};
- i2c@12CA0000 {
- status = "disabled";
- };
-
- i2c@12CB0000 {
- status = "disabled";
- };
-
- i2c@12CC0000 {
- status = "disabled";
- };
-
- i2c@12CD0000 {
- status = "disabled";
- };
-
i2c@12CE0000 {
+ status = "okay";
+
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
samsung,i2c-slave-addr = <0x38>;
};
};
- i2c@121D0000 {
- status = "disabled";
- };
-
- dwmmc_0: dwmmc0@12200000 {
+ mmc_0: mmc@12200000 {
+ status = "okay";
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc_1: dwmmc1@12210000 {
- status = "disabled";
- };
-
- dwmmc_2: dwmmc2@12220000 {
+ mmc_2: mmc@12220000 {
+ status = "okay";
num-slots = <1>;
supports-highspeed;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc_3: dwmmc3@12230000 {
- status = "disabled";
- };
-
i2s0: i2s@03830000 {
status = "okay";
};
- spi_0: spi@12d20000 {
- status = "disabled";
- };
-
- spi_1: spi@12d30000 {
- status = "disabled";
- };
-
- spi_2: spi@12d40000 {
- status = "disabled";
- };
-
gpio_keys {
compatible = "gpio-keys";
i2c2_bus: i2c2-bus {
samsung,pin-pud = <0>;
};
+
+ max77686_irq: max77686-irq {
+ samsung,pins = "gpx3-2";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
};
i2c@12C60000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <378000>;
max77686@09 {
compatible = "maxim,max77686";
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77686_irq>;
+ wakeup-source;
reg = <0x09>;
voltage-regulators {
};
i2c@12C70000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <378000>;
};
i2c@12C80000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
};
i2c@12C90000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
};
i2c@12CA0000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
};
i2c@12CB0000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
};
- i2c@12CC0000 {
- status = "disabled";
- };
-
i2c@12CD0000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
};
i2c@12CE0000 {
+ status = "okay";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <378000>;
};
};
- dwmmc0@12200000 {
+ mmc@12200000 {
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc1@12210000 {
- status = "disabled";
- };
-
- dwmmc2@12220000 {
+ mmc@12220000 {
num-slots = <1>;
supports-highspeed;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc3@12230000 {
+ mmc@12230000 {
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- spi_0: spi@12d20000 {
- status = "disabled";
- };
-
spi_1: spi@12d30000 {
+ status = "okay";
samsung,spi-src-clk = <0>;
num-cs = <1>;
};
- spi_2: spi@12d40000 {
- status = "disabled";
- };
-
hdmi {
hpd-gpio = <&gpx3 7 0>;
};
i2c@12C60000 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <20000>;
+ status = "okay";
eeprom@50 {
compatible = "samsung,s524ad0xd1";
};
};
- vdd:fixed-regulator@0 {
+ vdd: fixed-regulator@0 {
compatible = "regulator-fixed";
regulator-name = "vdd-supply";
regulator-min-microvolt = <1800000>;
regulator-always-on;
};
- dbvdd:fixed-regulator@1 {
+ dbvdd: fixed-regulator@1 {
compatible = "regulator-fixed";
regulator-name = "dbvdd-supply";
regulator-min-microvolt = <3300000>;
regulator-always-on;
};
- spkvdd:fixed-regulator@2 {
+ spkvdd: fixed-regulator@2 {
compatible = "regulator-fixed";
regulator-name = "spkvdd-supply";
regulator-min-microvolt = <5000000>;
i2c@12C70000 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <20000>;
+ status = "okay";
eeprom@51 {
compatible = "samsung,s524ad0xd1";
gpio-controller;
#gpio-cells = <2>;
+ clocks = <&codec_mclk>;
+ clock-names = "MCLK1";
+
AVDD2-supply = <&vdd>;
CPVDD-supply = <&vdd>;
DBVDD-supply = <&dbvdd>;
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <40000>;
samsung,i2c-slave-addr = <0x38>;
+ status = "okay";
sata-phy {
compatible = "samsung,sata-phy";
i2c@12C80000 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
+ status = "okay";
hdmiddc@50 {
compatible = "samsung,exynos4210-hdmiddc";
};
};
- i2c@12C90000 {
- status = "disabled";
- };
-
- i2c@12CA0000 {
- status = "disabled";
- };
-
- i2c@12CB0000 {
- status = "disabled";
- };
-
- i2c@12CC0000 {
- status = "disabled";
- };
-
- i2c@12CD0000 {
- status = "disabled";
- };
-
i2c@12CE0000 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
+ status = "okay";
hdmiphy@38 {
compatible = "samsung,exynos4212-hdmiphy";
};
};
- dwmmc0@12200000 {
+ mmc@12200000 {
+ status = "okay";
num-slots = <1>;
supports-highspeed;
broken-cd;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc1@12210000 {
- status = "disabled";
- };
-
- dwmmc2@12220000 {
+ mmc@12220000 {
+ status = "okay";
num-slots = <1>;
supports-highspeed;
- fifo-depth = <0x80>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <2 3>;
};
};
- dwmmc3@12230000 {
- status = "disabled";
- };
-
spi_0: spi@12d20000 {
status = "disabled";
};
spi_1: spi@12d30000 {
+ status = "okay";
+
w25q80bw@0 {
#address-cells = <1>;
#size-cells = <1>;
};
};
- spi_2: spi@12d40000 {
- status = "disabled";
- };
-
hdmi {
hpd-gpio = <&gpx3 7 0>;
};
compatible = "samsung,clock-xxti";
clock-frequency = <24000000>;
};
+
+ codec_mclk: codec-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16934000>;
+ };
};
};
/dts-v1/;
#include "exynos5250.dtsi"
-#include "cros5250-common.dtsi"
+#include "exynos5250-cros-common.dtsi"
/ {
model = "Google Snow";
keypad,num-rows = <8>;
keypad,num-columns = <13>;
google,needs-ghost-filter;
- linux,keymap = <0x0001003a /* CAPSLK */
+ linux,keymap = <0x0001007d /* L_META */
0x0002003b /* F1 */
0x00030030 /* B */
0x00040044 /* F10 */
0x04060024 /* J */
0x04080027 /* ; */
0x04090026 /* L */
+ 0x040a002b /* \ */
0x040b001c /* ENTER */
0x0501002c /* Z */
};
};
+ mmc@12200000 {
+ status = "okay";
+ };
+
+ mmc@12220000 {
+ status = "okay";
+ };
+
/*
* On Snow we've got SIP WiFi and so can keep drive strengths low to
* reduce EMI.
*/
- dwmmc3@12230000 {
+ mmc@12230000 {
+ status = "okay";
slot@0 {
pinctrl-names = "default";
pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
gsc1 = &gsc_1;
gsc2 = &gsc_2;
gsc3 = &gsc_3;
- mshc0 = &dwmmc_0;
- mshc1 = &dwmmc_1;
- mshc2 = &dwmmc_2;
- mshc3 = &dwmmc_3;
+ mshc0 = &mmc_0;
+ mshc1 = &mmc_1;
+ mshc2 = &mmc_2;
+ mshc3 = &mmc_3;
i2c0 = &i2c_0;
i2c1 = &i2c_1;
i2c2 = &i2c_2;
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0>;
+ clock-frequency = <1700000000>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <1>;
+ clock-frequency = <1700000000>;
};
};
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c0_bus>;
+ status = "disabled";
};
i2c_1: i2c@12C70000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_bus>;
+ status = "disabled";
};
i2c_2: i2c@12C80000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c2_bus>;
+ status = "disabled";
};
i2c_3: i2c@12C90000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c3_bus>;
+ status = "disabled";
};
i2c_4: i2c@12CA0000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c4_bus>;
+ status = "disabled";
};
i2c_5: i2c@12CB0000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c5_bus>;
+ status = "disabled";
};
i2c_6: i2c@12CC0000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c6_bus>;
+ status = "disabled";
};
i2c_7: i2c@12CD0000 {
clock-names = "i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c7_bus>;
+ status = "disabled";
};
i2c_8: i2c@12CE0000 {
#size-cells = <0>;
clocks = <&clock 302>;
clock-names = "i2c";
+ status = "disabled";
};
i2c@121D0000 {
#size-cells = <0>;
clocks = <&clock 288>;
clock-names = "i2c";
+ status = "disabled";
};
spi_0: spi@12d20000 {
compatible = "samsung,exynos4210-spi";
+ status = "disabled";
reg = <0x12d20000 0x100>;
interrupts = <0 66 0>;
dmas = <&pdma0 5
spi_1: spi@12d30000 {
compatible = "samsung,exynos4210-spi";
+ status = "disabled";
reg = <0x12d30000 0x100>;
interrupts = <0 67 0>;
dmas = <&pdma1 5
spi_2: spi@12d40000 {
compatible = "samsung,exynos4210-spi";
+ status = "disabled";
reg = <0x12d40000 0x100>;
interrupts = <0 68 0>;
dmas = <&pdma0 7
pinctrl-0 = <&spi2_bus>;
};
- dwmmc_0: dwmmc0@12200000 {
+ mmc_0: mmc@12200000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0x12200000 0x1000>;
clocks = <&clock 280>, <&clock 139>;
clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
};
- dwmmc_1: dwmmc1@12210000 {
+ mmc_1: mmc@12210000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 76 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0x12210000 0x1000>;
clocks = <&clock 281>, <&clock 140>;
clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
};
- dwmmc_2: dwmmc2@12220000 {
+ mmc_2: mmc@12220000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0x12220000 0x1000>;
clocks = <&clock 282>, <&clock 141>;
clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
};
- dwmmc_3: dwmmc3@12230000 {
+ mmc_3: mmc@12230000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12230000 0x1000>;
interrupts = <0 78 0>;
#size-cells = <0>;
clocks = <&clock 283>, <&clock 142>;
clock-names = "biu", "ciu";
+ fifo-depth = <0x80>;
+ status = "disabled";
};
i2s0: i2s@03830000 {
};
};
+ pwm: pwm@12dd0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x12dd0000 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock 311>;
+ clock-names = "timers";
+ };
+
amba {
#address-cells = <1>;
#size-cells = <1>;
--- /dev/null
+/*
+ * Samsung's Exynos5420 based Arndale Octa board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+
+/ {
+ model = "Insignal Arndale Octa evaluation board based on EXYNOS5420";
+ compatible = "insignal,arndale-octa", "samsung,exynos5420";
+
+ memory {
+ reg = <0x20000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC3,115200";
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ mmc@12200000 {
+ status = "okay";
+ broken-cd;
+ supports-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ };
+ };
+
+ mmc@12220000 {
+ status = "okay";
+ supports-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+};
samsung,pins = "gpx0-7";
samsung,pin-function = <3>;
samsung,pin-pud = <0>;
- samaung,pin-drv = <0>;
+ samsung,pin-drv = <0>;
};
};
};
};
+ mmc@12200000 {
+ status = "okay";
+ broken-cd;
+ supports-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ };
+ };
+
+ mmc@12220000 {
+ status = "okay";
+ supports-highspeed;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ };
+ };
+
dp-controller@145B0000 {
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>;
compatible = "samsung,exynos5420";
aliases {
+ mshc0 = &mmc_0;
+ mshc1 = &mmc_1;
+ mshc2 = &mmc_2;
pinctrl0 = &pinctrl_0;
pinctrl1 = &pinctrl_1;
pinctrl2 = &pinctrl_2;
i2c1 = &i2c_1;
i2c2 = &i2c_2;
i2c3 = &i2c_3;
+ i2c4 = &hsi2c_4;
+ i2c5 = &hsi2c_5;
+ i2c6 = &hsi2c_6;
+ i2c7 = &hsi2c_7;
+ i2c8 = &hsi2c_8;
+ i2c9 = &hsi2c_9;
+ i2c10 = &hsi2c_10;
+ gsc0 = &gsc_0;
+ gsc1 = &gsc_1;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
};
cpus {
reg = <0x3>;
clock-frequency = <1800000000>;
};
+
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ clock-frequency = <1000000000>;
+ };
+
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ clock-frequency = <1000000000>;
+ };
+
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x102>;
+ clock-frequency = <1000000000>;
+ };
+
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x103>;
+ clock-frequency = <1000000000>;
+ };
};
clock: clock-controller@10010000 {
clock-names = "mfc";
};
+ mmc_0: mmc@12200000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12200000 0x2000>;
+ clocks = <&clock 351>, <&clock 132>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@12210000 {
+ compatible = "samsung,exynos5420-dw-mshc-smu";
+ interrupts = <0 76 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12210000 0x2000>;
+ clocks = <&clock 352>, <&clock 133>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@12220000 {
+ compatible = "samsung,exynos5420-dw-mshc";
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x12220000 0x1000>;
+ clocks = <&clock 353>, <&clock 134>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
mct@101C0000 {
compatible = "samsung,exynos4210-mct";
reg = <0x101C0000 0x800>;
interrupt-controller;
#interrups-cells = <1>;
interrupt-parent = <&mct_map>;
- interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>;
+ interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>,
+ <8>, <9>, <10>, <11>;
clocks = <&clock 1>, <&clock 315>;
clock-names = "fin_pll", "mct";
<4 &gic 0 120 0>,
<5 &gic 0 121 0>,
<6 &gic 0 122 0>,
- <7 &gic 0 123 0>;
+ <7 &gic 0 123 0>,
+ <8 &gic 0 128 0>,
+ <9 &gic 0 129 0>,
+ <10 &gic 0 130 0>,
+ <11 &gic 0 131 0>;
};
};
status = "okay";
};
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma0: pdma@121A0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121A0000 0x1000>;
+ interrupts = <0 34 0>;
+ clocks = <&clock 362>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@121B0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121B0000 0x1000>;
+ interrupts = <0 35 0>;
+ clocks = <&clock 363>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ mdma0: mdma@10800000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x10800000 0x1000>;
+ interrupts = <0 33 0>;
+ clocks = <&clock 473>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+
+ mdma1: mdma@11C10000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x11C10000 0x1000>;
+ interrupts = <0 124 0>;
+ clocks = <&clock 442>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <1>;
+ };
+ };
+
+ spi_0: spi@12d20000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d20000 0x100>;
+ interrupts = <0 66 0>;
+ dmas = <&pdma0 5
+ &pdma0 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ clocks = <&clock 271>, <&clock 135>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
+ spi_1: spi@12d30000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d30000 0x100>;
+ interrupts = <0 67 0>;
+ dmas = <&pdma1 5
+ &pdma1 4>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ clocks = <&clock 272>, <&clock 136>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
+ spi_2: spi@12d40000 {
+ compatible = "samsung,exynos4210-spi";
+ reg = <0x12d40000 0x100>;
+ interrupts = <0 68 0>;
+ dmas = <&pdma0 7
+ &pdma0 6>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ clocks = <&clock 273>, <&clock 137>;
+ clock-names = "spi", "spi_busclk0";
+ status = "disabled";
+ };
+
serial@12C00000 {
clocks = <&clock 257>, <&clock 128>;
clock-names = "uart", "clk_uart_baud0";
clock-names = "uart", "clk_uart_baud0";
};
+ pwm: pwm@12dd0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x12dd0000 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock 279>;
+ clock-names = "timers";
+ };
+
dp_phy: video-phy@10040728 {
compatible = "samsung,exynos5250-dp-video-phy";
reg = <0x10040728 4>;
status = "disabled";
};
+ hsi2c_4: i2c@12CA0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CA0000 0x1000>;
+ interrupts = <0 60 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_hs_bus>;
+ clocks = <&clock 265>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_5: i2c@12CB0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CB0000 0x1000>;
+ interrupts = <0 61 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_hs_bus>;
+ clocks = <&clock 266>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_6: i2c@12CC0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CC0000 0x1000>;
+ interrupts = <0 62 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_hs_bus>;
+ clocks = <&clock 267>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_7: i2c@12CD0000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12CD0000 0x1000>;
+ interrupts = <0 63 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_hs_bus>;
+ clocks = <&clock 268>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_8: i2c@12E00000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E00000 0x1000>;
+ interrupts = <0 87 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8_hs_bus>;
+ clocks = <&clock 281>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_9: i2c@12E10000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E10000 0x1000>;
+ interrupts = <0 88 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c9_hs_bus>;
+ clocks = <&clock 282>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_10: i2c@12E20000 {
+ compatible = "samsung,exynos5-hsi2c";
+ reg = <0x12E20000 0x1000>;
+ interrupts = <0 203 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c10_hs_bus>;
+ clocks = <&clock 283>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
hdmi@14530000 {
compatible = "samsung,exynos4212-hdmi";
reg = <0x14530000 0x70000>;
clocks = <&clock 431>, <&clock 143>;
clock-names = "mixer", "sclk_hdmi";
};
+
+ gsc_0: video-scaler@13e00000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e00000 0x1000>;
+ interrupts = <0 85 0>;
+ clocks = <&clock 465>;
+ clock-names = "gscl";
+ samsung,power-domain = <&gsc_pd>;
+ };
+
+ gsc_1: video-scaler@13e10000 {
+ compatible = "samsung,exynos5-gsc";
+ reg = <0x13e10000 0x1000>;
+ interrupts = <0 86 0>;
+ clocks = <&clock 466>;
+ clock-names = "gscl";
+ samsung,power-domain = <&gsc_pd>;
+ };
+
+ tmu_cpu0: tmu@10060000 {
+ compatible = "samsung,exynos5420-tmu";
+ reg = <0x10060000 0x100>;
+ interrupts = <0 65 0>;
+ clocks = <&clock 318>;
+ clock-names = "tmu_apbif";
+ };
+
+ tmu_cpu1: tmu@10064000 {
+ compatible = "samsung,exynos5420-tmu";
+ reg = <0x10064000 0x100>;
+ interrupts = <0 183 0>;
+ clocks = <&clock 318>;
+ clock-names = "tmu_apbif";
+ };
+
+ tmu_cpu2: tmu@10068000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x10068000 0x100>, <0x1006c000 0x4>;
+ interrupts = <0 184 0>;
+ clocks = <&clock 318>, <&clock 318>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ };
+
+ tmu_cpu3: tmu@1006c000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
+ interrupts = <0 185 0>;
+ clocks = <&clock 318>, <&clock 319>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ };
+
+ tmu_gpu: tmu@100a0000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x100a0000 0x100>, <0x10068000 0x4>;
+ interrupts = <0 215 0>;
+ clocks = <&clock 319>, <&clock 318>;
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ };
};
#clock-cells = <1>;
};
- gic:interrupt-controller@2E0000 {
+ gic: interrupt-controller@2E0000 {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
interrupt-controller;
clocks = <&clks 197>, <&clks 3>,
<&clks 197>, <&clks 107>,
<&clks 0>, <&clks 118>,
- <&clks 62>, <&clks 139>,
+ <&clks 0>, <&clks 139>,
<&clks 0>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
reg = <0x10000000 0x200>;
};
+ ebi@12000000 {
+ compatible = "arm,external-bus-interface";
+ reg = <0x12000000 0x100>;
+ };
+
timer@13000000 {
reg = <0x13000000 0x100>;
interrupt-parent = <&pic>;
--- /dev/null
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+
+/ {
+ compatible = "ti,keystone-evm";
+
+ soc {
+ clock {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-sys";
+ };
+
+ refclkpass: refclkpass {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-pass";
+ };
+
+ refclkarm: refclkarm {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "refclk-arm";
+ };
+
+ refclkddr3a: refclkddr3a {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3a";
+ };
+
+ refclkddr3b: refclkddr3b {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3b";
+ };
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
#size-cells = <1>;
ranges;
- refclkmain: refclkmain {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <122880000>;
- clock-output-names = "refclk-main";
- };
-
mainpllclk: mainpllclk@2310110 {
#clock-cells = <0>;
compatible = "ti,keystone,main-pll-clock";
- clocks = <&refclkmain>;
+ clocks = <&refclksys>;
reg = <0x02620350 4>, <0x02310110 4>;
reg-names = "control", "multiplier";
fixed-postdiv = <2>;
papllclk: papllclk@2620358 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-clock";
- clocks = <&refclkmain>;
+ clocks = <&refclkpass>;
clock-output-names = "pa-pll-clk";
reg = <0x02620358 4>;
reg-names = "control";
- fixed-postdiv = <6>;
};
- ddr3allclk: ddr3apllclk@2620360 {
+ ddr3apllclk: ddr3apllclk@2620360 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-clock";
- clocks = <&refclkmain>;
+ clocks = <&refclkddr3a>;
clock-output-names = "ddr-3a-pll-clk";
reg = <0x02620360 4>;
reg-names = "control";
- fixed-postdiv = <6>;
};
- ddr3bllclk: ddr3bpllclk@2620368 {
+ ddr3bpllclk: ddr3bpllclk@2620368 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-clock";
- clocks = <&refclkmain>;
+ clocks = <&refclkddr3b>;
clock-output-names = "ddr-3b-pll-clk";
reg = <0x02620368 4>;
reg-names = "control";
- fixed-postdiv = <6>;
};
armpllclk: armpllclk@2620370 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-clock";
- clocks = <&refclkmain>;
+ clocks = <&refclkarm>;
clock-output-names = "arm-pll-clk";
reg = <0x02620370 4>;
reg-names = "control";
- fixed-postdiv = <6>;
};
mainmuxclk: mainmuxclk@2310108 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-mux-clock";
- clocks = <&mainpllclk>, <&refclkmain>;
+ clocks = <&mainpllclk>, <&refclksys>;
reg = <0x02310108 4>;
bit-shift = <23>;
bit-mask = <1>;
clock-output-names = "chipclk13";
};
+ paclk13: paclk13 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&papllclk>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "paclk13";
+ };
+
chipclk14: chipclk14 {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
* published by the Free Software Foundation.
*/
-/dts-v1/;
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
/ {
model = "Texas Instruments Keystone 2 SoC";
- compatible = "ti,keystone-evm";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
#address-cells = <1>;
interrupt-controller;
reg = <0x0 0x02561000 0x0 0x1000>,
- <0x0 0x02562000 0x0 0x2000>;
+ <0x0 0x02562000 0x0 0x2000>,
+ <0x0 0x02564000 0x0 0x1000>,
+ <0x0 0x02566000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
};
timer {
interrupts = <GIC_SPI 300 IRQ_TYPE_EDGE_RISING>;
clocks = <&clkspi>;
};
+
+ usb_phy: usb_phy@2620738 {
+ compatible = "ti,keystone-usbphy";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2620738 32>;
+ status = "disabled";
+ };
+
+ usb: usb@2680000 {
+ compatible = "ti,keystone-dwc3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2680000 0x10000>;
+ clocks = <&clkusb>;
+ clock-names = "usb";
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ ranges;
+ status = "disabled";
+
+ dwc3@2690000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x2690000 0x70000>;
+ interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>;
+ usb-phy = <&usb_phy>, <&usb_phy>;
+ };
+ };
};
};
--- /dev/null
+/ {
+ mbus {
+ pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pinctrl@10000 {
+ compatible = "marvell,88f6192-pinctrl";
+ reg = <0x10000 0x20>;
+
+ pmx_nand: pmx-nand {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3",
+ "mpp4", "mpp5", "mpp18",
+ "mpp19";
+ marvell,function = "nand";
+ };
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp5", "mpp21", "mpp23";
+ marvell,function = "sata0";
+ };
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp4", "mpp20", "mpp22";
+ marvell,function = "sata1";
+ };
+ pmx_spi: pmx-spi {
+ marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3";
+ marvell,function = "spi";
+ };
+ pmx_twsi0: pmx-twsi0 {
+ marvell,pins = "mpp8", "mpp9";
+ marvell,function = "twsi0";
+ };
+ pmx_uart0: pmx-uart0 {
+ marvell,pins = "mpp10", "mpp11";
+ marvell,function = "uart0";
+ };
+ pmx_uart1: pmx-uart1 {
+ marvell,pins = "mpp13", "mpp14";
+ marvell,function = "uart1";
+ };
+ pmx_sdio: pmx-sdio {
+ marvell,pins = "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "sdio";
+ };
+ };
+
+ rtc@10300 {
+ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <53>;
+ clocks = <&gate_clk 7>;
+ };
+
+ sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <21>;
+ clocks = <&gate_clk 14>, <&gate_clk 15>;
+ clock-names = "0", "1";
+ status = "disabled";
+ };
+
+ mvsdio@90000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0x90000 0x200>;
+ interrupts = <28>;
+ clocks = <&gate_clk 4>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ status = "disabled";
+ };
+ };
+};
interrupts = <21>;
clocks = <&gate_clk 14>, <&gate_clk 15>;
clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
status = "disabled";
};
reg = <0x90000 0x200>;
interrupts = <28>;
clocks = <&gate_clk 4>;
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
bus-width = <4>;
cap-sdio-irq;
cap-sd-highspeed;
};
};
+ thermal@10078 {
+ compatible = "marvell,kirkwood-thermal";
+ reg = <0x10078 0x4>;
+ status = "okay";
+ };
+
rtc@10300 {
compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
reg = <0x10300 0x20>;
clocks = <&gate_clk 7>;
};
+ i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ clock-frequency = <100000>;
+ clocks = <&gate_clk 7>;
+ status = "disabled";
+ };
+
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
interrupts = <21>;
clocks = <&gate_clk 14>, <&gate_clk 15>;
clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
status = "disabled";
};
reg = <0x90000 0x200>;
interrupts = <28>;
clocks = <&gate_clk 4>;
+ pinctrl-0 = <&pmx_sdio>;
+ pinctrl-names = "default";
bus-width = <4>;
cap-sdio-irq;
cap-sd-highspeed;
cap-mmc-highspeed;
status = "disabled";
};
-
- thermal@10078 {
- compatible = "marvell,kirkwood-thermal";
- reg = <0x10078 0x4>;
- status = "okay";
- };
-
- i2c@11100 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0x11100 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <32>;
- clock-frequency = <100000>;
- clocks = <&gate_clk 7>;
- status = "disabled";
- };
-
};
};
button@1 {
label = "Power push button";
- linux,code = <116>;
- gpios = <&gpio0 16 1>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
};
};
red-fail {
label = "cloudbox:red:fail";
- gpios = <&gpio0 14 0>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
};
blue-sata {
label = "cloudbox:blue:sata";
- gpios = <&gpio0 15 0>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
};
gpio_poweroff {
compatible = "gpio-poweroff";
- gpios = <&gpio0 17 0>;
+ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
};
};
mvsdio@90000 {
pinctrl-0 = <&pmx_sdio_gpios>;
pinctrl-names = "default";
- wp-gpios = <&gpio1 5 0>;
- cd-gpios = <&gpio1 6 0>;
+ wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
blue-power {
label = "dns320:blue:power";
- gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
blue-usb {
label = "dns320:blue:usb";
- gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
orange-l_hdd {
label = "dns320:orange:l_hdd";
- gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
orange-r_hdd {
label = "dns320:orange:r_hdd";
- gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */
+ gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
};
orange-usb {
label = "dns320:orange:usb";
- gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* GPIO 35 */
};
};
white-power {
label = "dns325:white:power";
- gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
white-usb {
label = "dns325:white:usb";
- gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO 43 */
};
red-l_hdd {
label = "dns325:red:l_hdd";
- gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
red-r_hdd {
label = "dns325:red:r_hdd";
- gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */
+ gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
};
red-usb {
label = "dns325:red:usb";
- gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
};
button@1 {
label = "Power button";
- linux,code = <116>;
- gpios = <&gpio1 2 1>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "USB unmount button";
- linux,code = <161>;
- gpios = <&gpio1 15 1>;
+ linux,code = <KEY_EJECTCD>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Reset button";
- linux,code = <0x198>;
- gpios = <&gpio1 16 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
compatible = "gpio-fan";
pinctrl-0 = <&pmx_fan_high_speed &pmx_fan_low_speed>;
pinctrl-names = "default";
- gpios = <&gpio1 14 1
- &gpio1 13 1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW
+ &gpio1 13 GPIO_ACTIVE_LOW>;
gpio-fan,speed-map = <0 0
3000 1
6000 2>;
compatible = "gpio-poweroff";
pinctrl-0 = <&pmx_power_off>;
pinctrl-names = "default";
- gpios = <&gpio1 4 0>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
ocp@f1000000 {
health {
label = "status:green:health";
- gpios = <&gpio1 14 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
fault {
label = "status:orange:fault";
- gpios = <&gpio1 15 1>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
};
regulators {
bluetooth {
label = "dreamplug:blue:bluetooth";
- gpios = <&gpio1 15 1>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
wifi {
label = "dreamplug:green:wifi";
- gpios = <&gpio1 16 1>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
wifi-ap {
label = "dreamplug:green:wifi_ap";
- gpios = <&gpio1 17 1>;
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
};
};
health {
label = "status:green:health";
- gpios = <&gpio1 14 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
fault {
label = "status:orange:fault";
- gpios = <&gpio1 15 1>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
left0 {
label = "status:white:left0";
- gpios = <&gpio1 10 0>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
left1 {
label = "status:white:left1";
- gpios = <&gpio1 11 0>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
left2 {
label = "status:white:left2";
- gpios = <&gpio1 12 0>;
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
left3 {
label = "status:white:left3";
- gpios = <&gpio1 13 0>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
right0 {
label = "status:white:right0";
- gpios = <&gpio1 6 0>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
right1 {
label = "status:white:right1";
- gpios = <&gpio1 7 0>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
right2 {
label = "status:white:right2";
- gpios = <&gpio1 8 0>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
right3 {
label = "status:white:right3";
- gpios = <&gpio1 9 0>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
};
regulators {
enable-active-high;
regulator-always-on;
regulator-boot-on;
- gpio = <&gpio0 29 0>;
+ gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
};
};
nr-ports = <1>;
};
+ /* AzureWave AW-GH381 WiFi/BT */
mvsdio@90000 {
status = "okay";
- /* No CD or WP GPIOs */
- broken-cd;
+ non-removable;
};
};
health-r {
label = "guruplug:red:health";
- gpios = <&gpio1 14 1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
health-g {
label = "guruplug:green:health";
- gpios = <&gpio1 15 1>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
wmode-r {
label = "guruplug:red:wmode";
- gpios = <&gpio1 16 1>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
wmode-g {
label = "guruplug:green:wmode";
- gpios = <&gpio1 17 1>;
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
};
};
button@1 {
label = "USB Copy";
- linux,code = <133>;
- gpios = <&gpio0 29 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Reset";
- linux,code = <0x198>;
- gpios = <&gpio0 28 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
};
green-os {
label = "ib62x0:green:os";
- gpios = <&gpio0 25 0>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
};
red-os {
label = "ib62x0:red:os";
- gpios = <&gpio0 22 0>;
+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
};
usb-copy {
label = "ib62x0:red:usb_copy";
- gpios = <&gpio0 27 0>;
+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
};
};
compatible = "gpio-poweroff";
pinctrl-0 = <&pmx_power_off>;
pinctrl-names = "default";
- gpios = <&gpio0 24 0>;
+ gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
};
};
led-level {
label = "led_level";
- gpios = <&gpio1 9 0>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
};
power-blue {
label = "power:blue";
- gpios = <&gpio1 10 0>;
- linux,default-trigger = "timer";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
};
power-red {
label = "power:red";
- gpios = <&gpio1 11 0>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
usb1 {
label = "usb1:blue";
- gpios = <&gpio1 12 0>;
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
usb2 {
label = "usb2:blue";
- gpios = <&gpio1 13 0>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
usb3 {
label = "usb3:blue";
- gpios = <&gpio1 14 0>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
usb4 {
label = "usb4:blue";
- gpios = <&gpio1 15 0>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
otb {
label = "otb:blue";
- gpios = <&gpio1 16 0>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
};
button@1 {
label = "OTB Button";
- linux,code = <133>;
- gpios = <&gpio1 3 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
button@2 {
label = "Reset";
- linux,code = <0x198>;
- gpios = <&gpio0 12 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
};
power_led {
label = "status:white:power_led";
- gpios = <&gpio0 16 0>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
};
rebuild_led {
label = "status:white:rebuild_led";
- gpios = <&gpio1 4 0>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
health_led {
label = "status:red:health_led";
- gpios = <&gpio1 5 0>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
};
backup_led {
label = "status:blue:backup_led";
- gpios = <&gpio0 15 0>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
};
gpio-keys {
Power {
label = "Power Button";
- linux,code = <116>;
- gpios = <&gpio0 14 1>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
};
Reset {
label = "Reset Button";
- linux,code = <0x198>;
- gpios = <&gpio0 12 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
};
OTB {
label = "OTB Button";
- linux,code = <133>;
- gpios = <&gpio1 3 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};
};
};
i2c@0 {
compatible = "i2c-gpio";
- gpios = < &gpio0 8 0 /* sda */
- &gpio0 9 0 >; /* scl */
+ gpios = < &gpio0 8 GPIO_ACTIVE_HIGH /* sda */
+ &gpio0 9 GPIO_ACTIVE_HIGH>; /* scl */
i2c-gpio,delay-us = <2>; /* ~100 kHz */
};
};
--- /dev/null
+/*
+ * Copyright (C) 2013 Maxime Hadjinlian <maxime.hadjinlian@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+ model = "LaCie LaPlug";
+ compatible = "lacie,laplug", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>; /* 128 MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ pinctrl-0 = <&pmx_uart0>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ i2c@11000 {
+ pinctrl-0 = <&pmx_twsi0>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "at,24c04";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+ };
+
+ pinctrl: pinctrl@10000 {
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button@1{
+ label = "Power push button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-fail {
+ label = "laplug_v2:red:power";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ blue-power {
+ label = "laplug_v2:blue:power";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power_back1: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power Back 1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb_power_back2: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "USB Power Back 2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb_power_front: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "USB Power Front";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ /* Total size : 512MB */
+ status = "okay";
+ pinctrl-0 = <&pmx_nand>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>; /* 1MB */
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x1000000>; /* 16MB */
+ };
+
+ partition@1100000 {
+ label = "rootfs";
+ reg = <0x1100000 0x1EF00000>; /* 495MB */
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ device_type = "ethernet-phy";
+ reg = <0>;
+ };
+};
+
+ð0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <ðphy0>;
+ };
+};
button@1 {
label = "Function Button";
- linux,code = <357>;
- gpios = <&gpio1 9 1>;
+ linux,code = <KEY_OPTION>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Power-on Switch";
- linux,code = <0>;
+ linux,code = <KEY_RESERVED>;
linux,input-type = <5>;
- gpios = <&gpio1 10 1>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Power-auto Switch";
- linux,code = <1>;
+ linux,code = <KEY_ESC>;
linux,input-type = <5>;
- gpios = <&gpio1 11 1>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
};
led@1 {
label = "lsxl:blue:func";
- gpios = <&gpio1 4 1>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
led@2 {
label = "lsxl:red:alarm";
- gpios = <&gpio1 5 1>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
led@3 {
label = "lsxl:amber:info";
- gpios = <&gpio1 6 1>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
led@4 {
label = "lsxl:blue:power";
- gpios = <&gpio1 7 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
led@5 {
label = "lsxl:red:func";
- gpios = <&gpio1 16 1>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
compatible = "gpio-fan";
pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
pinctrl-names = "default";
- gpios = <&gpio0 19 1
- &gpio0 18 1>;
+ gpios = <&gpio0 19 GPIO_ACTIVE_LOW
+ &gpio0 18 GPIO_ACTIVE_LOW>;
gpio-fan,speed-map = <0 3
1500 2
3250 1
5000 0>;
- alarm-gpios = <&gpio1 8 0>;
+ alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
restart_poweroff {
pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
pinctrl-names = "default";
status = "okay";
- cd-gpios = <&gpio1 15 1>;
+ cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
/* No WP GPIO */
};
};
health {
label = "status:green:health";
- gpios = <&gpio0 7 1>;
+ gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
};
user1o {
label = "user1:orange";
- gpios = <&gpio1 8 1>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
default-state = "on";
};
user1g {
label = "user1:green";
- gpios = <&gpio1 9 1>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
default-state = "on";
};
user0o {
label = "user0:orange";
- gpios = <&gpio1 12 1>;
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
default-state = "on";
};
user0g {
label = "user0:green";
- gpios = <&gpio1 13 1>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
default-state = "on";
};
misc {
label = "status:orange:misc";
- gpios = <&gpio1 14 1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
default-state = "on";
};
green-status {
label = "gtw:green:Status";
- gpios = <&gpio0 20 0>;
+ gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
};
red-status {
label = "gtw:red:Status";
- gpios = <&gpio0 21 0>;
+ gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
};
green-usb {
label = "gtw:green:USB";
- gpios = <&gpio0 12 0>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
};
button@1 {
label = "SWR Button";
- linux,code = <0x198>; /* KEY_RESTART */
- gpios = <&gpio1 15 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "WPS Button";
- linux,code = <0x211>; /* KEY_WPS_BUTTON */
- gpios = <&gpio1 14 1>;
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
};
};
+/*
+ * Device Tree file for NETGEAR ReadyNAS Duo v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
/dts-v1/;
#include "kirkwood.dtsi"
marvell,pins = "mpp47";
marvell,function = "gpio";
};
+
pmx_button_backup: pmx-button-backup {
marvell,pins = "mpp45";
marvell,function = "gpio";
};
+
pmx_button_reset: pmx-button-reset {
marvell,pins = "mpp13";
marvell,function = "gpio";
};
+
pmx_led_blue_power: pmx-led-blue-power {
marvell,pins = "mpp31";
marvell,function = "gpio";
};
+
pmx_led_blue_activity: pmx-led-blue-activity {
marvell,pins = "mpp38";
marvell,function = "gpio";
};
+
pmx_led_blue_disk1: pmx-led-blue-disk1 {
marvell,pins = "mpp23";
marvell,function = "gpio";
};
+
pmx_led_blue_disk2: pmx-led-blue-disk2 {
marvell,pins = "mpp22";
marvell,function = "gpio";
};
+
pmx_led_blue_backup: pmx-led-blue-backup {
marvell,pins = "mpp29";
marvell,function = "gpio";
};
+
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
};
clocks {
- #address-cells = <1>;
- #size-cells = <0>;
-
- g762_clk: fixedclk {
+ g762_clk: g762-oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <8192>;
power_led {
label = "status:blue:power_led";
- gpios = <&gpio0 31 1>; /* GPIO 31 Active Low */
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
+
activity_led {
label = "status:blue:activity_led";
- gpios = <&gpio1 6 1>; /* GPIO 38 Active Low */
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
};
+
disk1_led {
label = "status:blue:disk1_led";
- gpios = <&gpio0 23 1>; /* GPIO 23 Active Low */
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
};
+
disk2_led {
label = "status:blue:disk2_led";
- gpios = <&gpio0 22 1>; /* GPIO 22 Active Low */
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
};
+
backup_led {
label = "status:blue:backup_led";
- gpios = <&gpio0 29 1>; /* GPIO 29 Active Low*/
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
};
- gpio_keys {
+ gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_button_power &pmx_button_backup
&pmx_button_reset>;
pinctrl-names = "default";
- button@1 {
+ power-button {
label = "Power Button";
- linux,code = <116>; /* KEY_POWER */
- gpios = <&gpio1 15 1>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- button@2 {
+
+ reset-button {
label = "Reset Button";
- linux,code = <0x198>; /* KEY_RESTART */
- gpios = <&gpio0 13 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
};
- button@3 {
+
+ backup-button {
label = "Backup Button";
- linux,code = <133>; /* KEY_COPY */
- gpios = <&gpio1 13 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
};
};
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "USB 3.0 Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio1 14 0>;
- };
- };
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_regulator: usb3-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB 3.0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
};
&nand {
&mdio {
status = "okay";
- ethphy0: ethernet-phy@0 {
+ ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
device_type = "ethernet-phy";
reg = <0>;
};
--- /dev/null
+/*
+ * Device Tree file for NETGEAR ReadyNAS NV+ v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+ model = "NETGEAR ReadyNAS NV+ v2";
+ compatible = "netgear,readynas-nv+-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+ memory { /* 256 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ /* Connected to NEC uPD720200 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+
+ ocp@f1000000 {
+ pinctrl: pinctrl@10000 {
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_backup: pmx-button-backup {
+ marvell,pins = "mpp45";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_power: pmx-led-blue-power {
+ marvell,pins = "mpp31";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_backup: pmx-led-blue-backup {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk1: pmx-led-blue-disk1 {
+ marvell,pins = "mpp20";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk2: pmx-led-blue-disk2 {
+ marvell,pins = "mpp23";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk3: pmx-led-blue-disk3 {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_blue_disk4: pmx-led-blue-disk4 {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp30";
+ marvell,function = "gpio";
+ };
+ };
+
+ clocks {
+ g762_clk: g762-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <8192>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ rs5c372a: rs5c372a@32 {
+ compatible = "ricoh,rs5c372a";
+ reg = <0x32>;
+ };
+
+ g762: g762@3e {
+ compatible = "gmt,g762";
+ reg = <0x3e>;
+ clocks = <&g762_clk>; /* input clock */
+ fan_gear_mode = <0>;
+ fan_startv = <1>;
+ pwm_polarity = <0>;
+ };
+ };
+
+ serial@12000 {
+ pinctrl-0 = <&pmx_uart0>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ sata@80000 { /* Connected to Marvell 88SM4140 SATA port multiplier */
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_backup
+ &pmx_led_blue_disk1 &pmx_led_blue_disk2
+ &pmx_led_blue_disk3 &pmx_led_blue_disk3 >;
+ pinctrl-names = "default";
+
+ power_led {
+ label = "status:blue:power_led";
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ backup_led {
+ label = "status:blue:backup_led";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ };
+
+ disk1_led {
+ label = "status:blue:disk1_led";
+ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ };
+
+ disk2_led {
+ label = "status:blue:disk2_led";
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+ };
+
+ disk3_led {
+ label = "status:blue:disk3_led";
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+
+ disk4_led {
+ label = "status:blue:disk4_led";
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_button_power &pmx_button_backup
+ &pmx_button_reset>;
+ pinctrl-names = "default";
+
+ power-button {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ reset-button {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+
+ backup-button {
+ label = "Backup Button";
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_regulator: usb3-regulator {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB 3.0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x180000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "u-boot-env";
+ reg = <0x180000 0x20000>;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x0200000 0x600000>;
+ };
+
+ partition@800000 {
+ label = "minirootfs";
+ reg = <0x0800000 0x1000000>;
+ };
+
+ partition@1800000 {
+ label = "jffs2";
+ reg = <0x1800000 0x6800000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ device_type = "ethernet-phy";
+ reg = <0>;
+ };
+};
+
+ð0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <ðphy0>;
+ };
+};
button@1 {
label = "Power push button";
- linux,code = <116>;
- gpios = <&gpio1 0 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
};
};
red-fail {
label = "ns2:red:fail";
- gpios = <&gpio0 12 0>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
};
gpio_poweroff {
compatible = "gpio-poweroff";
- gpios = <&gpio0 31 0>;
+ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
};
};
blue-sata {
label = "ns2:blue:sata";
- gpios = <&gpio0 30 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "ide-disk";
};
};
};
gpio_fan {
compatible = "gpio-fan";
- gpios = <&gpio0 22 1
- &gpio0 7 1
- &gpio1 1 1
- &gpio0 23 1>;
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+ &gpio0 7 GPIO_ACTIVE_LOW
+ &gpio1 1 GPIO_ACTIVE_LOW
+ &gpio0 23 GPIO_ACTIVE_LOW>;
gpio-fan,speed-map =
< 0 0
1500 15
3300 10
4300 9
5500 8>;
- alarm-gpios = <&gpio0 25 1>;
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
ns2-leds {
gpio_fan {
compatible = "gpio-fan";
- gpios = <&gpio0 22 1
- &gpio0 7 1
- &gpio1 1 1
- &gpio0 23 1>;
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+ &gpio0 7 GPIO_ACTIVE_LOW
+ &gpio1 1 GPIO_ACTIVE_LOW
+ &gpio0 23 GPIO_ACTIVE_LOW>;
gpio-fan,speed-map =
< 0 0
3000 15
7140 10
7980 9
9200 8>;
- alarm-gpios = <&gpio0 25 1>;
+ alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
ns2-leds {
compatible = "gpio-poweroff";
pinctrl-0 = <&pmx_pwr_off>;
pinctrl-names = "default";
- gpios = <&gpio1 16 0>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
regulators {
regulator-max-microvolt = <5000000>;
regulator-always-on;
regulator-boot-on;
- gpio = <&gpio0 21 0>;
+ gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
};
};
};
button@1 {
label = "Power Button";
- linux,code = <116>;
- gpios = <&gpio1 14 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
button@2 {
label = "Copy Button";
- linux,code = <133>;
- gpios = <&gpio1 5 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Reset Button";
- linux,code = <0x198>;
- gpios = <&gpio1 4 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
};
green-sys {
label = "nsa310:green:sys";
- gpios = <&gpio0 28 0>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
red-sys {
label = "nsa310:red:sys";
- gpios = <&gpio0 29 0>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
green-hdd {
label = "nsa310:green:hdd";
- gpios = <&gpio1 9 0>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
red-hdd {
label = "nsa310:red:hdd";
- gpios = <&gpio1 10 0>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
green-esata {
label = "nsa310:green:esata";
- gpios = <&gpio0 12 0>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
red-esata {
label = "nsa310:red:esata";
- gpios = <&gpio0 13 0>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
green-usb {
label = "nsa310:green:usb";
- gpios = <&gpio0 15 0>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
red-usb {
label = "nsa310:red:usb";
- gpios = <&gpio0 16 0>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
};
green-copy {
label = "nsa310:green:copy";
- gpios = <&gpio1 7 0>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
red-copy {
label = "nsa310:red:copy";
- gpios = <&gpio1 8 0>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
};
};
button@1 {
label = "Power Button";
- linux,code = <116>;
- gpios = <&gpio1 14 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
button@2 {
label = "Copy Button";
- linux,code = <133>;
- gpios = <&gpio1 5 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Reset Button";
- linux,code = <0x198>;
- gpios = <&gpio1 4 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
};
green-sys {
label = "nsa310:green:sys";
- gpios = <&gpio0 28 0>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
};
red-sys {
label = "nsa310:red:sys";
- gpios = <&gpio0 29 0>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
green-hdd {
label = "nsa310:green:hdd";
- gpios = <&gpio1 9 0>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
red-hdd {
label = "nsa310:red:hdd";
- gpios = <&gpio1 10 0>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
green-esata {
label = "nsa310:green:esata";
- gpios = <&gpio0 12 0>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
red-esata {
label = "nsa310:red:esata";
- gpios = <&gpio0 13 0>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
};
green-usb {
label = "nsa310:green:usb";
- gpios = <&gpio0 15 0>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
green-copy {
label = "nsa310:green:copy";
- gpios = <&gpio1 7 0>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
red-copy {
label = "nsa310:red:copy";
- gpios = <&gpio1 8 0>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
};
};
led-red {
label = "obsa6:red:stat";
- gpios = <&gpio1 9 1>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
led-green {
label = "obsa6:green:stat";
- gpios = <&gpio1 10 1>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
led-yellow {
label = "obsa6:yellow:stat";
- gpios = <&gpio1 11 1>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
};
button@1 {
label = "Init Button";
- linux,code = <116>;
- gpios = <&gpio1 6 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
};
};
led-red {
label = "obsa7:red:stat";
- gpios = <&gpio1 9 1>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
led-green {
label = "obsa7:green:stat";
- gpios = <&gpio1 10 1>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
led-yellow {
label = "obsa7:yellow:stat";
- gpios = <&gpio1 11 1>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
};
button@1 {
label = "Init Button";
- linux,code = <116>;
- gpios = <&gpio1 6 0>;
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
};
};
/*
- * kirkwood-sheevaplug-common.dts - Common parts for Sheevaplugs
+ * kirkwood-sheevaplug-common.dtsi - Common parts for Sheevaplugs
*
* Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
*
pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>;
pinctrl-names = "default";
status = "okay";
- cd-gpios = <&gpio1 12 1>;
- wp-gpios = <&gpio1 15 0>;
+ cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
};
health {
label = "sheevaplug:blue:health";
- gpios = <&gpio1 17 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
};
};
/*
- * kirkwood-sheevaplug-esata.dts - Device tree file for Sheevaplug
+ * kirkwood-sheevaplug.dts - Device tree file for Sheevaplug
*
* Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
*
health {
label = "sheevaplug:blue:health";
- gpios = <&gpio1 17 1>;
- linux,default-trigger = "default-on";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
misc {
label = "sheevaplug:red:misc";
- gpios = <&gpio1 14 1>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
};
};
disk {
label = "topkick:yellow:disk";
- gpios = <&gpio0 21 1>;
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
linux,default-trigger = "ide-disk";
};
system2 {
label = "topkick:red:system";
- gpios = <&gpio1 5 1>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
system {
label = "topkick:blue:system";
- gpios = <&gpio1 6 1>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
default-state = "on";
};
wifi {
label = "topkick:green:wifi";
- gpios = <&gpio1 7 1>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
};
wifi2 {
label = "topkick:yellow:wifi";
- gpios = <&gpio1 16 1>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
regulators {
button@1 {
label = "USB Copy";
- linux,code = <133>;
- gpios = <&gpio0 15 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Reset";
- linux,code = <0x198>;
- gpios = <&gpio0 16 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
};
};
};
button@1 {
label = "USB Copy";
- linux,code = <133>;
- gpios = <&gpio1 11 1>;
+ linux,code = <KEY_COPY>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Reset";
- linux,code = <0x198>;
- gpios = <&gpio1 5 1>;
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
};
};
/include/ "skeleton.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
#address-cells = <1>;
#size-cells = <1>;
- mbusc: mbus-controller@20000 {
- compatible = "marvell,mbus-controller";
- reg = <0x20000 0x80>, <0x1500 0x20>;
- };
-
- timer: timer@20300 {
- compatible = "marvell,orion-timer";
- reg = <0x20300 0x20>;
- interrupt-parent = <&bridge_intc>;
- interrupts = <1>, <2>;
- clocks = <&core_clk 0>;
- };
-
- intc: main-interrupt-ctrl@20200 {
- compatible = "marvell,orion-intc";
- interrupt-controller;
- #interrupt-cells = <1>;
- reg = <0x20200 0x10>, <0x20210 0x10>;
- };
-
- bridge_intc: bridge-interrupt-ctrl@20110 {
- compatible = "marvell,orion-bridge-intc";
- interrupt-controller;
- #interrupt-cells = <1>;
- reg = <0x20110 0x8>;
- interrupts = <1>;
- marvell,#interrupts = <6>;
- };
-
core_clk: core-clocks@10030 {
compatible = "marvell,kirkwood-core-clock";
reg = <0x10030 0x4>;
- #clock-cells = <1>;
+ #clock-cells = <1>;
+ };
+
+ spi@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <23>;
+ reg = <0x10600 0x28>;
+ clocks = <&gate_clk 7>;
+ status = "disabled";
};
gpio0: gpio@10100 {
clocks = <&gate_clk 7>;
};
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <29>;
+ clock-frequency = <100000>;
+ clocks = <&gate_clk 7>;
+ status = "disabled";
+ };
+
serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
status = "disabled";
};
- spi@10600 {
- compatible = "marvell,orion-spi";
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- interrupts = <23>;
- reg = <0x10600 0x28>;
- clocks = <&gate_clk 7>;
- status = "disabled";
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x80>, <0x1500 0x20>;
+ };
+
+ bridge_intc: bridge-interrupt-ctrl@20110 {
+ compatible = "marvell,orion-bridge-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20110 0x8>;
+ interrupts = <1>;
+ marvell,#interrupts = <6>;
};
gate_clk: clock-gating-control@2011c {
#clock-cells = <1>;
};
+ intc: main-interrupt-ctrl@20200 {
+ compatible = "marvell,orion-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x20200 0x10>, <0x20210 0x10>;
+ };
+
+ timer: timer@20300 {
+ compatible = "marvell,orion-timer";
+ reg = <0x20300 0x20>;
+ interrupt-parent = <&bridge_intc>;
+ interrupts = <1>, <2>;
+ clocks = <&core_clk 0>;
+ };
+
wdt: watchdog-timer@20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
status = "okay";
};
+ ehci@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <19>;
+ clocks = <&gate_clk 3>;
+ status = "okay";
+ };
+
xor@60800 {
compatible = "marvell,orion-xor";
reg = <0x60800 0x100
};
};
- ehci@50000 {
- compatible = "marvell,orion-ehci";
- reg = <0x50000 0x1000>;
- interrupts = <19>;
- clocks = <&gate_clk 3>;
- status = "okay";
- };
-
- i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0x11000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <29>;
- clock-frequency = <100000>;
- clocks = <&gate_clk 7>;
- status = "disabled";
- };
-
- mdio: mdio-bus@72004 {
- compatible = "marvell,orion-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x72004 0x84>;
- interrupts = <46>;
- clocks = <&gate_clk 0>;
- status = "disabled";
-
- /* add phy nodes in board file */
- };
-
eth0: ethernet-controller@72000 {
compatible = "marvell,kirkwood-eth";
#address-cells = <1>;
};
};
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <46>;
+ clocks = <&gate_clk 0>;
+ status = "disabled";
+
+ /* add phy nodes in board file */
+ };
+
eth1: ethernet-controller@76000 {
compatible = "marvell,kirkwood-eth";
#address-cells = <1>;
/* set phy-handle property in board file */
};
};
+
+ sata_phy0: sata-phy@82000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0x82000 0x0334>;
+ clocks = <&gate_clk 14>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
+
+ sata_phy1: sata-phy@84000 {
+ compatible = "marvell,mvebu-sata-phy";
+ reg = <0x84000 0x0334>;
+ clocks = <&gate_clk 15>;
+ clock-names = "sata";
+ #phy-cells = <0>;
+ status = "ok";
+ };
};
};
--- /dev/null
+/* moxart-uc7112lx.dts - Device Tree file for MOXA UC-7112-LX
+ *
+ * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+/include/ "moxart.dtsi"
+
+/ {
+ model = "MOXA UC-7112-LX";
+ compatible = "moxa,moxart-uc-7112-lx", "moxa,moxart";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x2000000>;
+ };
+
+ flash@80000000,0 {
+ compatible = "numonyx,js28f128", "cfi-flash";
+ reg = <0x80000000 0x1000000>;
+ bank-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "bootloader";
+ reg = <0x0 0x40000>;
+ };
+ partition@40000 {
+ label = "linux kernel";
+ reg = <0x40000 0x1C0000>;
+ };
+ partition@200000 {
+ label = "root filesystem";
+ reg = <0x200000 0x800000>;
+ };
+ partition@a00000 {
+ label = "user filesystem";
+ reg = <0xa00000 0x600000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ user-led {
+ label = "ready-led";
+ gpios = <&gpio 27 0x1>;
+ default-state = "on";
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ gpio_keys_polled {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <500>;
+ button@25 {
+ label = "GPIO Reset";
+ linux,code = <116>;
+ gpios = <&gpio 25 1>;
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p1 rw rootwait";
+ };
+};
+
+&clk_pll {
+ clocks = <&ref12>;
+};
+
+&sdhci {
+ status = "okay";
+};
+
+&mdio0 {
+ status = "okay";
+
+ ethphy0: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mdio1 {
+ status = "okay";
+
+ ethphy1: ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mac0 {
+ status = "okay";
+};
+
+&mac1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
--- /dev/null
+/* moxart.dtsi - Device Tree Include file for MOXA ART family SoC
+ *
+ * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "moxa,moxart";
+ model = "MOXART";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "faraday,fa526";
+ reg = <0>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ref12: ref12M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x90000000 0x10000000>;
+ ranges;
+
+ intc: interrupt-controller@98800000 {
+ compatible = "moxa,moxart-ic";
+ reg = <0x98800000 0x38>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-mask = <0x00080000>;
+ };
+
+ clk_pll: clk_pll@98100000 {
+ compatible = "moxa,moxart-pll-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ };
+
+ clk_apb: clk_apb@98100000 {
+ compatible = "moxa,moxart-apb-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ clocks = <&clk_pll>;
+ };
+
+ timer: timer@98400000 {
+ compatible = "moxa,moxart-timer";
+ reg = <0x98400000 0x42>;
+ interrupts = <19 1>;
+ clocks = <&clk_apb>;
+ };
+
+ gpio: gpio@98700000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "moxa,moxart-gpio";
+ reg = <0x98700000 0xC>;
+ };
+
+ rtc: rtc {
+ compatible = "moxa,moxart-rtc";
+ gpio-rtc-sclk = <&gpio 5 0>;
+ gpio-rtc-data = <&gpio 6 0>;
+ gpio-rtc-reset = <&gpio 7 0>;
+ };
+
+ dma: dma@90500000 {
+ compatible = "moxa,moxart-dma";
+ reg = <0x90500080 0x40>;
+ interrupts = <24 0>;
+ #dma-cells = <1>;
+ };
+
+ watchdog: watchdog@98500000 {
+ compatible = "moxa,moxart-watchdog";
+ reg = <0x98500000 0x10>;
+ clocks = <&clk_apb>;
+ };
+
+ sdhci: sdhci@98e00000 {
+ compatible = "moxa,moxart-sdhci";
+ reg = <0x98e00000 0x5C>;
+ interrupts = <5 0>;
+ clocks = <&clk_apb>;
+ dmas = <&dma 5>,
+ <&dma 5>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ mdio0: mdio@90900090 {
+ compatible = "moxa,moxart-mdio";
+ reg = <0x90900090 0x8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mdio1: mdio@92000090 {
+ compatible = "moxa,moxart-mdio";
+ reg = <0x92000090 0x8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mac0: mac@90900000 {
+ compatible = "moxa,moxart-mac";
+ reg = <0x90900000 0x90>;
+ interrupts = <25 0>;
+ phy-handle = <ðphy0>;
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ mac1: mac@92000000 {
+ compatible = "moxa,moxart-mac";
+ reg = <0x92000000 0x90>;
+ interrupts = <27 0>;
+ phy-handle = <ðphy1>;
+ phy-mode = "mii";
+ status = "disabled";
+ };
+
+ uart0: uart@98200000 {
+ compatible = "ns16550a";
+ reg = <0x98200000 0x20>;
+ interrupts = <31 8>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <14745600>;
+ status = "disabled";
+ };
+ };
+};
gpmc,wr-access-ns = <186>;
gpmc,cycle2cycle-samecsen;
gpmc,cycle2cycle-diffcsen;
- vmmc-supply = <&vddvario>;
- vmmc_aux-supply = <&vdd33a>;
+ vddvario-supply = <&vddvario>;
+ vdd33a-supply = <&vdd33a>;
reg-io-width = <4>;
smsc,save-mac-address;
};
* they probably share the same GPIO IRQ
* REVISIT: Add timing support from slls644g.pdf
*/
- 8250@3,0 {
+ uart@3,0 {
compatible = "ns16550a";
reg = <3 0 0x100>;
bank-width = <2>;
*/
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/omap.h>
#include "skeleton.dtsi"
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
};
cpus {
ranges;
ti,hwmods = "l3_main";
+ aes: aes@480a6000 {
+ compatible = "ti,omap2-aes";
+ ti,hwmods = "aes";
+ reg = <0x480a6000 0x50>;
+ dmas = <&sdma 9 &sdma 10>;
+ dma-names = "tx", "rx";
+ };
+
+ hdq1w: 1w@480b2000 {
+ compatible = "ti,omap2420-1w";
+ ti,hwmods = "hdq1w";
+ reg = <0x480b2000 0x1000>;
+ interrupts = <58>;
+ };
+
+ mailbox: mailbox@48094000 {
+ compatible = "ti,omap2-mailbox";
+ ti,hwmods = "mailbox";
+ reg = <0x48094000 0x200>;
+ interrupts = <26>;
+ };
+
intc: interrupt-controller@1 {
compatible = "ti,omap2-intc";
interrupt-controller;
sdma: dma-controller@48056000 {
compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
+ ti,hwmods = "dma";
reg = <0x48056000 0x1000>;
interrupts = <12>,
<13>,
#dma-requests = <64>;
};
+ i2c1: i2c@48070000 {
+ compatible = "ti,omap2-i2c";
+ ti,hwmods = "i2c1";
+ reg = <0x48070000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <56>;
+ dmas = <&sdma 27 &sdma 28>;
+ dma-names = "tx", "rx";
+ };
+
+ i2c2: i2c@48072000 {
+ compatible = "ti,omap2-i2c";
+ ti,hwmods = "i2c2";
+ reg = <0x48072000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <57>;
+ dmas = <&sdma 29 &sdma 30>;
+ dma-names = "tx", "rx";
+ };
+
+ mcspi1: mcspi@48098000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi1";
+ reg = <0x48098000 0x100>;
+ interrupts = <65>;
+ dmas = <&sdma 35 &sdma 36 &sdma 37 &sdma 38
+ &sdma 39 &sdma 40 &sdma 41 &sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: mcspi@4809a000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi2";
+ reg = <0x4809a000 0x100>;
+ interrupts = <66>;
+ dmas = <&sdma 43 &sdma 44 &sdma 45 &sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ rng: rng@480a0000 {
+ compatible = "ti,omap2-rng";
+ ti,hwmods = "rng";
+ reg = <0x480a0000 0x50>;
+ interrupts = <36>;
+ };
+
+ sham: sham@480a4000 {
+ compatible = "ti,omap2-sham";
+ ti,hwmods = "sham";
+ reg = <0x480a4000 0x64>;
+ interrupts = <51>;
+ dmas = <&sdma 13>;
+ dma-names = "rx";
+ };
+
uart1: serial@4806a000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart1";
+ reg = <0x4806a000 0x2000>;
+ interrupts = <72>;
+ dmas = <&sdma 49 &sdma 50>;
+ dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
uart2: serial@4806c000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart2";
+ reg = <0x4806c000 0x400>;
+ interrupts = <73>;
+ dmas = <&sdma 51 &sdma 52>;
+ dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
uart3: serial@4806e000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart3";
+ reg = <0x4806e000 0x400>;
+ interrupts = <74>;
+ dmas = <&sdma 53 &sdma 54>;
+ dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
dma-names = "tx", "rx";
};
+ msdi1: mmc@4809c000 {
+ compatible = "ti,omap2420-mmc";
+ ti,hwmods = "msdi1";
+ reg = <0x4809c000 0x80>;
+ interrupts = <83>;
+ dmas = <&sdma 61 &sdma 62>;
+ dma-names = "tx", "rx";
+ };
+
timer1: timer@48028000 {
compatible = "ti,omap2420-timer";
reg = <0x48028000 0x400>;
ti,hwmods = "timer1";
ti,timer-alwon;
};
+
+ wd_timer2: wdt@48022000 {
+ compatible = "ti,omap2-wdt";
+ ti,hwmods = "wd_timer2";
+ reg = <0x48022000 0x80>;
+ };
};
};
+
+&i2c1 {
+ compatible = "ti,omap2420-i2c";
+};
+
+&i2c2 {
+ compatible = "ti,omap2420-i2c";
+};
dma-names = "tx", "rx";
};
+ mmc1: mmc@4809c000 {
+ compatible = "ti,omap2-hsmmc";
+ reg = <0x4809c000 0x200>;
+ interrupts = <83>;
+ ti,hwmods = "mmc1";
+ ti,dual-volt;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
+ };
+
+ mmc2: mmc@480b4000 {
+ compatible = "ti,omap2-hsmmc";
+ reg = <0x480b4000 0x200>;
+ interrupts = <86>;
+ ti,hwmods = "mmc2";
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
+ };
+
timer1: timer@49018000 {
compatible = "ti,omap2420-timer";
reg = <0x49018000 0x400>;
ti,hwmods = "timer1";
ti,timer-alwon;
};
+
+ mcspi3: mcspi@480b8000 {
+ compatible = "ti,omap2-mcspi";
+ ti,hwmods = "mcspi3";
+ reg = <0x480b8000 0x100>;
+ interrupts = <91>;
+ dmas = <&sdma 15 &sdma 16 &sdma 23 &sdma 24>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ usb_otg_hs: usb_otg_hs@480ac000 {
+ compatible = "ti,omap2-musb";
+ ti,hwmods = "usb_otg_hs";
+ reg = <0x480ac000 0x1000>;
+ interrupts = <93>;
+ };
+
+ wd_timer2: wdt@49016000 {
+ compatible = "ti,omap2-wdt";
+ ti,hwmods = "wd_timer2";
+ reg = <0x49016000 0x80>;
+ };
};
};
+
+&i2c1 {
+ compatible = "ti,omap2430-i2c";
+};
+
+&i2c2 {
+ compatible = "ti,omap2430-i2c";
+};
&usbhsehci {
phys = <0 &hsusb2_phy>;
};
+
+&vaux2 {
+ regulator-name = "usb_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
vcc-supply = <&hsusb2_power>;
};
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3beagle";
+
+ ti,mcbsp = <&mcbsp2>;
+ ti,codec = <&twl_audio>;
+ };
+
gpio_keys {
compatible = "gpio-keys";
reg = <0x48>;
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
};
};
mode = <3>;
power = <50>;
};
+
+&vaux2 {
+ regulator-name = "vdd_ehci";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+};
/*
- * Device Tree Source for IGEP Technology devices
+ * Common device tree for IGEP boards based on AM/DM37x
*
* Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
*/
/dts-v1/;
-#include "omap34xx.dtsi"
+#include "omap36xx.dtsi"
/ {
memory {
ti,mcbsp = <&mcbsp2>;
ti,codec = <&twl_audio>;
};
+
+ vdd33: regulator-vdd33 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33";
+ regulator-always-on;
+ };
+
+ lbee1usjyc_vmmc: lbee1usjyc_vmmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lbee1usjyc_pins>;
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-lbee1usjyc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>; /* gpio_138 WIFI_PDN */
+ startup-delay-us = <10000>;
+ enable-active-high;
+ vin-supply = <&vdd33>;
+ };
};
&omap3_pmx_core {
>;
};
+ /* WiFi/BT combo */
+ lbee1usjyc_pins: pinmux_lbee1usjyc_pins {
+ pinctrl-single,pins = <
+ 0x136 (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 */
+ 0x138 (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 */
+ 0x13a (PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 */
+ >;
+ };
+
mcbsp2_pins: pinmux_mcbsp2_pins {
pinctrl-single,pins = <
0x10c (PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx.mcbsp2_fsx */
0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
- 0x120 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat4.sdmmc1_dat4 */
- 0x122 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat5.sdmmc1_dat5 */
- 0x124 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat6.sdmmc1_dat6 */
- 0x126 (PIN_INPUT | MUX_MODE0) /* sdmmc1_dat7.sdmmc1_dat7 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
>;
};
>;
};
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x18a (PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ 0x18c (PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x18e (PIN_INPUT | MUX_MODE0) /* i2c2_scl.i2c2_scl */
+ 0x190 (PIN_INPUT | MUX_MODE0) /* i2c2_sda.i2c2_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0x192 (PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ 0x194 (PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+
leds_pins: pinmux_leds_pins { };
};
&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
clock-frequency = <2600000>;
twl: twl@48 {
#include "twl4030_omap3.dtsi"
&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
clock-frequency = <400000>;
};
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
&mcbsp2 {
pinctrl-names = "default";
pinctrl-0 = <&mcbsp2_pins>;
pinctrl-0 = <&mmc1_pins>;
vmmc-supply = <&vmmc1>;
vmmc_aux-supply = <&vsim>;
- bus-width = <8>;
+ bus-width = <4>;
};
&mmc2 {
- status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&lbee1usjyc_vmmc>;
+ bus-width = <4>;
+ non-removable;
};
&mmc3 {
/*
- * Device Tree Source for IGEPv2 board
+ * Device Tree Source for IGEPv2 Rev. (TI OMAP AM/DM37x)
*
* Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
#include "omap-gpmc-smsc911x.dtsi"
/ {
- model = "IGEPv2";
+ model = "IGEPv2 (TI OMAP AM/DM37x)";
compatible = "isee,omap3-igep0020", "ti,omap3";
leds {
pinctrl-names = "default";
pinctrl-0 = <
&hsusbb1_pins
+ &tfp410_pins
+ &dss_pins
>;
hsusbb1_pins: pinmux_hsusbb1_pins {
0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */
>;
};
+
+ tfp410_pins: tfp410_dvi_pins {
+ pinctrl-single,pins = <
+ 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ >;
+ };
+
+ dss_pins: pinmux_dss_dvi_pins {
+ pinctrl-single,pins = <
+ 0x0a4 (PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ 0x0a6 (PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ 0x0a8 (PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ 0x0aa (PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ 0x0ac (PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ 0x0ae (PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ 0x0b0 (PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ 0x0b2 (PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ 0x0b4 (PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ 0x0b6 (PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ 0x0b8 (PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ 0x0ba (PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ 0x0bc (PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ 0x0be (PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ 0x0c0 (PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ 0x0c2 (PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ 0x0c4 (PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ 0x0c6 (PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ 0x0c8 (PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ 0x0ca (PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ 0x0cc (PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ 0x0ce (PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ 0x0d0 (PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ 0x0d2 (PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ 0x0d4 (PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ 0x0d6 (PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ 0x0d8 (PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ 0x0da (PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
};
&leds_pins {
&usbhsehci {
phys = <&hsusb1_phy>;
};
+
+&vpll2 {
+ /* Needed for DSS */
+ regulator-name = "vdds_dsi";
+};
/*
- * Device Tree Source for IGEP COM Module
+ * Device Tree Source for IGEP COM MODULE (TI OMAP AM/DM37x)
*
* Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
#include "omap3-igep.dtsi"
/ {
- model = "IGEP COM Module";
+ model = "IGEP COM MODULE (TI OMAP AM/DM37x)";
compatible = "isee,omap3-igep0030", "ti,omap3";
leds {
>;
};
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+ 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+ 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+ 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat4 */
+ 0x136 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat5 */
+ 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat6 */
+ 0x13a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat7 */
+ >;
+ };
+
display_pins: pinmux_display_pins {
pinctrl-single,pins = <
0x0d4 (PIN_OUTPUT | MUX_MODE4) /* RX51_LCD_RESET_GPIO */
cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */
};
+/* most boards use vaux3, only some old versions use vmmc2 instead */
&mmc2 {
- status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&vaux3>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+ non-removable;
};
&mmc3 {
ranges;
ti,hwmods = "l3_main";
+ aes: aes@480c5000 {
+ compatible = "ti,omap3-aes";
+ ti,hwmods = "aes";
+ reg = <0x480c5000 0x50>;
+ interrupts = <0>;
+ };
+
counter32k: counter@48320000 {
compatible = "ti,omap-counter32k";
reg = <0x48320000 0x20>;
ti,hwmods = "i2c3";
};
+ mailbox: mailbox@48094000 {
+ compatible = "ti,omap3-mailbox";
+ ti,hwmods = "mailbox";
+ reg = <0x48094000 0x200>;
+ interrupts = <26>;
+ };
+
mcspi1: spi@48098000 {
compatible = "ti,omap2-mcspi";
reg = <0x48098000 0x100>;
dma-names = "tx", "rx";
};
+ mmu_isp: mmu@480bd400 {
+ compatible = "ti,omap3-mmu-isp";
+ ti,hwmods = "mmu_isp";
+ reg = <0x480bd400 0x80>;
+ interrupts = <8>;
+ };
+
wdt2: wdt@48314000 {
compatible = "ti,omap3-wdt";
reg = <0x48314000 0x80>;
dma-names = "tx", "rx";
};
+ sham: sham@480c3000 {
+ compatible = "ti,omap3-sham";
+ ti,hwmods = "sham";
+ reg = <0x480c3000 0x64>;
+ interrupts = <49>;
+ };
+
+ smartreflex_core: smartreflex@480cb000 {
+ compatible = "ti,omap3-smartreflex-core";
+ ti,hwmods = "smartreflex_core";
+ reg = <0x480cb000 0x400>;
+ interrupts = <19>;
+ };
+
+ smartreflex_mpu_iva: smartreflex@480c9000 {
+ compatible = "ti,omap3-smartreflex-iva";
+ ti,hwmods = "smartreflex_mpu_iva";
+ reg = <0x480c9000 0x400>;
+ interrupts = <18>;
+ };
+
timer1: timer@48318000 {
compatible = "ti,omap3430-timer";
reg = <0x48318000 0x400>;
0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
>;
};
-};
-
-&omap4_pmx_wkup {
- led_wkgpio_pins: pinmux_leds_wkpins {
- pinctrl-single,pins = <
- 0x1a (PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */
- 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
- >;
- };
/*
* wl12xx GPIO outputs for WLAN_EN, BT_EN, FM_EN, BT_WAKEUP
pinctrl-single,pins = <
0x38 (PIN_INPUT | MUX_MODE3) /* gpmc_ncs2.gpio_52 */
0x3a (PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
- 0x108 (PIN_OUTPUT | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
+ 0x108 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
0x10a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_cmd.sdmmc5_cmd */
0x10c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat0.sdmmc5_dat0 */
0x10e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1.sdmmc5_dat1 */
};
};
+&omap4_pmx_wkup {
+ led_wkgpio_pins: pinmux_leds_wkpins {
+ pinctrl-single,pins = <
+ 0x1a (PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */
+ 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
+ >;
+ };
+};
+
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
wl12xx_pins: pinmux_wl12xx_pins {
pinctrl-single,pins = <
0x3a (PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
- 0x108 (PIN_OUTPUT | MUX_MODE3) /* sdmmc5_clk.sdmmc5_clk */
- 0x10a (PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc5_cmd.sdmmc5_cmd */
- 0x10c (PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc5_dat0.sdmmc5_dat0 */
- 0x10e (PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc5_dat1.sdmmc5_dat1 */
- 0x110 (PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc5_dat2.sdmmc5_dat2 */
- 0x112 (PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc5_dat3.sdmmc5_dat3 */
+ 0x108 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */
+ 0x10a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_cmd.sdmmc5_cmd */
+ 0x10c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat0.sdmmc5_dat0 */
+ 0x10e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat1.sdmmc5_dat1 */
+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat2.sdmmc5_dat2 */
+ 0x112 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_dat3.sdmmc5_dat3 */
>;
};
};
status = "okay";
ethphy: ethernet-phy {
- device-type = "ethernet-phy";
+ device_type = "ethernet-phy";
reg = <8>;
};
};
interrupts = <6>, <7>, <8>, <9>;
};
+ spi@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ reg = <0x10600 0x28>;
+ status = "disabled";
+ };
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <5>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
status = "disabled";
};
- spi@10600 {
- compatible = "marvell,orion-spi";
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- reg = <0x10600 0x28>;
- status = "disabled";
- };
-
wdt@20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
status = "disabled";
};
- ehci@a0000 {
- compatible = "marvell,orion-ehci";
- reg = <0xa0000 0x1000>;
- interrupts = <12>;
- status = "disabled";
- };
-
- sata@80000 {
- compatible = "marvell,orion-sata";
- reg = <0x80000 0x5000>;
- interrupts = <29>;
- status = "disabled";
- };
-
- i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0x11000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <5>;
- clock-frequency = <100000>;
- status = "disabled";
- };
-
xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
};
};
- crypto@90000 {
- compatible = "marvell,orion-crypto";
- reg = <0x90000 0x10000>,
- <0xf2200000 0x800>;
- reg-names = "regs", "sram";
- interrupts = <28>;
- status = "okay";
- };
-
- mdio: mdio-bus@72004 {
- compatible = "marvell,orion-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x72004 0x84>;
- interrupts = <22>;
- status = "disabled";
-
- /* add phy nodes in board file */
- };
-
eth: ethernet-controller@72000 {
compatible = "marvell,orion-eth";
#address-cells = <1>;
/* set phy-handle property in board file */
};
};
+
+ mdio: mdio-bus@72004 {
+ compatible = "marvell,orion-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x72004 0x84>;
+ interrupts = <22>;
+ status = "disabled";
+
+ /* add phy nodes in board file */
+ };
+
+ sata@80000 {
+ compatible = "marvell,orion-sata";
+ reg = <0x80000 0x5000>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ crypto@90000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x90000 0x10000>,
+ <0xf2200000 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <28>;
+ status = "okay";
+ };
+
+ ehci@a0000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0xa0000 0x1000>;
+ interrupts = <12>;
+ status = "disabled";
+ };
};
};
marvell,intc-priority;
marvell,intc-nr-irqs = <34>;
};
+
+ pwm0: pwm@40b00000 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40b00000 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm1: pwm@40b00010 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40b00010 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm2: pwm@40c00000 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40c00000 0x10>;
+ #pwm-cells = <1>;
+ };
+
+ pwm3: pwm@40c00010 {
+ compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm";
+ reg = <0x40c00010 0x10>;
+ #pwm-cells = <1>;
+ };
};
};
--- /dev/null
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "Qualcomm MSM8974";
+ compatible = "qcom,msm8974";
+ interrupt-parent = <&intc>;
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 2 0xf08>,
+ <1 3 0xf08>,
+ <1 4 0xf08>,
+ <1 1 0xf08>;
+ clock-frequency = <19200000>;
+ };
+
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+ clock-frequency = <19200000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <0 8 0x4>,
+ <0 7 0x4>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <0 9 0x4>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <0 10 0x4>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <0 11 0x4>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <0 12 0x4>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <0 13 0x4>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <0 14 0x4>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ restart@fc4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0xfc4ab000 0x4>;
+ };
+ };
+};
*/
/dts-v1/;
-/include/ "r7s72100.dtsi"
+#include "r7s72100.dtsi"
/ {
model = "Genmai";
*/
/dts-v1/;
-/include/ "r8a73a4.dtsi"
+#include "r8a73a4.dtsi"
#include <dt-bindings/gpio/gpio.h>
/ {
reg = <0 0x40000000 0 0x40000000>;
};
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+
vcc_mmc0: regulator@0 {
compatible = "regulator-fixed";
regulator-name = "MMC0 Vcc";
pinctrl-0 = <&scifa0_pins>;
pinctrl-names = "default";
- scifa0_pins: scifa0 {
+ scifa0_pins: serial0 {
renesas,groups = "scifa0_data";
renesas,function = "scifa0";
};
- mmc0_pins: mmcif {
+ mmc0_pins: mmc {
renesas,groups = "mmc0_data8", "mmc0_ctrl";
renesas,function = "mmc0";
};
- sdhi0_pins: sdhi0 {
+ sdhi0_pins: sd0 {
renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
renesas,function = "sdhi0";
};
- sdhi1_pins: sdhi1 {
+ sdhi1_pins: sd1 {
renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
renesas,function = "sdhi1";
};
*/
/dts-v1/;
-/include/ "r8a73a4.dtsi"
+#include "r8a73a4.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "APE6EVM";
reg = <0 0x40000000 0 0x40000000>;
};
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+
ape6evm_fixed_3v3: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "3V3";
compatible = "smsc,lan9118", "smsc,lan9115";
reg = <0x08000000 0x1000>;
interrupt-parent = <&irqc1>;
- interrupts = <8 0x4>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
phy-mode = "mii";
reg-io-width = <4>;
smsc,irq-active-high;
* kind, whether express or implied.
*/
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a73a4";
interrupt-parent = <&gic>;
<0 0xf1002000 0 0x1000>,
<0 0xf1004000 0 0x2000>,
<0 0xf1006000 0 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
irqc0: interrupt-controller@e61c0000 {
interrupt-controller;
reg = <0 0xe61c0000 0 0x200>;
interrupt-parent = <&gic>;
- interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>,
- <0 4 4>, <0 5 4>, <0 6 4>, <0 7 4>,
- <0 8 4>, <0 9 4>, <0 10 4>, <0 11 4>,
- <0 12 4>, <0 13 4>, <0 14 4>, <0 15 4>,
- <0 16 4>, <0 17 4>, <0 18 4>, <0 19 4>,
- <0 20 4>, <0 21 4>, <0 22 4>, <0 23 4>,
- <0 24 4>, <0 25 4>, <0 26 4>, <0 27 4>,
- <0 28 4>, <0 29 4>, <0 30 4>, <0 31 4>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 4 IRQ_TYPE_LEVEL_HIGH>,
+ <0 5 IRQ_TYPE_LEVEL_HIGH>,
+ <0 6 IRQ_TYPE_LEVEL_HIGH>,
+ <0 7 IRQ_TYPE_LEVEL_HIGH>,
+ <0 8 IRQ_TYPE_LEVEL_HIGH>,
+ <0 9 IRQ_TYPE_LEVEL_HIGH>,
+ <0 10 IRQ_TYPE_LEVEL_HIGH>,
+ <0 11 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>,
+ <0 18 IRQ_TYPE_LEVEL_HIGH>,
+ <0 19 IRQ_TYPE_LEVEL_HIGH>,
+ <0 20 IRQ_TYPE_LEVEL_HIGH>,
+ <0 21 IRQ_TYPE_LEVEL_HIGH>,
+ <0 22 IRQ_TYPE_LEVEL_HIGH>,
+ <0 23 IRQ_TYPE_LEVEL_HIGH>,
+ <0 24 IRQ_TYPE_LEVEL_HIGH>,
+ <0 25 IRQ_TYPE_LEVEL_HIGH>,
+ <0 26 IRQ_TYPE_LEVEL_HIGH>,
+ <0 27 IRQ_TYPE_LEVEL_HIGH>,
+ <0 28 IRQ_TYPE_LEVEL_HIGH>,
+ <0 29 IRQ_TYPE_LEVEL_HIGH>,
+ <0 30 IRQ_TYPE_LEVEL_HIGH>,
+ <0 31 IRQ_TYPE_LEVEL_HIGH>;
};
irqc1: interrupt-controller@e61c0200 {
interrupt-controller;
reg = <0 0xe61c0200 0 0x200>;
interrupt-parent = <&gic>;
- interrupts = <0 32 4>, <0 33 4>, <0 34 4>, <0 35 4>,
- <0 36 4>, <0 37 4>, <0 38 4>, <0 39 4>,
- <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>,
- <0 44 4>, <0 45 4>, <0 46 4>, <0 47 4>,
- <0 48 4>, <0 49 4>, <0 50 4>, <0 51 4>,
- <0 52 4>, <0 53 4>, <0 54 4>, <0 55 4>,
- <0 56 4>, <0 57 4>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+ <0 33 IRQ_TYPE_LEVEL_HIGH>,
+ <0 34 IRQ_TYPE_LEVEL_HIGH>,
+ <0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 36 IRQ_TYPE_LEVEL_HIGH>,
+ <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>,
+ <0 39 IRQ_TYPE_LEVEL_HIGH>,
+ <0 40 IRQ_TYPE_LEVEL_HIGH>,
+ <0 41 IRQ_TYPE_LEVEL_HIGH>,
+ <0 42 IRQ_TYPE_LEVEL_HIGH>,
+ <0 43 IRQ_TYPE_LEVEL_HIGH>,
+ <0 44 IRQ_TYPE_LEVEL_HIGH>,
+ <0 45 IRQ_TYPE_LEVEL_HIGH>,
+ <0 46 IRQ_TYPE_LEVEL_HIGH>,
+ <0 47 IRQ_TYPE_LEVEL_HIGH>,
+ <0 48 IRQ_TYPE_LEVEL_HIGH>,
+ <0 49 IRQ_TYPE_LEVEL_HIGH>,
+ <0 50 IRQ_TYPE_LEVEL_HIGH>,
+ <0 51 IRQ_TYPE_LEVEL_HIGH>,
+ <0 52 IRQ_TYPE_LEVEL_HIGH>,
+ <0 53 IRQ_TYPE_LEVEL_HIGH>,
+ <0 54 IRQ_TYPE_LEVEL_HIGH>,
+ <0 55 IRQ_TYPE_LEVEL_HIGH>,
+ <0 56 IRQ_TYPE_LEVEL_HIGH>,
+ <0 57 IRQ_TYPE_LEVEL_HIGH>;
};
dmac: dma-multiplexer@0 {
compatible = "renesas,shdma-r8a73a4";
reg = <0 0xe6700020 0 0x89e0>;
interrupt-parent = <&gic>;
- interrupts = <0 220 4
- 0 200 4
- 0 201 4
- 0 202 4
- 0 203 4
- 0 204 4
- 0 205 4
- 0 206 4
- 0 207 4
- 0 208 4
- 0 209 4
- 0 210 4
- 0 211 4
- 0 212 4
- 0 213 4
- 0 214 4
- 0 215 4
- 0 216 4
- 0 217 4
- 0 218 4
- 0 219 4>;
+ interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+ 0 200 IRQ_TYPE_LEVEL_HIGH
+ 0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH
+ 0 205 IRQ_TYPE_LEVEL_HIGH
+ 0 206 IRQ_TYPE_LEVEL_HIGH
+ 0 207 IRQ_TYPE_LEVEL_HIGH
+ 0 208 IRQ_TYPE_LEVEL_HIGH
+ 0 209 IRQ_TYPE_LEVEL_HIGH
+ 0 210 IRQ_TYPE_LEVEL_HIGH
+ 0 211 IRQ_TYPE_LEVEL_HIGH
+ 0 212 IRQ_TYPE_LEVEL_HIGH
+ 0 213 IRQ_TYPE_LEVEL_HIGH
+ 0 214 IRQ_TYPE_LEVEL_HIGH
+ 0 215 IRQ_TYPE_LEVEL_HIGH
+ 0 216 IRQ_TYPE_LEVEL_HIGH
+ 0 217 IRQ_TYPE_LEVEL_HIGH
+ 0 218 IRQ_TYPE_LEVEL_HIGH
+ 0 219 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
<0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>;
interrupt-parent = <&gic>;
- interrupts = <0 69 4>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
};
i2c0: i2c@e6500000 {
compatible = "renesas,rmobile-iic";
reg = <0 0xe6500000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 174 0x4>;
+ interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6510000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 175 0x4>;
+ interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6520000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 176 0x4>;
+ interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6530000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 177 0x4>;
+ interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6540000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 178 0x4>;
+ interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe60b0000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 179 0x4>;
+ interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6550000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 184 0x4>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6560000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 185 0x4>;
+ interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0 0xe6570000 0 0x428>;
interrupt-parent = <&gic>;
- interrupts = <0 173 0x4>;
+ interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- mmcif0: mmcif@ee200000 {
+ mmcif0: mmc@ee200000 {
compatible = "renesas,sh-mmcif";
reg = <0 0xee200000 0 0x80>;
interrupt-parent = <&gic>;
- interrupts = <0 169 0x4>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
reg-io-width = <4>;
status = "disabled";
};
- mmcif1: mmcif@ee220000 {
+ mmcif1: mmc@ee220000 {
compatible = "renesas,sh-mmcif";
reg = <0 0xee220000 0 0x80>;
interrupt-parent = <&gic>;
- interrupts = <0 170 0x4>;
+ interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
reg-io-width = <4>;
status = "disabled";
};
reg = <0 0xe6050000 0 0x9000>;
gpio-controller;
#gpio-cells = <2>;
+ interrupts-extended =
+ <&irqc0 0 0>, <&irqc0 1 0>, <&irqc0 2 0>, <&irqc0 3 0>,
+ <&irqc0 4 0>, <&irqc0 5 0>, <&irqc0 6 0>, <&irqc0 7 0>,
+ <&irqc0 8 0>, <&irqc0 9 0>, <&irqc0 10 0>, <&irqc0 11 0>,
+ <&irqc0 12 0>, <&irqc0 13 0>, <&irqc0 14 0>, <&irqc0 15 0>,
+ <&irqc0 16 0>, <&irqc0 17 0>, <&irqc0 18 0>, <&irqc0 19 0>,
+ <&irqc0 20 0>, <&irqc0 21 0>, <&irqc0 22 0>, <&irqc0 23 0>,
+ <&irqc0 24 0>, <&irqc0 25 0>, <&irqc0 26 0>, <&irqc0 27 0>,
+ <&irqc0 28 0>, <&irqc0 29 0>, <&irqc0 30 0>, <&irqc0 31 0>,
+ <&irqc1 0 0>, <&irqc1 1 0>, <&irqc1 2 0>, <&irqc1 3 0>,
+ <&irqc1 4 0>, <&irqc1 5 0>, <&irqc1 6 0>, <&irqc1 7 0>,
+ <&irqc1 8 0>, <&irqc1 9 0>, <&irqc1 10 0>, <&irqc1 11 0>,
+ <&irqc1 12 0>, <&irqc1 13 0>, <&irqc1 14 0>, <&irqc1 15 0>,
+ <&irqc1 16 0>, <&irqc1 17 0>, <&irqc1 18 0>, <&irqc1 19 0>,
+ <&irqc1 20 0>, <&irqc1 21 0>, <&irqc1 22 0>, <&irqc1 23 0>,
+ <&irqc1 24 0>, <&irqc1 25 0>;
};
- sdhi0: sdhi@ee100000 {
+ sdhi0: sd@ee100000 {
compatible = "renesas,sdhi-r8a73a4";
reg = <0 0xee100000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 165 4>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
status = "disabled";
};
- sdhi1: sdhi@ee120000 {
+ sdhi1: sd@ee120000 {
compatible = "renesas,sdhi-r8a73a4";
reg = <0 0xee120000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 166 4>;
+ interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
status = "disabled";
};
- sdhi2: sdhi@ee140000 {
+ sdhi2: sd@ee140000 {
compatible = "renesas,sdhi-r8a73a4";
reg = <0 0xee140000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 167 4>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
status = "disabled";
};
*/
/dts-v1/;
-/include/ "r8a7740.dtsi"
+#include "r8a7740.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>
/ {
enable-active-high;
};
+ reg_5p0v: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5.0V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
+ linux,code = <116>;
+ label = "SW3";
+ gpio-key,wakeup;
+ };
+
+ back-key {
+ gpios = <&pfc 100 GPIO_ACTIVE_LOW>;
+ linux,code = <158>;
+ label = "SW4";
+ };
+
+ menu-key {
+ gpios = <&pfc 97 GPIO_ACTIVE_LOW>;
+ linux,code = <139>;
+ label = "SW5";
+ };
+
+ home-key {
+ gpios = <&pfc 98 GPIO_ACTIVE_LOW>;
+ linux,code = <102>;
+ label = "SW6";
+ };
+ };
+
leds {
compatible = "gpio-leds";
led1 {
default-brightness-level = <9>;
pinctrl-0 = <&backlight_pins>;
pinctrl-names = "default";
+ power-supply = <®_5p0v>;
+ enable-gpios = <&pfc 61 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "i2s";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sh_fsi2 0>;
+ bitclock-inversion;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8978>;
+ bitclock-master;
+ frame-master;
+ system-clock-frequency = <12288000>;
+ };
};
};
&i2c0 {
status = "okay";
- touchscreen: st1232@55 {
+ touchscreen@55 {
compatible = "sitronix,st1232";
reg = <0x55>;
interrupt-parent = <&irqpin1>;
- interrupts = <2 0>; /* IRQ10: hwirq 2 on irqpin1 */
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
pinctrl-0 = <&st1232_pins>;
pinctrl-names = "default";
gpios = <&pfc 166 GPIO_ACTIVE_LOW>;
};
+
+ wm8978: wm8978@1a {
+ #sound-dai-cells = <0>;
+ compatible = "wlf,wm8978";
+ reg = <0x1a>;
+ };
};
&pfc {
pinctrl-0 = <&scifa1_pins>;
pinctrl-names = "default";
- scifa1_pins: scifa1 {
+ scifa1_pins: serial1 {
renesas,groups = "scifa1_data";
renesas,function = "scifa1";
};
- st1232_pins: st1232 {
+ st1232_pins: touchscreen {
renesas,groups = "intc_irq10";
renesas,function = "intc";
};
renesas,function = "mmc0";
};
- sdhi0_pins: sdhi0 {
+ sdhi0_pins: sd0 {
renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
renesas,function = "sdhi0";
};
+
+ fsia_pins: sounda {
+ renesas,groups = "fsia_sclk_in", "fsia_mclk_out",
+ "fsia_data_in_1", "fsia_data_out_0";
+ renesas,function = "fsia";
+ };
};
&tpu {
cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>;
status = "okay";
};
+
+&sh_fsi2 {
+ pinctrl-0 = <&fsia_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
*/
/dts-v1/;
-/include/ "r8a7740.dtsi"
+#include "r8a7740.dtsi"
/ {
model = "armadillo 800 eva";
/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a7740";
pmu {
compatible = "arm,cortex-a9-pmu";
- interrupts = <0 83 4>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
};
/* irqpin0: IRQ0 - IRQ7 */
irqpin0: irqpin@e6900000 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900000 4>,
<0xe6900040 1>,
<0xe6900060 1>;
interrupt-parent = <&gic>;
- interrupts = <0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
};
/* irqpin1: IRQ8 - IRQ15 */
irqpin1: irqpin@e6900004 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900004 4>,
<0xe6900044 1>,
<0xe6900064 1>;
interrupt-parent = <&gic>;
- interrupts = <0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
};
/* irqpin2: IRQ16 - IRQ23 */
irqpin2: irqpin@e6900008 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900008 4>,
<0xe6900048 1>,
<0xe6900068 1>;
interrupt-parent = <&gic>;
- interrupts = <0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
};
/* irqpin3: IRQ24 - IRQ31 */
irqpin3: irqpin@e690000c {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe690000c 4>,
<0xe690004c 1>,
<0xe690006c 1>;
interrupt-parent = <&gic>;
- interrupts = <0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4
- 0 149 0x4>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH
+ 0 149 IRQ_TYPE_LEVEL_HIGH>;
};
i2c0: i2c@fff20000 {
compatible = "renesas,rmobile-iic";
reg = <0xfff20000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 201 0x4
- 0 202 0x4
- 0 203 0x4
- 0 204 0x4>;
+ interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH
+ 0 202 IRQ_TYPE_LEVEL_HIGH
+ 0 203 IRQ_TYPE_LEVEL_HIGH
+ 0 204 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0xe6c20000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 70 0x4
- 0 71 0x4
- 0 72 0x4
- 0 73 0x4>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH
+ 0 71 IRQ_TYPE_LEVEL_HIGH
+ 0 72 IRQ_TYPE_LEVEL_HIGH
+ 0 73 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
<0xe605800c 0x20>;
gpio-controller;
#gpio-cells = <2>;
+ interrupts-extended =
+ <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
+ <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
+ <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
+ <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
+ <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
+ <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
+ <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
+ <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
};
tpu: pwm@e6600000 {
#pwm-cells = <3>;
};
- mmcif0: mmcif@e6bd0000 {
+ mmcif0: mmc@e6bd0000 {
compatible = "renesas,sh-mmcif";
reg = <0xe6bd0000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 56 4
- 0 57 4>;
+ interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH
+ 0 57 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- sdhi0: sdhi@e6850000 {
+ sdhi0: sd@e6850000 {
compatible = "renesas,sdhi-r8a7740";
reg = <0xe6850000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 117 4
- 0 118 4
- 0 119 4>;
+ interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH
+ 0 118 IRQ_TYPE_LEVEL_HIGH
+ 0 119 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
cap-sdio-irq;
status = "disabled";
};
- sdhi1: sdhi@e6860000 {
+ sdhi1: sd@e6860000 {
compatible = "renesas,sdhi-r8a7740";
reg = <0xe6860000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 121 4
- 0 122 4
- 0 123 4>;
+ interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH
+ 0 122 IRQ_TYPE_LEVEL_HIGH
+ 0 123 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi2: sd@e6870000 {
+ compatible = "renesas,sdhi-r8a7740";
+ reg = <0xe6870000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH
+ 0 126 IRQ_TYPE_LEVEL_HIGH
+ 0 127 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
cap-sdio-irq;
status = "disabled";
};
+
+ sh_fsi2: sound@fe1f0000 {
+ #sound-dai-cells = <1>;
+ compatible = "renesas,sh_fsi2";
+ reg = <0xfe1f0000 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 9 0x4>;
+ status = "disabled";
+ };
};
*/
/dts-v1/;
-/include/ "r8a7778.dtsi"
+#include "r8a7778.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "bockw";
phy-mode = "mii";
interrupt-parent = <&irqpin>;
- interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
reg-io-width = <4>;
vddvario-supply = <&fixedregulator3v3>;
vdd33a-supply = <&fixedregulator3v3>;
};
+
+};
+
+&mmcif {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <8>;
+ broken-cd;
+ status = "okay";
};
&irqpin {
status = "okay";
};
+
+&pfc {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_a", "scif0_ctrl";
+ renesas,function = "scif0";
+ };
+
+ mmc_pins: mmc {
+ renesas,groups = "mmc_data8", "mmc_ctrl";
+ renesas,function = "mmc";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
+ "sdhi0_cd", "sdhi0_wp";
+ renesas,function = "sdhi0";
+ };
+
+ hspi0_pins: hspi0 {
+ renesas,groups = "hspi0_a";
+ renesas,function = "hspi0";
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&hspi0 {
+ pinctrl-0 = <&hspi0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
*/
/dts-v1/;
-/include/ "r8a7778.dtsi"
+#include "r8a7778.dtsi"
/ {
model = "bockw";
/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a7778";
};
};
+ aliases {
+ spi0 = &hspi0;
+ spi1 = &hspi1;
+ spi2 = &hspi2;
+ };
+
gic: interrupt-controller@fe438000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
/* irqpin: IRQ0 - IRQ3 */
irqpin: irqpin@fe78001c {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7778", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
status = "disabled"; /* default off */
<0xfe780044 4>,
<0xfe780064 4>;
interrupt-parent = <&gic>;
- interrupts = <0 27 0x4
- 0 28 0x4
- 0 29 0x4
- 0 30 0x4>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH>;
sense-bitfield-width = <2>;
};
compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
reg = <0xffc40000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 103 0x4>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 0 32>;
compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
reg = <0xffc41000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 103 0x4>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 32 32>;
compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
reg = <0xffc42000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 103 0x4>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 64 32>;
compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
reg = <0xffc43000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 103 0x4>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 96 32>;
compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
reg = <0xffc44000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 103 0x4>;
+ interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 128 27>;
pfc: pfc@fffc0000 {
compatible = "renesas,pfc-r8a7778";
- reg = <0xfffc000 0x118>;
+ reg = <0xfffc0000 0x118>;
+ };
+
+ i2c0: i2c@ffc70000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc70000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc71000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc71000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc72000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc72000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc73000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc73000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmcif: mmc@ffe4e000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0xffe4e000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@ffe4c000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4c000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ffe4d000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4d000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ffe4f000 {
+ compatible = "renesas,sdhi-r8a7778";
+ reg = <0xffe4f000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ i2c0: i2c@ffc70000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc70000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc71000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc71000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc72000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc72000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc73000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7778";
+ reg = <0xffc73000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ hspi0: spi@fffc7000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc7000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ hspi1: spi@fffc8000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc8000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ hspi2: spi@fffc6000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc6000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
};
};
*/
/dts-v1/;
-/include/ "r8a7779.dtsi"
+#include "r8a7779.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "marzen";
phy-mode = "mii";
interrupt-parent = <&irqpin0>;
- interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
reg-io-width = <4>;
vddvario-supply = <&fixedregulator3v3>;
vdd33a-supply = <&fixedregulator3v3>;
};
&pfc {
- pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>;
+ pinctrl-0 = <&scif2_pins &scif4_pins>;
pinctrl-names = "default";
lan0_pins: lan0 {
};
};
- scif2_pins: scif2 {
+ scif2_pins: serial2 {
renesas,groups = "scif2_data_c";
renesas,function = "scif2";
};
- scif4_pins: scif4 {
+ scif4_pins: serial4 {
renesas,groups = "scif4_data";
renesas,function = "scif4";
};
- sdhi0_pins: sdhi0 {
- renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd",
- "sdhi0_wp";
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
renesas,function = "sdhi0";
};
+
+ hspi0_pins: hspi0 {
+ renesas,groups = "hspi0";
+ renesas,function = "hspi0";
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&hspi0 {
+ pinctrl-0 = <&hspi0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
};
*/
/dts-v1/;
-/include/ "r8a7779.dtsi"
+#include "r8a7779.dtsi"
/ {
model = "marzen";
/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a7779";
};
};
+ aliases {
+ spi0 = &hspi0;
+ spi1 = &hspi1;
+ spi2 = &hspi2;
+ };
+
gic: interrupt-controller@f0001000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc40000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 141 0x4>;
+ interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 0 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc41000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 142 0x4>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 32 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc42000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 143 0x4>;
+ interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 64 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc43000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 144 0x4>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 96 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc44000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 145 0x4>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 128 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc45000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 146 0x4>;
+ interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 160 32>;
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc46000 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 147 0x4>;
+ interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 192 9>;
};
irqpin0: irqpin@fe780010 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-r8a7779", "renesas,intc-irqpin";
#interrupt-cells = <2>;
status = "disabled";
interrupt-controller;
<0xfe780044 4>,
<0xfe780064 4>;
interrupt-parent = <&gic>;
- interrupts = <0 27 0x4
- 0 28 0x4
- 0 29 0x4
- 0 30 0x4>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH>;
sense-bitfield-width = <2>;
};
i2c0: i2c@ffc70000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "renesas,rmobile-iic";
+ compatible = "renesas,i2c-r8a7779";
reg = <0xffc70000 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <0 79 0x4>;
+ interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
i2c1: i2c@ffc71000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "renesas,rmobile-iic";
+ compatible = "renesas,i2c-r8a7779";
reg = <0xffc71000 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <0 82 0x4>;
+ interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
i2c2: i2c@ffc72000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "renesas,rmobile-iic";
+ compatible = "renesas,i2c-r8a7779";
reg = <0xffc72000 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <0 80 0x4>;
+ interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
i2c3: i2c@ffc73000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "renesas,rmobile-iic";
+ compatible = "renesas,i2c-r8a7779";
reg = <0xffc73000 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <0 81 0x4>;
+ interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rcar-sata";
reg = <0xfc600000 0x2000>;
interrupt-parent = <&gic>;
- interrupts = <0 100 0x4>;
+ interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sdhi0: sd@ffe4c000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4c000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ffe4d000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4d000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ffe4e000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4e000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi3: sd@ffe4f000 {
+ compatible = "renesas,sdhi-r8a7779";
+ reg = <0xffe4f000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ hspi0: spi@fffc7000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc7000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ hspi1: spi@fffc8000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc8000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ hspi2: spi@fffc6000 {
+ compatible = "renesas,hspi";
+ reg = <0xfffc6000 0x18>;
+ interrupt-controller = <&gic>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
};
};
+++ /dev/null
-/*
- * Device Tree Source for the Lager board
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/dts-v1/;
-/include/ "r8a7790.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- model = "Lager";
- compatible = "renesas,lager-reference", "renesas,r8a7790";
-
- chosen {
- bootargs = "console=ttySC6,115200 ignore_loglevel rw";
- };
-
- memory@40000000 {
- device_type = "memory";
- reg = <0 0x40000000 0 0x80000000>;
- };
-
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
- leds {
- compatible = "gpio-leds";
- led6 {
- gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
- };
- led7 {
- gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>;
- };
- led8 {
- gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
- };
- };
-};
*/
/dts-v1/;
-/include/ "r8a7790.dtsi"
+#include "r8a7790.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Lager";
reg = <0 0x40000000 0 0x80000000>;
};
+ memory@180000000 {
+ device_type = "memory";
+ reg = <1 0x80000000 0 0x80000000>;
+ };
+
lbsc {
#address-cells = <1>;
#size-cells = <1>;
};
+
+ leds {
+ compatible = "gpio-leds";
+ led6 {
+ gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ };
+ led7 {
+ gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>;
+ };
+ led8 {
+ gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ fixedregulator3v3: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&pfc {
+ pinctrl-0 = <&scif0_pins &scif1_pins>;
+ pinctrl-names = "default";
+
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data";
+ renesas,function = "scif0";
+ };
+
+ scif1_pins: serial1 {
+ renesas,groups = "scif1_data";
+ renesas,function = "scif1";
+ };
+
+ mmc1_pins: mmc1 {
+ renesas,groups = "mmc1_data8", "mmc1_ctrl";
+ renesas,function = "mmc1";
+ };
+};
+
+&mmcif1 {
+ pinctrl-0 = <&mmc1_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&fixedregulator3v3>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
};
* kind, whether express or implied.
*/
+#include <dt-bindings/clock/r8a7790-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a7790";
interrupt-parent = <&gic>;
<0 0xf1002000 0 0x1000>,
<0 0xf1004000 0 0x2000>,
<0 0xf1006000 0 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
gpio0: gpio@ffc40000 {
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc40000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 4 0x4>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 0 32>;
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc41000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 5 0x4>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 32 32>;
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc42000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 6 0x4>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 64 32>;
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc43000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 7 0x4>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 96 32>;
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc44000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 8 0x4>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 128 32>;
compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
reg = <0 0xffc45000 0 0x2c>;
interrupt-parent = <&gic>;
- interrupts = <0 9 0x4>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 160 32>;
interrupt-controller;
};
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
irqc0: interrupt-controller@e61c0000 {
- compatible = "renesas,irqc";
+ compatible = "renesas,irqc-r8a7790", "renesas,irqc";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0 0xe61c0000 0 0x200>;
interrupt-parent = <&gic>;
- interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>;
};
i2c0: i2c@e6508000 {
compatible = "renesas,i2c-r8a7790";
reg = <0 0xe6508000 0 0x40>;
interrupt-parent = <&gic>;
- interrupts = <0 287 0x4>;
+ interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_I2C0>;
status = "disabled";
};
compatible = "renesas,i2c-r8a7790";
reg = <0 0xe6518000 0 0x40>;
interrupt-parent = <&gic>;
- interrupts = <0 288 0x4>;
+ interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_I2C1>;
status = "disabled";
};
compatible = "renesas,i2c-r8a7790";
reg = <0 0xe6530000 0 0x40>;
interrupt-parent = <&gic>;
- interrupts = <0 286 0x4>;
+ interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_I2C2>;
status = "disabled";
};
compatible = "renesas,i2c-r8a7790";
reg = <0 0xe6540000 0 0x40>;
interrupt-parent = <&gic>;
- interrupts = <0 290 0x4>;
+ interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_I2C3>;
status = "disabled";
};
mmcif0: mmcif@ee200000 {
- compatible = "renesas,sh-mmcif";
+ compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
reg = <0 0xee200000 0 0x80>;
interrupt-parent = <&gic>;
- interrupts = <0 169 0x4>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
reg-io-width = <4>;
status = "disabled";
};
- mmcif1: mmcif@ee220000 {
- compatible = "renesas,sh-mmcif";
+ mmcif1: mmc@ee220000 {
+ compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
reg = <0 0xee220000 0 0x80>;
interrupt-parent = <&gic>;
- interrupts = <0 170 0x4>;
+ interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
reg-io-width = <4>;
status = "disabled";
};
reg = <0 0xe6060000 0 0x250>;
};
- sdhi0: sdhi@ee100000 {
+ sdhi0: sd@ee100000 {
compatible = "renesas,sdhi-r8a7790";
reg = <0 0xee100000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 165 4>;
+ interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
cap-sd-highspeed;
status = "disabled";
};
- sdhi1: sdhi@ee120000 {
+ sdhi1: sd@ee120000 {
compatible = "renesas,sdhi-r8a7790";
reg = <0 0xee120000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 166 4>;
+ interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
cap-sd-highspeed;
status = "disabled";
};
- sdhi2: sdhi@ee140000 {
+ sdhi2: sd@ee140000 {
compatible = "renesas,sdhi-r8a7790";
reg = <0 0xee140000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 167 4>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
cap-sd-highspeed;
status = "disabled";
};
- sdhi3: sdhi@ee160000 {
+ sdhi3: sd@ee160000 {
compatible = "renesas,sdhi-r8a7790";
reg = <0 0xee160000 0 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 168 4>;
+ interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
cap-sd-highspeed;
status = "disabled";
};
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7790-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "sd1",
+ "z";
+ };
+
+ /* Variable factor clocks */
+ sd2_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ sd3_clk: sd3_clk@e615007c {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615007c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd3";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+ mmc1_clk: mmc1_clk@e6150244 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150244 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc1";
+ };
+ ssp_clk: ssp_clk@e6150248 {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150248 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssp";
+ };
+ ssprs_clk: ssprs_clk@e615024c {
+ compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615024c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssprs";
+ };
+
+ /* Fixed factor clocks */
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ z2_clk: z2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "z2";
+ };
+ zg_clk: zg_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zg";
+ };
+ zx_clk: zx_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zx";
+ };
+ zs_clk: zs_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zs";
+ };
+ hp_clk: hp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "hp";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ b_clk: b_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "b";
+ };
+ p_clk: p_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "p";
+ };
+ cl_clk: cl_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cl";
+ };
+ m2_clk: m2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "m2";
+ };
+ imp_clk: imp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "imp";
+ };
+ rclk_clk: rclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(48 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "rclk";
+ };
+ oscclk_clk: oscclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(12 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "oscclk";
+ };
+ zb3_clk: zb3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "zb3";
+ };
+ zb3d2_clk: zb3d2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "zb3d2";
+ };
+ ddr_clk: ddr_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "ddr";
+ };
+ mp_clk: mp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ clock-output-names = "mp";
+ };
+ cp_clk: cp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "cp";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7790_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+ <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>,
+ <&zs_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2
+ R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1
+ R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY
+ >;
+ clock-output-names =
+ "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+ "vsp1-du0", "vsp1-rt", "vsp1-sy";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
+ R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1
+ R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
+ "scifb1", "msiof1", "msiof3", "scifb2";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+ <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+ <&mmc0_clk>, <&rclk_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+ R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+ R8A7790_CLK_MMCIF0 R8A7790_CLK_CMT1
+ >;
+ clock-output-names =
+ "tpu0", "mmcif1", "sdhi3", "sdhi2",
+ "sdhi1", "sdhi0", "mmcif0", "cmt1";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&extal_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
+ clock-output-names = "thermal", "pwm";
+ };
+ mstp7_clks: mstp7_clks@e615014c {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>,
+ <&p_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>,
+ <&zx_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7790_CLK_EHCI R8A7790_CLK_HSUSB R8A7790_CLK_HSCIF1
+ R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1 R8A7790_CLK_SCIF0
+ R8A7790_CLK_DU2 R8A7790_CLK_DU1 R8A7790_CLK_DU0
+ R8A7790_CLK_LVDS1 R8A7790_CLK_LVDS0
+ >;
+ clock-output-names =
+ "ehci", "hsusb", "hscif1", "hscif0", "scif1",
+ "scif0", "du2", "du1", "du0", "lvds1", "lvds0";
+ };
+ mstp8_clks: mstp8_clks@e6150990 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+ clocks = <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7790_CLK_ETHER>;
+ clock-output-names = "ether";
+ };
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&p_clk>, <&p_clk>, <&cpg_clocks R8A7790_CLK_QSPI>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_QSPI_MOD
+ R8A7790_CLK_I2C3 R8A7790_CLK_I2C2 R8A7790_CLK_I2C1
+ R8A7790_CLK_I2C0
+ >;
+ clock-output-names =
+ "rcan1", "rcan0", "qspi_mod", "i2c3", "i2c2", "i2c1", "i2c0";
+ };
+ };
};
--- /dev/null
+/*
+ * Device Tree Source for the Koelsch board
+ *
+ * Copyright (C) 2013 Renesas Electronics Corporation
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7791.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Koelsch";
+ compatible = "renesas,koelsch-reference", "renesas,r8a7791";
+
+ chosen {
+ bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x80000000>;
+ };
+
+ lbsc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-a {
+ gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ linux,code = <30>;
+ label = "SW30";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-b {
+ gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+ linux,code = <48>;
+ label = "SW31";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-c {
+ gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
+ linux,code = <46>;
+ label = "SW32";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-d {
+ gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
+ linux,code = <32>;
+ label = "SW33";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-e {
+ gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
+ linux,code = <18>;
+ label = "SW34";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-f {
+ gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+ linux,code = <33>;
+ label = "SW35";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ key-g {
+ gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
+ linux,code = <34>;
+ label = "SW36";
+ gpio-key,wakeup;
+ debounce-interval = <20>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led6 {
+ gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ };
+ led7 {
+ gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ };
+ led8 {
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&pfc {
+ pinctrl-0 = <&scif0_pins &scif1_pins>;
+ pinctrl-names = "default";
+
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_d";
+ renesas,function = "scif0";
+ };
+
+ scif1_pins: serial1 {
+ renesas,groups = "scif1_data_d";
+ renesas,function = "scif1";
+ };
+};
*/
/dts-v1/;
-/include/ "r8a7791.dtsi"
+#include "r8a7791.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Koelsch";
#address-cells = <1>;
#size-cells = <1>;
};
+
+ leds {
+ compatible = "gpio-leds";
+ led6 {
+ gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ };
+ led7 {
+ gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ };
+ led8 {
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&pfc {
+ pinctrl-0 = <&scif0_pins &scif1_pins>;
+ pinctrl-names = "default";
+
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data_d";
+ renesas,function = "scif0";
+ };
+
+ scif1_pins: serial1 {
+ renesas,groups = "scif1_data_d";
+ renesas,function = "scif1";
+ };
};
* kind, whether express or implied.
*/
+#include <dt-bindings/clock/r8a7791-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,r8a7791";
interrupt-parent = <&gic>;
<0 0xf1002000 0 0x1000>,
<0 0xf1004000 0 0x2000>,
<0 0xf1006000 0 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055400 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio7: gpio@e6055800 {
+ compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+ reg = <0 0xe6055800 0 0x50>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
};
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
irqc0: interrupt-controller@e61c0000 {
- compatible = "renesas,irqc";
+ compatible = "renesas,irqc-r8a7791", "renesas,irqc";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0 0xe61c0000 0 0x200>;
interrupt-parent = <&gic>;
- interrupts = <0 0 4>,
- <0 1 4>,
- <0 2 4>,
- <0 3 4>,
- <0 12 4>,
- <0 13 4>,
- <0 14 4>,
- <0 15 4>,
- <0 16 4>,
- <0 17 4>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pfc: pfc@e6060000 {
+ compatible = "renesas,pfc-r8a7791";
+ reg = <0 0xe6060000 0 0x250>;
+ #gpio-range-cells = <3>;
+ };
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* External root clock */
+ extal_clk: extal_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overriden by the board. */
+ clock-frequency = <0>;
+ clock-output-names = "extal";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7791-cpg-clocks",
+ "renesas,rcar-gen2-cpg-clocks";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll3",
+ "lb", "qspi", "sdh", "sd0", "z";
+ };
+
+ /* Variable factor clocks */
+ sd1_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd1";
+ };
+ sd2_clk: sd3_clk@e615007c {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615007c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
+ ssp_clk: ssp_clk@e6150248 {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150248 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssp";
+ };
+ ssprs_clk: ssprs_clk@e615024c {
+ compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615024c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "ssprs";
+ };
+
+ /* Fixed factor clocks */
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ zg_clk: zg_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zg";
+ };
+ zx_clk: zx_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <3>;
+ clock-mult = <1>;
+ clock-output-names = "zx";
+ };
+ zs_clk: zs_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <6>;
+ clock-mult = <1>;
+ clock-output-names = "zs";
+ };
+ hp_clk: hp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "hp";
+ };
+ i_clk: i_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "i";
+ };
+ b_clk: b_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <12>;
+ clock-mult = <1>;
+ clock-output-names = "b";
+ };
+ p_clk: p_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <24>;
+ clock-mult = <1>;
+ clock-output-names = "p";
+ };
+ cl_clk: cl_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <48>;
+ clock-mult = <1>;
+ clock-output-names = "cl";
+ };
+ m2_clk: m2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "m2";
+ };
+ imp_clk: imp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "imp";
+ };
+ rclk_clk: rclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(48 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "rclk";
+ };
+ oscclk_clk: oscclk_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <(12 * 1024)>;
+ clock-mult = <1>;
+ clock-output-names = "oscclk";
+ };
+ zb3_clk: zb3_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "zb3";
+ };
+ zb3d2_clk: zb3d2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "zb3d2";
+ };
+ ddr_clk: ddr_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "ddr";
+ };
+ mp_clk: mp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ clock-output-names = "mp";
+ };
+ cp_clk: cp_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&extal_clk>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "cp";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7791_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+ clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+ <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2
+ R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1
+ R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY
+ >;
+ clock-output-names =
+ "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+ "vsp1-du0", "vsp1-sy";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0
+ R8A7791_CLK_MSIOF2 R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1
+ R8A7791_CLK_MSIOF1 R8A7791_CLK_SCIFB2
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "misof2", "scifb0",
+ "scifb1", "msiof1", "scifb2";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+ clocks = <&cp_clk>, <&sd2_clk>, <&sd1_clk>,
+ <&cpg_clocks R8A7791_CLK_SD0>, <&mmc0_clk>, <&rclk_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1
+ R8A7791_CLK_SDHI0 R8A7791_CLK_MMCIF0 R8A7791_CLK_CMT1
+ >;
+ clock-output-names =
+ "tpu0", "sdhi2", "sdhi1", "sdhi0", "mmcif0", "cmt1";
+ };
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&extal_clk>, <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
+ clock-output-names = "thermal", "pwm";
+ };
+ mstp7_clks: mstp7_clks@e615014c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+ clocks = <&mp_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&zx_clk>, <&zx_clk>, <&zx_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_HSUSB R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5
+ R8A7791_CLK_SCIF4 R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0
+ R8A7791_CLK_SCIF3 R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1
+ R8A7791_CLK_SCIF0 R8A7791_CLK_DU1 R8A7791_CLK_DU0
+ R8A7791_CLK_LVDS0
+ >;
+ clock-output-names =
+ "hsusb", "hscif2", "scif5", "scif4", "hscif1", "hscif0",
+ "scif3", "scif2", "scif1", "scif0", "du1", "du0", "lvds0";
+ };
+ mstp8_clks: mstp8_clks@e6150990 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+ clocks = <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <R8A7791_CLK_ETHER>;
+ clock-output-names = "ether";
+ };
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&p_clk>, <&p_clk>, <&cpg_clocks R8A7791_CLK_QSPI>,
+ <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&p_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD
+ R8A7791_CLK_I2C4 R8A7791_CLK_I2C4 R8A7791_CLK_I2C3
+ R8A7791_CLK_I2C2 R8A7791_CLK_I2C1 R8A7791_CLK_I2C0
+ >;
+ clock-output-names =
+ "rcan1", "rcan0", "qspi_mod", "i2c5", "i2c4", "i2c3",
+ "i2c2", "i2c1", "i2c0";
+ };
+ mstp11_clks: mstp11_clks@e615099c {
+ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ #clock-cells = <1>;
+ renesas,clock-indices = <
+ R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5
+ >;
+ clock-output-names = "scifa3", "scifa4", "scifa5";
+ };
};
};
/*
* sama5d3.dtsi - Device Tree Include file for SAMA5D3 family SoC
- * applies to SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35 SoC
+ * applies to SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36 SoC
*
* Copyright (C) 2013 Atmel,
* 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
#include <dt-bindings/pinctrl/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/at91.h>
/ {
model = "Atmel SAMA5D3 family SoC";
i2c2 = &i2c2;
ssc0 = &ssc0;
ssc1 = &ssc1;
+ pwm0 = &pwm0;
};
cpus {
#address-cells = <1>;
reg = <0x20000000 0x8000000>;
};
+ clocks {
+ adc_op_clk: adc_op_clk{
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ };
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&mci0_clk>;
+ clock-names = "mci_clk";
};
spi0: spi@f0004000 {
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi0>;
+ clocks = <&spi0_clk>;
+ clock-names = "spi_clk";
status = "disabled";
};
interrupts = <38 IRQ_TYPE_LEVEL_HIGH 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+ clocks = <&ssc0_clk>;
+ clock-names = "pclk";
status = "disabled";
};
compatible = "atmel,at91sam9x5-tcb";
reg = <0xf0010000 0x100>;
interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb0_clk>;
+ clock-names = "t0_clk";
};
i2c0: i2c@f0014000 {
pinctrl-0 = <&pinctrl_i2c0>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&twi0_clk>;
status = "disabled";
};
pinctrl-0 = <&pinctrl_i2c1>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&twi1_clk>;
status = "disabled";
};
interrupts = <12 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart0>;
+ clocks = <&usart0_clk>;
+ clock-names = "usart";
status = "disabled";
};
interrupts = <13 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart1>;
+ clocks = <&usart1_clk>;
+ clock-names = "usart";
+ status = "disabled";
+ };
+
+ pwm0: pwm@f002c000 {
+ compatible = "atmel,sama5d3-pwm";
+ reg = <0xf002c000 0x300>;
+ interrupts = <28 IRQ_TYPE_LEVEL_HIGH 4>;
+ #pwm-cells = <3>;
+ clocks = <&pwm_clk>;
status = "disabled";
};
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&mci1_clk>;
+ clock-names = "mci_clk";
};
spi1: spi@f8008000 {
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi1>;
+ clocks = <&spi1_clk>;
+ clock-names = "spi_clk";
status = "disabled";
};
interrupts = <39 IRQ_TYPE_LEVEL_HIGH 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+ clocks = <&ssc1_clk>;
+ clock-names = "pclk";
status = "disabled";
};
&pinctrl_adc0_ad10
&pinctrl_adc0_ad11
>;
+ clocks = <&adc_clk>,
+ <&adc_op_clk>;
+ clock-names = "adc_clk", "adc_op_clk";
atmel,adc-channel-base = <0x50>;
atmel,adc-channels-used = <0xfff>;
atmel,adc-drdy-mask = <0x1000000>;
dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(11)>,
<&dma1 2 AT91_DMA_CFG_PER_ID(12)>;
dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&twi2_clk>;
status = "disabled";
};
interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart2>;
+ clocks = <&usart2_clk>;
+ clock-names = "usart";
status = "disabled";
};
interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart3>;
+ clocks = <&usart3_clk>;
+ clock-names = "usart";
status = "disabled";
};
sha@f8034000 {
- compatible = "atmel,sam9g46-sha";
+ compatible = "atmel,at91sam9g46-sha";
reg = <0xf8034000 0x100>;
interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(17)>;
+ dma-names = "tx";
+ clocks = <&sha_clk>;
+ clock-names = "sha_clk";
};
aes@f8038000 {
- compatible = "atmel,sam9g46-aes";
+ compatible = "atmel,at91sam9g46-aes";
reg = <0xf8038000 0x100>;
- interrupts = <43 4 0>;
+ interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(18)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(19)>;
+ dma-names = "tx", "rx";
+ clocks = <&aes_clk>;
+ clock-names = "aes_clk";
};
tdes@f803c000 {
- compatible = "atmel,sam9g46-tdes";
+ compatible = "atmel,at91sam9g46-tdes";
reg = <0xf803c000 0x100>;
interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(20)>,
+ <&dma1 2 AT91_DMA_CFG_PER_ID(21)>;
+ dma-names = "tx", "rx";
+ clocks = <&tdes_clk>;
+ clock-names = "tdes_clk";
};
dma0: dma-controller@ffffe600 {
reg = <0xffffe600 0x200>;
interrupts = <30 IRQ_TYPE_LEVEL_HIGH 0>;
#dma-cells = <2>;
+ clocks = <&dma0_clk>;
+ clock-names = "dma_clk";
};
dma1: dma-controller@ffffe800 {
reg = <0xffffe800 0x200>;
interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
#dma-cells = <2>;
+ clocks = <&dma1_clk>;
+ clock-names = "dma_clk";
};
ramc0: ramc@ffffea00 {
interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dbgu>;
+ clocks = <&dbgu_clk>;
+ clock-names = "usart";
status = "disabled";
};
};
};
+ i2c2 {
+ pinctrl_i2c2: i2c2-0 {
+ atmel,pins =
+ <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* TWD2 pin, conflicts with LCDDAT18, ISI_D2 */
+ AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* TWCK2 pin, conflicts with LCDDAT19, ISI_D3 */
+ };
+ };
+
isi {
pinctrl_isi: isi-0 {
atmel,pins =
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&pioA_clk>;
};
pioB: gpio@fffff400 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&pioB_clk>;
};
pioC: gpio@fffff600 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&pioC_clk>;
};
pioD: gpio@fffff800 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
};
pioE: gpio@fffffa00 {
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&pioE_clk>;
};
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91rm9200-pmc";
+ compatible = "atmel,sama5d3-pmc";
reg = <0xfffffc00 0x120>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ clk32k: slck {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91rm9200-clk-main";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCS>;
+ clocks = <&clk32k>;
+ };
+
+ plla: pllack {
+ compatible = "atmel,sama5d3-clk-pll";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKA>;
+ clocks = <&main>;
+ reg = <0>;
+ atmel,clk-input-range = <8000000 50000000>;
+ #atmel,pll-clk-output-range-cells = <4>;
+ atmel,pll-clk-output-ranges = <400000000 1000000000 0 0>;
+ };
+
+ plladiv: plladivck {
+ compatible = "atmel,at91sam9x5-clk-plldiv";
+ #clock-cells = <0>;
+ clocks = <&plla>;
+ };
+
+ utmi: utmick {
+ compatible = "atmel,at91sam9x5-clk-utmi";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_LOCKU>;
+ clocks = <&main>;
+ };
+
+ mck: masterck {
+ compatible = "atmel,at91sam9x5-clk-master";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MCKRDY>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
+ atmel,clk-output-range = <0 166000000>;
+ atmel,clk-divisors = <1 2 4 3>;
+ };
+
+ usb: usbck {
+ compatible = "atmel,at91sam9x5-clk-usb";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ prog: progck {
+ compatible = "atmel,at91sam9x5-clk-programmable";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ prog0: prog0 {
+ #clock-cells = <0>;
+ reg = <0>;
+ interrupts = <AT91_PMC_PCKRDY(0)>;
+ };
+
+ prog1: prog1 {
+ #clock-cells = <0>;
+ reg = <1>;
+ interrupts = <AT91_PMC_PCKRDY(1)>;
+ };
+
+ prog2: prog2 {
+ #clock-cells = <0>;
+ reg = <2>;
+ interrupts = <AT91_PMC_PCKRDY(2)>;
+ };
+ };
+
+ smd: smdclk {
+ compatible = "atmel,at91sam9x5-clk-smd";
+ #clock-cells = <0>;
+ clocks = <&plladiv>, <&utmi>;
+ };
+
+ systemck {
+ compatible = "atmel,at91rm9200-clk-system";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ddrck: ddrck {
+ #clock-cells = <0>;
+ reg = <2>;
+ clocks = <&mck>;
+ };
+
+ smdck: smdck {
+ #clock-cells = <0>;
+ reg = <4>;
+ clocks = <&smd>;
+ };
+
+ uhpck: uhpck {
+ #clock-cells = <0>;
+ reg = <6>;
+ clocks = <&usb>;
+ };
+
+ udpck: udpck {
+ #clock-cells = <0>;
+ reg = <7>;
+ clocks = <&usb>;
+ };
+
+ pck0: pck0 {
+ #clock-cells = <0>;
+ reg = <8>;
+ clocks = <&prog0>;
+ };
+
+ pck1: pck1 {
+ #clock-cells = <0>;
+ reg = <9>;
+ clocks = <&prog1>;
+ };
+
+ pck2: pck2 {
+ #clock-cells = <0>;
+ reg = <10>;
+ clocks = <&prog2>;
+ };
+ };
+
+ periphck {
+ compatible = "atmel,at91sam9x5-clk-peripheral";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mck>;
+
+ dbgu_clk: dbgu_clk {
+ #clock-cells = <0>;
+ reg = <2>;
+ };
+
+ pioA_clk: pioA_clk {
+ #clock-cells = <0>;
+ reg = <6>;
+ };
+
+ pioB_clk: pioB_clk {
+ #clock-cells = <0>;
+ reg = <7>;
+ };
+
+ pioC_clk: pioC_clk {
+ #clock-cells = <0>;
+ reg = <8>;
+ };
+
+ pioD_clk: pioD_clk {
+ #clock-cells = <0>;
+ reg = <9>;
+ };
+
+ pioE_clk: pioE_clk {
+ #clock-cells = <0>;
+ reg = <10>;
+ };
+
+ usart0_clk: usart0_clk {
+ #clock-cells = <0>;
+ reg = <12>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart1_clk: usart1_clk {
+ #clock-cells = <0>;
+ reg = <13>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart2_clk: usart2_clk {
+ #clock-cells = <0>;
+ reg = <14>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ usart3_clk: usart3_clk {
+ #clock-cells = <0>;
+ reg = <15>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ twi0_clk: twi0_clk {
+ reg = <18>;
+ #clock-cells = <0>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ twi1_clk: twi1_clk {
+ #clock-cells = <0>;
+ reg = <19>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ twi2_clk: twi2_clk {
+ #clock-cells = <0>;
+ reg = <20>;
+ atmel,clk-output-range = <0 16625000>;
+ };
+
+ mci0_clk: mci0_clk {
+ #clock-cells = <0>;
+ reg = <21>;
+ };
+
+ mci1_clk: mci1_clk {
+ #clock-cells = <0>;
+ reg = <22>;
+ };
+
+ spi0_clk: spi0_clk {
+ #clock-cells = <0>;
+ reg = <24>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ spi1_clk: spi1_clk {
+ #clock-cells = <0>;
+ reg = <25>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ tcb0_clk: tcb0_clk {
+ #clock-cells = <0>;
+ reg = <26>;
+ atmel,clk-output-range = <0 133000000>;
+ };
+
+ pwm_clk: pwm_clk {
+ #clock-cells = <0>;
+ reg = <28>;
+ };
+
+ adc_clk: adc_clk {
+ #clock-cells = <0>;
+ reg = <29>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ dma0_clk: dma0_clk {
+ #clock-cells = <0>;
+ reg = <30>;
+ };
+
+ dma1_clk: dma1_clk {
+ #clock-cells = <0>;
+ reg = <31>;
+ };
+
+ uhphs_clk: uhphs_clk {
+ #clock-cells = <0>;
+ reg = <32>;
+ };
+
+ udphs_clk: udphs_clk {
+ #clock-cells = <0>;
+ reg = <33>;
+ };
+
+ isi_clk: isi_clk {
+ #clock-cells = <0>;
+ reg = <37>;
+ };
+
+ ssc0_clk: ssc0_clk {
+ #clock-cells = <0>;
+ reg = <38>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ ssc1_clk: ssc1_clk {
+ #clock-cells = <0>;
+ reg = <39>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ sha_clk: sha_clk {
+ #clock-cells = <0>;
+ reg = <42>;
+ };
+
+ aes_clk: aes_clk {
+ #clock-cells = <0>;
+ reg = <43>;
+ };
+
+ tdes_clk: tdes_clk {
+ #clock-cells = <0>;
+ reg = <44>;
+ };
+
+ trng_clk: trng_clk {
+ #clock-cells = <0>;
+ reg = <45>;
+ };
+
+ fuse_clk: fuse_clk {
+ #clock-cells = <0>;
+ reg = <48>;
+ };
+ };
};
rstc@fffffe00 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
+ clocks = <&mck>;
};
watchdog@fffffe40 {
reg = <0x00500000 0x100000
0xf8030000 0x4000>;
interrupts = <33 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&udphs_clk>, <&utmi>;
+ clock-names = "pclk", "hclk";
status = "disabled";
ep0 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00600000 0x100000>;
interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&udphs_clk>,
+ <&uhpck>;
+ clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
status = "disabled";
};
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00700000 0x100000>;
interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
+ clocks = <&usb>, <&uhphs_clk>, <&uhpck>;
+ clock-names = "usb_clk", "ehci_clk", "uhpck";
status = "disabled";
};
--- /dev/null
+/*
+ * sama5d36.dtsi - Device Tree Include file for SAMA5D36 SoC
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Josh Wu <josh.wu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_tcb1.dtsi"
+#include "sama5d3_uart.dtsi"
+
+/ {
+ compatible = "atmel,samad36", "atmel,sama5d3", "atmel,sama5";
+};
--- /dev/null
+/*
+ * sama5d36ek.dts - Device Tree file for SAMA5D36-EK board
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Josh Wu <josh.wu@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
+
+/ {
+ model = "Atmel SAMA5D36-EK";
+ compatible = "atmel,sama5d36ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
};
+ pmc: pmc@fffffc00 {
+ periphck {
+ can0_clk: can0_clk {
+ #clock-cells = <0>;
+ reg = <40>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ can1_clk: can0_clk {
+ #clock-cells = <0>;
+ reg = <41>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+ };
+ };
+
can0: can@f000c000 {
compatible = "atmel,at91sam9x5-can";
reg = <0xf000c000 0x300>;
interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_can0_rx_tx>;
+ clocks = <&can0_clk>;
+ clock-names = "can_clk";
status = "disabled";
};
interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_can1_rx_tx>;
+ clocks = <&can1_clk>;
+ clock-names = "can_clk";
status = "disabled";
};
};
};
};
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb1_clk: macb1_clk {
+ #clock-cells = <0>;
+ reg = <35>;
+ };
+ };
+ };
+
macb1: ethernet@f802c000 {
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xf802c000 0x100>;
interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_macb1_rmii>;
+ clocks = <&macb1_clk>, <&macb1_clk>;
+ clock-names = "hclk", "pclk";
status = "disabled";
};
};
};
};
+ pmc: pmc@fffffc00 {
+ periphck {
+ macb0_clk: macb0_clk {
+ #clock-cells = <0>;
+ reg = <34>;
+ };
+ };
+ };
+
macb0: ethernet@f0028000 {
compatible = "cdns,pc302-gem", "cdns,gem";
reg = <0xf0028000 0x100>;
interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>;
+ clocks = <&macb0_clk>, <&macb0_clk>;
+ clock-names = "hclk", "pclk";
status = "disabled";
};
};
};
};
};
+
+ pmc: pmc@fffffc00 {
+ periphck {
+ lcdc_clk: lcdc_clk {
+ #clock-cells = <0>;
+ reg = <36>;
+ };
+ };
+
+ systemck {
+ lcdck: lcdck {
+ #clock-cells = <0>;
+ reg = <3>;
+ clocks = <&mck>;
+ };
+ };
+ };
};
};
};
#include <dt-bindings/pinctrl/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clk/at91.h>
/ {
ahb {
};
};
+ pmc: pmc@fffffc00 {
+ periphck {
+ mci2_clk: mci2_clk {
+ #clock-cells = <0>;
+ reg = <23>;
+ };
+ };
+ };
+
mmc2: mmc@f8004000 {
compatible = "atmel,hsmci";
reg = <0xf8004000 0x600>;
dma-names = "rxtx";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
+ clocks = <&mci2_clk>;
+ clock-names = "mci_clk";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
#include <dt-bindings/pinctrl/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clk/at91.h>
/ {
aliases {
ahb {
apb {
+ pmc: pmc@fffffc00 {
+ periphck {
+ tcb1_clk: tcb1_clk {
+ #clock-cells = <0>;
+ reg = <27>;
+ };
+ };
+ };
+
tcb1: timer@f8014000 {
compatible = "atmel,at91sam9x5-tcb";
reg = <0xf8014000 0x100>;
interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&tcb1_clk>;
+ clock-names = "t0_clk";
};
};
};
#include <dt-bindings/pinctrl/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clk/at91.h>
/ {
+ aliases {
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
ahb {
apb {
pinctrl@fffff200 {
};
};
+ pmc: pmc@fffffc00 {
+ periphck {
+ uart0_clk: uart0_clk {
+ #clock-cells = <0>;
+ reg = <16>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+
+ uart1_clk: uart1_clk {
+ #clock-cells = <0>;
+ reg = <17>;
+ atmel,clk-output-range = <0 66000000>;
+ };
+ };
+ };
+
uart0: serial@f0024000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xf0024000 0x200>;
interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart0_clk>;
+ clock-names = "usart";
status = "disabled";
};
interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart1_clk>;
+ clock-names = "usart";
status = "disabled";
};
};
reg = <0x20000000 0x20000000>;
};
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- main_clock: clock@0 {
- compatible = "atmel,osc", "fixed-clock";
- clock-frequency = <12000000>;
- };
- };
-
ahb {
apb {
spi0: spi@f0004000 {
macb0: ethernet@f0028000 {
phy-mode = "rgmii";
};
+
+ pmc: pmc@fffffc00 {
+ main: mainck {
+ clock-frequency = <12000000>;
+ };
+ };
};
nand0: nand@60000000 {
interrupts = <31 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qt1070_irq>;
+ wakeup-source;
};
};
*/
/dts-v1/;
-/include/ "sh7372.dtsi"
+#include "sh7372.dtsi"
/ {
model = "Mackerel (AP4 EVM 2nd)";
*/
/dts-v1/;
-/include/ "sh73a0.dtsi"
+#include "sh73a0.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "KZM-A9-GT";
reg = <0x10000000 0x100>;
phy-mode = "mii";
interrupt-parent = <&irqpin0>;
- interrupts = <3 0>; /* active low */
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
reg-io-width = <4>;
smsc,irq-push-pull;
smsc,save-mac-address;
gpios = <&pfc 23 GPIO_ACTIVE_LOW>;
};
};
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ back-key {
+ gpios = <&pcf8575 8 GPIO_ACTIVE_LOW>;
+ linux,code = <158>;
+ label = "SW3";
+ };
+
+ right-key {
+ gpios = <&pcf8575 9 GPIO_ACTIVE_LOW>;
+ linux,code = <106>;
+ label = "SW2-R";
+ };
+
+ left-key {
+ gpios = <&pcf8575 10 GPIO_ACTIVE_LOW>;
+ linux,code = <105>;
+ label = "SW2-L";
+ };
+
+ enter-key {
+ gpios = <&pcf8575 11 GPIO_ACTIVE_LOW>;
+ linux,code = <28>;
+ label = "SW2-P";
+ };
+
+ up-key {
+ gpios = <&pcf8575 12 GPIO_ACTIVE_LOW>;
+ linux,code = <103>;
+ label = "SW2-U";
+ };
+
+ down-key {
+ gpios = <&pcf8575 13 GPIO_ACTIVE_LOW>;
+ linux,code = <108>;
+ label = "SW2-D";
+ };
+
+ home-key {
+ gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>;
+ linux,code = <102>;
+ label = "SW1";
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "left_j";
+ simple-audio-card,cpu {
+ sound-dai = <&sh_fsi2 0>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&ak4648>;
+ bitclock-master;
+ frame-master;
+ system-clock-frequency = <11289600>;
+ };
+ };
};
&i2c0 {
};
};
};
+
+ ak4648: ak4648@0x12 {
+ #sound-dai-cells = <0>;
+ compatible = "asahi-kasei,ak4648";
+ reg = <0x12>;
+ };
};
&i2c3 {
pinctrl-0 = <&i2c3_pins>;
pinctrl-names = "default";
status = "okay";
+
+ pcf8575: gpio@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ interrupt-parent = <&irqpin2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
&mmcif {
renesas,function = "i2c3";
};
- mmcif_pins: mmcif {
+ mmcif_pins: mmc {
mux {
renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0";
renesas,function = "mmc0";
};
};
- scifa4_pins: scifa4 {
+ scifa4_pins: serial4 {
renesas,groups = "scifa4_data", "scifa4_ctrl";
renesas,function = "scifa4";
};
- sdhi0_pins: sdhi0 {
+ sdhi0_pins: sd0 {
renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd", "sdhi0_wp";
renesas,function = "sdhi0";
};
- sdhi2_pins: sdhi2 {
+ sdhi2_pins: sd2 {
renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
renesas,function = "sdhi2";
};
+
+ fsia_pins: sounda {
+ renesas,groups = "fsia_mclk_in", "fsia_sclk_in",
+ "fsia_data_in", "fsia_data_out";
+ renesas,function = "fsia";
+ };
};
&sdhi0 {
broken-cd;
status = "okay";
};
+
+&sh_fsi2 {
+ pinctrl-0 = <&fsia_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
*/
/dts-v1/;
-/include/ "sh73a0.dtsi"
+#include "sh73a0.dtsi"
/ {
model = "KZM-A9-GT";
/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
/ {
compatible = "renesas,sh73a0";
pmu {
compatible = "arm,cortex-a9-pmu";
- interrupts = <0 55 4>,
- <0 56 4>;
+ interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>,
+ <0 56 IRQ_TYPE_LEVEL_HIGH>;
};
irqpin0: irqpin@e6900000 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900000 4>,
<0xe6900040 1>,
<0xe6900060 1>;
interrupt-parent = <&gic>;
- interrupts = <0 1 0x4
- 0 2 0x4
- 0 3 0x4
- 0 4 0x4
- 0 5 0x4
- 0 6 0x4
- 0 7 0x4
- 0 8 0x4>;
+ interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH
+ 0 2 IRQ_TYPE_LEVEL_HIGH
+ 0 3 IRQ_TYPE_LEVEL_HIGH
+ 0 4 IRQ_TYPE_LEVEL_HIGH
+ 0 5 IRQ_TYPE_LEVEL_HIGH
+ 0 6 IRQ_TYPE_LEVEL_HIGH
+ 0 7 IRQ_TYPE_LEVEL_HIGH
+ 0 8 IRQ_TYPE_LEVEL_HIGH>;
};
irqpin1: irqpin@e6900004 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900004 4>,
<0xe6900044 1>,
<0xe6900064 1>;
interrupt-parent = <&gic>;
- interrupts = <0 9 0x4
- 0 10 0x4
- 0 11 0x4
- 0 12 0x4
- 0 13 0x4
- 0 14 0x4
- 0 15 0x4
- 0 16 0x4>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH
+ 0 10 IRQ_TYPE_LEVEL_HIGH
+ 0 11 IRQ_TYPE_LEVEL_HIGH
+ 0 12 IRQ_TYPE_LEVEL_HIGH
+ 0 13 IRQ_TYPE_LEVEL_HIGH
+ 0 14 IRQ_TYPE_LEVEL_HIGH
+ 0 15 IRQ_TYPE_LEVEL_HIGH
+ 0 16 IRQ_TYPE_LEVEL_HIGH>;
control-parent;
};
irqpin2: irqpin@e6900008 {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900008 4>,
<0xe6900048 1>,
<0xe6900068 1>;
interrupt-parent = <&gic>;
- interrupts = <0 17 0x4
- 0 18 0x4
- 0 19 0x4
- 0 20 0x4
- 0 21 0x4
- 0 22 0x4
- 0 23 0x4
- 0 24 0x4>;
+ interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH
+ 0 18 IRQ_TYPE_LEVEL_HIGH
+ 0 19 IRQ_TYPE_LEVEL_HIGH
+ 0 20 IRQ_TYPE_LEVEL_HIGH
+ 0 21 IRQ_TYPE_LEVEL_HIGH
+ 0 22 IRQ_TYPE_LEVEL_HIGH
+ 0 23 IRQ_TYPE_LEVEL_HIGH
+ 0 24 IRQ_TYPE_LEVEL_HIGH>;
};
irqpin3: irqpin@e690000c {
- compatible = "renesas,intc-irqpin";
+ compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe690000c 4>,
<0xe690004c 1>,
<0xe690006c 1>;
interrupt-parent = <&gic>;
- interrupts = <0 25 0x4
- 0 26 0x4
- 0 27 0x4
- 0 28 0x4
- 0 29 0x4
- 0 30 0x4
- 0 31 0x4
- 0 32 0x4>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH
+ 0 26 IRQ_TYPE_LEVEL_HIGH
+ 0 27 IRQ_TYPE_LEVEL_HIGH
+ 0 28 IRQ_TYPE_LEVEL_HIGH
+ 0 29 IRQ_TYPE_LEVEL_HIGH
+ 0 30 IRQ_TYPE_LEVEL_HIGH
+ 0 31 IRQ_TYPE_LEVEL_HIGH
+ 0 32 IRQ_TYPE_LEVEL_HIGH>;
};
i2c0: i2c@e6820000 {
compatible = "renesas,rmobile-iic";
reg = <0xe6820000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 167 0x4
- 0 168 0x4
- 0 169 0x4
- 0 170 0x4>;
+ interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH
+ 0 168 IRQ_TYPE_LEVEL_HIGH
+ 0 169 IRQ_TYPE_LEVEL_HIGH
+ 0 170 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0xe6822000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 51 0x4
- 0 52 0x4
- 0 53 0x4
- 0 54 0x4>;
+ interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH
+ 0 52 IRQ_TYPE_LEVEL_HIGH
+ 0 53 IRQ_TYPE_LEVEL_HIGH
+ 0 54 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0xe6824000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 171 0x4
- 0 172 0x4
- 0 173 0x4
- 0 174 0x4>;
+ interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH
+ 0 172 IRQ_TYPE_LEVEL_HIGH
+ 0 173 IRQ_TYPE_LEVEL_HIGH
+ 0 174 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0xe6826000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 183 0x4
- 0 184 0x4
- 0 185 0x4
- 0 186 0x4>;
+ interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH
+ 0 184 IRQ_TYPE_LEVEL_HIGH
+ 0 185 IRQ_TYPE_LEVEL_HIGH
+ 0 186 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
compatible = "renesas,rmobile-iic";
reg = <0xe6828000 0x425>;
interrupt-parent = <&gic>;
- interrupts = <0 187 0x4
- 0 188 0x4
- 0 189 0x4
- 0 190 0x4>;
+ interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH
+ 0 188 IRQ_TYPE_LEVEL_HIGH
+ 0 189 IRQ_TYPE_LEVEL_HIGH
+ 0 190 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- mmcif: mmcif@e6bd0000 {
+ mmcif: mmc@e6bd0000 {
compatible = "renesas,sh-mmcif";
reg = <0xe6bd0000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 140 0x4
- 0 141 0x4>;
+ interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
+ 0 141 IRQ_TYPE_LEVEL_HIGH>;
reg-io-width = <4>;
status = "disabled";
};
- sdhi0: sdhi@ee100000 {
- compatible = "renesas,sdhi-r8a7740";
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-sh73a0";
reg = <0xee100000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 83 4
- 0 84 4
- 0 85 4>;
+ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
+ 0 84 IRQ_TYPE_LEVEL_HIGH
+ 0 85 IRQ_TYPE_LEVEL_HIGH>;
cap-sd-highspeed;
status = "disabled";
};
/* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */
- sdhi1: sdhi@ee120000 {
- compatible = "renesas,sdhi-r8a7740";
+ sdhi1: sd@ee120000 {
+ compatible = "renesas,sdhi-sh73a0";
reg = <0xee120000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 88 4
- 0 89 4>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
+ 0 89 IRQ_TYPE_LEVEL_HIGH>;
toshiba,mmc-wrprotect-disable;
cap-sd-highspeed;
status = "disabled";
};
- sdhi2: sdhi@ee140000 {
- compatible = "renesas,sdhi-r8a7740";
+ sdhi2: sd@ee140000 {
+ compatible = "renesas,sdhi-sh73a0";
reg = <0xee140000 0x100>;
interrupt-parent = <&gic>;
- interrupts = <0 104 4
- 0 105 4>;
+ interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
+ 0 105 IRQ_TYPE_LEVEL_HIGH>;
toshiba,mmc-wrprotect-disable;
cap-sd-highspeed;
status = "disabled";
<0xe605801c 0x1c>;
gpio-controller;
#gpio-cells = <2>;
+ interrupts-extended =
+ <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
+ <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
+ <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
+ <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
+ <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
+ <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
+ <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
+ <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
+ };
+
+ sh_fsi2: sound@ec230000 {
+ #sound-dai-cells = <1>;
+ compatible = "renesas,sh_fsi2";
+ reg = <0xec230000 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 146 0x4>;
+ status = "disabled";
};
};
mpu_periph_clk: mpu_periph_clk {
#clock-cells = <0>;
- compatible = "altr,socfpga-gate-clk";
+ compatible = "altr,socfpga-perip-clk";
clocks = <&mpuclk>;
fixed-divider = <4>;
};
mpu_l2_ram_clk: mpu_l2_ram_clk {
#clock-cells = <0>;
- compatible = "altr,socfpga-gate-clk";
+ compatible = "altr,socfpga-perip-clk";
clocks = <&mpuclk>;
fixed-divider = <2>;
};
l3_main_clk: l3_main_clk {
#clock-cells = <0>;
- compatible = "altr,socfpga-gate-clk";
+ compatible = "altr,socfpga-perip-clk";
clocks = <&mainclk>;
+ fixed-divider = <1>;
};
l3_mp_clk: l3_mp_clk {
/* Pull Up */
#define PU (1 << 26)
/* Open Drain */
-#define OD (1 << 26)
+#define OD (1 << 25)
#define RT (1 << 23)
#define INVERTCLK (1 << 22)
#define CLKNOTDATA (1 << 21)
/* Custom board node with GPIO pins to active etc */
usb-s8815 {
- /* The S8815 is using this very GPIO pin for the SMSC91x IRQs */
- ethernet-gpio {
- gpios = <&gpio3 8 0x1>;
- };
/* This will bias the MMC/SD card detect line */
mmcsd-gpio {
gpios = <&gpio3 16 0x1>;
#size-cells = <1>;
ranges;
- vica: intc@0x10140000 {
+ vica: intc@10140000 {
compatible = "arm,versatile-vic";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x10140000 0x20>;
};
- vicb: intc@0x10140020 {
+ vicb: intc@10140020 {
compatible = "arm,versatile-vic";
interrupt-controller;
#interrupt-cells = <1>;
};
};
};
+
+ sbc_i2c0 {
+ pinctrl_sbc_i2c0_default: sbc_i2c0-default {
+ st,pins {
+ sda = <&PIO4 6 ALT1 BIDIR>;
+ scl = <&PIO4 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ sbc_i2c1 {
+ pinctrl_sbc_i2c1_default: sbc_i2c1-default {
+ st,pins {
+ sda = <&PIO3 2 ALT2 BIDIR>;
+ scl = <&PIO3 1 ALT2 BIDIR>;
+ };
+ };
+ };
};
pin-controller-front {
reg = <0x7000 0x100>;
st,bank-name = "PIO12";
};
+
+ i2c0 {
+ pinctrl_i2c0_default: i2c0-default {
+ st,pins {
+ sda = <&PIO9 3 ALT1 BIDIR>;
+ scl = <&PIO9 2 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_default: i2c1-default {
+ st,pins {
+ sda = <&PIO12 1 ALT1 BIDIR>;
+ scl = <&PIO12 0 ALT1 BIDIR>;
+ };
+ };
+ };
};
pin-controller-rear {
#include "stih41x.dtsi"
#include "stih415-clock.dtsi"
#include "stih415-pinctrl.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
L2: cache-controller {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sbc_serial1>;
};
+
+ i2c@fed40000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed40000 0x110>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLKS_ICN_REG_0>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fed41000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed41000 0x110>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLKS_ICN_REG_0>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe540000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe540000 0x110>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_SYSIN>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe541000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe541000 0x110>;
+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_SYSIN>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
+
+ status = "disabled";
+ };
};
};
};
};
};
+
+ sbc_i2c0 {
+ pinctrl_sbc_i2c0_default: sbc_i2c0-default {
+ st,pins {
+ sda = <&PIO4 6 ALT1 BIDIR>;
+ scl = <&PIO4 5 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ sbc_i2c1 {
+ pinctrl_sbc_i2c1_default: sbc_i2c1-default {
+ st,pins {
+ sda = <&PIO3 2 ALT2 BIDIR>;
+ scl = <&PIO3 1 ALT2 BIDIR>;
+ };
+ };
+ };
};
pin-controller-front {
};
};
+ i2c0 {
+ pinctrl_i2c0_default: i2c0-default {
+ st,pins {
+ sda = <&PIO9 3 ALT1 BIDIR>;
+ scl = <&PIO9 2 ALT1 BIDIR>;
+ };
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_default: i2c1-default {
+ st,pins {
+ sda = <&PIO12 1 ALT1 BIDIR>;
+ scl = <&PIO12 0 ALT1 BIDIR>;
+ };
+ };
+ };
};
pin-controller-rear {
#include "stih41x.dtsi"
#include "stih416-clock.dtsi"
#include "stih416-pinctrl.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
L2: cache-controller {
compatible = "arm,pl310-cache";
pinctrl-0 = <&pinctrl_sbc_serial1>;
clocks = <&CLK_SYSIN>;
};
+
+ i2c@fed40000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed40000 0x110>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_S_ICN_REG_0>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fed41000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfed41000 0x110>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_S_ICN_REG_0>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe540000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe540000 0x110>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_SYSIN>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
+
+ status = "disabled";
+ };
+
+ i2c@fe541000 {
+ compatible = "st,comms-ssc4-i2c";
+ reg = <0xfe541000 0x110>;
+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CLK_SYSIN>;
+ clock-names = "ssc";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
+
+ status = "disabled";
+ };
};
};
};
};
+ /* HDMI Tx I2C */
+ i2c@fed41000 {
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ i2c-min-scl-pulse-width-us = <0>;
+ i2c-min-sda-pulse-width-us = <5>;
+
+ status = "okay";
+ };
};
};
default-state = "off";
};
};
+
+ i2c@fed40000 {
+ status = "okay";
+ };
+
+ /* HDMI Tx I2C */
+ i2c@fed41000 {
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ i2c-min-scl-pulse-width-us = <0>;
+ i2c-min-sda-pulse-width-us = <5>;
+
+ status = "okay";
+ };
+
+ i2c@fe540000 {
+ status = "okay";
+ };
+
+ i2c@fe541000 {
+ status = "okay";
+ };
};
};
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x01c20c90 0x10>;
};
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun4i-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <24>;
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
cpu@0 {
compatible = "arm,cortex-a8";
--- /dev/null
+/*
+ * Copyright 2012 Maxime Ripard
+ * Copyright 2013 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun5i-a13.dtsi"
+
+/ {
+ model = "Olimex A13-Olinuxino Micro";
+ compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
+
+ soc@01c00000 {
+ pinctrl@01c20800 {
+ led_pins_olinuxinom: led_pins@0 {
+ allwinner,pins = "PG9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <1>;
+ allwinner,pull = <0>;
+ };
+ };
+
+ uart1: serial@01c28400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinom>;
+
+ power {
+ label = "a13-olinuxino-micro:green:power";
+ gpios = <&pio 6 9 0>;
+ default-state = "on";
+ };
+ };
+};
};
};
+ ahb1_rst: reset@01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-ahb1-reset";
+ reg = <0x01c202c0 0xc>;
+ };
+
+ apb1_rst: reset@01c202d0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d0 0x4>;
+ };
+
+ apb2_rst: reset@01c202d8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d8 0x4>;
+ };
+
timer@01c20c00 {
compatible = "allwinner,sun4i-timer";
reg = <0x01c20c00 0xa0>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 16>;
+ resets = <&apb2_rst 16>;
status = "disabled";
};
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 17>;
+ resets = <&apb2_rst 17>;
status = "disabled";
};
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 18>;
+ resets = <&apb2_rst 18>;
status = "disabled";
};
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 19>;
+ resets = <&apb2_rst 19>;
status = "disabled";
};
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 20>;
+ resets = <&apb2_rst 20>;
status = "disabled";
};
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 21>;
+ resets = <&apb2_rst 21>;
status = "disabled";
};
#interrupt-cells = <3>;
interrupts = <1 9 0xf04>;
};
+
+ cpucfg@01f01c00 {
+ compatible = "allwinner,sun6i-a31-cpuconfig";
+ reg = <0x01f01c00 0x300>;
+ };
+
+ prcm@01f01c00 {
+ compatible = "allwinner,sun6i-a31-prcm";
+ reg = <0x01f01400 0x200>;
+ };
};
};
/ {
interrupt-parent = <&gic>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x01c20c90 0x10>;
};
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun7i-a20-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <0 24 1>;
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
model = "NVIDIA Tegra114 Dalmore evaluation board";
compatible = "nvidia,dalmore", "nvidia,tegra114";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps65913@58";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x80000000 0x40000000>;
};
- pinmux {
+ host1x@50000000 {
+ hdmi@54280000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_hdmi_reg>;
+ pll-supply = <&palmas_smps3_reg>;
+
+ nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio =
+ <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+ };
+
+ dsi@54300000 {
+ status = "okay";
+
+ panel@0 {
+ compatible = "panasonic,vvx10f004b00",
+ "simple-panel";
+ reg = <0>;
+
+ power-supply = <&avdd_lcd_reg>;
+ backlight = <&backlight>;
+ };
+ };
+ };
+
+ pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
clk1_out_pw4 {
nvidia,pins = "clk1_out_pw4";
nvidia,function = "extperiph1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
dap1_din_pn1 {
nvidia,pins = "dap1_din_pn1";
nvidia,function = "i2s0";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap1_dout_pn2 {
nvidia,pins = "dap1_dout_pn2",
"dap1_fs_pn0",
"dap1_sclk_pn3";
nvidia,function = "i2s0";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap2_din_pa4 {
nvidia,pins = "dap2_din_pa4";
nvidia,function = "i2s1";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap2_dout_pa5 {
nvidia,pins = "dap2_dout_pa5",
"dap2_fs_pa2",
"dap2_sclk_pa3";
nvidia,function = "i2s1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap4_din_pp5 {
nvidia,pins = "dap4_din_pp5",
"dap4_fs_pp4",
"dap4_sclk_pp7";
nvidia,function = "i2s3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dvfs_pwm_px0 {
nvidia,pins = "dvfs_pwm_px0",
"dvfs_clk_px2";
nvidia,function = "cldvfs";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
ulpi_clk_py0 {
nvidia,pins = "ulpi_clk_py0",
"ulpi_data6_po7",
"ulpi_data7_po0";
nvidia,function = "ulpi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
ulpi_dir_py1 {
nvidia,pins = "ulpi_dir_py1",
"ulpi_nxt_py2";
nvidia,function = "ulpi";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
ulpi_stp_py3 {
nvidia,pins = "ulpi_stp_py3";
nvidia,function = "ulpi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
cam_i2c_scl_pbb1 {
nvidia,pins = "cam_i2c_scl_pbb1",
"cam_i2c_sda_pbb2";
nvidia,function = "i2c3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
};
cam_mclk_pcc0 {
nvidia,pins = "cam_mclk_pcc0",
"pbb0";
nvidia,function = "vi_alt3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
- nvidia,lock = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
};
gen2_i2c_scl_pt5 {
nvidia,pins = "gen2_i2c_scl_pt5",
"gen2_i2c_sda_pt6";
nvidia,function = "i2c2";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
};
gmi_a16_pj7 {
nvidia,pins = "gmi_a16_pj7";
nvidia,function = "uartd";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_a17_pb0 {
nvidia,pins = "gmi_a17_pb0",
"gmi_a18_pb1";
nvidia,function = "uartd";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_a19_pk7 {
nvidia,pins = "gmi_a19_pk7";
nvidia,function = "uartd";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_ad5_pg5 {
nvidia,pins = "gmi_ad5_pg5",
"gmi_cs6_n_pi3",
"gmi_wr_n_pi0";
nvidia,function = "spi4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_ad6_pg6 {
nvidia,pins = "gmi_ad6_pg6",
"gmi_ad7_pg7";
nvidia,function = "spi4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_ad12_ph4 {
nvidia,pins = "gmi_ad12_ph4";
nvidia,function = "rsvd4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_ad9_ph1 {
nvidia,pins = "gmi_ad9_ph1";
nvidia,function = "pwm1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_cs1_n_pj2 {
nvidia,pins = "gmi_cs1_n_pj2",
"gmi_oe_n_pi1";
nvidia,function = "soc";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
clk2_out_pw5 {
nvidia,pins = "clk2_out_pw5";
nvidia,function = "extperiph2";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
sdmmc1_clk_pz0 {
nvidia,pins = "sdmmc1_clk_pz0";
nvidia,function = "sdmmc1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
sdmmc1_cmd_pz1 {
nvidia,pins = "sdmmc1_cmd_pz1",
"sdmmc1_dat2_py5",
"sdmmc1_dat3_py4";
nvidia,function = "sdmmc1";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
sdmmc1_wp_n_pv3 {
nvidia,pins = "sdmmc1_wp_n_pv3";
nvidia,function = "spi4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
sdmmc3_clk_pa6 {
nvidia,pins = "sdmmc3_clk_pa6";
nvidia,function = "sdmmc3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
sdmmc3_cmd_pa7 {
nvidia,pins = "sdmmc3_cmd_pa7",
"sdmmc3_clk_lb_out_pee4",
"sdmmc3_clk_lb_in_pee5";
nvidia,function = "sdmmc3";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
sdmmc4_clk_pcc4 {
nvidia,pins = "sdmmc4_clk_pcc4";
nvidia,function = "sdmmc4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
sdmmc4_cmd_pt7 {
nvidia,pins = "sdmmc4_cmd_pt7",
"sdmmc4_dat6_paa6",
"sdmmc4_dat7_paa7";
nvidia,function = "sdmmc4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
clk_32k_out_pa0 {
nvidia,pins = "clk_32k_out_pa0";
nvidia,function = "blink";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
kb_col0_pq0 {
nvidia,pins = "kb_col0_pq0",
"kb_row1_pr1",
"kb_row2_pr2";
nvidia,function = "kbc";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap3_din_pp1 {
nvidia,pins = "dap3_din_pp1",
"dap3_sclk_pp3";
nvidia,function = "displayb";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pv0 {
nvidia,pins = "pv0";
nvidia,function = "rsvd4";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
kb_row7_pr7 {
nvidia,pins = "kb_row7_pr7";
nvidia,function = "rsvd2";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
kb_row10_ps2 {
nvidia,pins = "kb_row10_ps2";
nvidia,function = "uarta";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
kb_row9_ps1 {
nvidia,pins = "kb_row9_ps1";
nvidia,function = "uarta";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pwr_i2c_scl_pz6 {
nvidia,pins = "pwr_i2c_scl_pz6",
"pwr_i2c_sda_pz7";
nvidia,function = "i2cpwr";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
};
sys_clk_req_pz5 {
nvidia,pins = "sys_clk_req_pz5";
nvidia,function = "sysclk";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
core_pwr_req {
nvidia,pins = "core_pwr_req";
nvidia,function = "pwron";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
cpu_pwr_req {
nvidia,pins = "cpu_pwr_req";
nvidia,function = "cpu";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pwr_int_n {
nvidia,pins = "pwr_int_n";
nvidia,function = "pmi";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
reset_out_n {
nvidia,pins = "reset_out_n";
nvidia,function = "reset_out_n";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
clk3_out_pee0 {
nvidia,pins = "clk3_out_pee0";
nvidia,function = "extperiph3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gen1_i2c_scl_pc4 {
nvidia,pins = "gen1_i2c_scl_pc4",
"gen1_i2c_sda_pc5";
nvidia,function = "i2c1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
};
uart2_cts_n_pj5 {
nvidia,pins = "uart2_cts_n_pj5";
nvidia,function = "uartb";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
uart2_rts_n_pj6 {
nvidia,pins = "uart2_rts_n_pj6";
nvidia,function = "uartb";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
uart2_rxd_pc3 {
nvidia,pins = "uart2_rxd_pc3";
nvidia,function = "irda";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
uart2_txd_pc2 {
nvidia,pins = "uart2_txd_pc2";
nvidia,function = "irda";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
uart3_cts_n_pa1 {
nvidia,pins = "uart3_cts_n_pa1",
"uart3_rxd_pw7";
nvidia,function = "uartc";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
uart3_rts_n_pc0 {
nvidia,pins = "uart3_rts_n_pc0",
"uart3_txd_pw6";
nvidia,function = "uartc";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
owr {
nvidia,pins = "owr";
nvidia,function = "owr";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
hdmi_cec_pee3 {
nvidia,pins = "hdmi_cec_pee3";
nvidia,function = "cec";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
};
ddc_scl_pv4 {
nvidia,pins = "ddc_scl_pv4",
"ddc_sda_pv5";
nvidia,function = "i2c4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,rcv-sel = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
};
spdif_in_pk6 {
nvidia,pins = "spdif_in_pk6";
nvidia,function = "usb";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
};
usb_vbus_en0_pn4 {
nvidia,pins = "usb_vbus_en0_pn4";
nvidia,function = "usb";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
- nvidia,lock = <0>;
- nvidia,open-drain = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
};
gpio_x6_aud_px6 {
nvidia,pins = "gpio_x6_aud_px6";
nvidia,function = "spi6";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gpio_x4_aud_px4 {
nvidia,pins = "gpio_x4_aud_px4",
"gpio_x7_aud_px7";
nvidia,function = "rsvd1";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gpio_x5_aud_px5 {
nvidia,pins = "gpio_x5_aud_px5";
nvidia,function = "rsvd1";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gpio_w2_aud_pw2 {
nvidia,pins = "gpio_w2_aud_pw2";
nvidia,function = "rsvd2";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gpio_w3_aud_pw3 {
nvidia,pins = "gpio_w3_aud_pw3";
nvidia,function = "spi6";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gpio_x1_aud_px1 {
nvidia,pins = "gpio_x1_aud_px1";
nvidia,function = "rsvd4";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gpio_x3_aud_px3 {
nvidia,pins = "gpio_x3_aud_px3";
nvidia,function = "rsvd4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
dap3_fs_pp0 {
nvidia,pins = "dap3_fs_pp0";
nvidia,function = "i2s2";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
dap3_dout_pp2 {
nvidia,pins = "dap3_dout_pp2";
nvidia,function = "i2s2";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pv1 {
nvidia,pins = "pv1";
nvidia,function = "rsvd1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
pbb3 {
nvidia,pins = "pbb3",
"pbb6",
"pbb7";
nvidia,function = "rsvd4";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pcc1 {
nvidia,pins = "pcc1",
"pcc2";
nvidia,function = "rsvd4";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_ad0_pg0 {
nvidia,pins = "gmi_ad0_pg0",
"gmi_ad1_pg1";
nvidia,function = "gmi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_ad10_ph2 {
nvidia,pins = "gmi_ad10_ph2",
"gmi_ad8_ph0",
"gmi_clk_pk1";
nvidia,function = "gmi";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
gmi_ad2_pg2 {
nvidia,pins = "gmi_ad2_pg2",
"gmi_ad3_pg3";
nvidia,function = "gmi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_adv_n_pk0 {
nvidia,pins = "gmi_adv_n_pk0",
"gmi_iordy_pi5",
"gmi_wp_n_pc7";
nvidia,function = "gmi";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
gmi_cs3_n_pk4 {
nvidia,pins = "gmi_cs3_n_pk4";
nvidia,function = "gmi";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
clk2_req_pcc5 {
nvidia,pins = "clk2_req_pcc5";
nvidia,function = "rsvd4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
kb_col3_pq3 {
nvidia,pins = "kb_col3_pq3",
"kb_col6_pq6",
"kb_col7_pq7";
nvidia,function = "kbc";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
kb_col5_pq5 {
nvidia,pins = "kb_col5_pq5";
nvidia,function = "kbc";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
kb_row3_pr3 {
nvidia,pins = "kb_row3_pr3",
"kb_row6_pr6",
"kb_row8_ps0";
nvidia,function = "kbc";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
clk3_req_pee1 {
nvidia,pins = "clk3_req_pee1";
nvidia,function = "rsvd4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pu4 {
nvidia,pins = "pu4";
nvidia,function = "displayb";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
pu5 {
nvidia,pins = "pu5",
"pu6";
nvidia,function = "displayb";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
hdmi_int_pn7 {
nvidia,pins = "hdmi_int_pn7";
nvidia,function = "rsvd1";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- nvidia,enable-input = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
clk1_req_pee2 {
nvidia,pins = "clk1_req_pee2",
"usb_vbus_en1_pn5";
nvidia,function = "rsvd4";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
- nvidia,enable-input = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
drive_sdio1 {
nvidia,pins = "drive_sdio1";
- nvidia,high-speed-mode = <1>;
- nvidia,schmitt = <0>;
- nvidia,low-power-mode = <3>;
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
nvidia,pull-down-strength = <36>;
nvidia,pull-up-strength = <20>;
- nvidia,slew-rate-rising = <2>;
- nvidia,slew-rate-falling = <2>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOW>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOW>;
};
drive_sdio3 {
nvidia,pins = "drive_sdio3";
- nvidia,high-speed-mode = <1>;
- nvidia,schmitt = <0>;
- nvidia,low-power-mode = <3>;
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
nvidia,pull-down-strength = <22>;
nvidia,pull-up-strength = <36>;
- nvidia,slew-rate-rising = <0>;
- nvidia,slew-rate-falling = <0>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
};
drive_gma {
nvidia,pins = "drive_gma";
- nvidia,high-speed-mode = <1>;
- nvidia,schmitt = <0>;
- nvidia,low-power-mode = <3>;
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
nvidia,pull-down-strength = <2>;
nvidia,pull-up-strength = <1>;
- nvidia,slew-rate-rising = <0>;
- nvidia,slew-rate-falling = <0>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
nvidia,drive-type = <1>;
};
};
status = "okay";
};
+ pwm@7000a000 {
+ status = "okay";
+ };
+
i2c@7000c000 {
status = "okay";
clock-frequency = <100000>;
- battery: smart-battery {
+ battery: smart-battery@b {
compatible = "ti,bq20z45", "sbs,sbs-battery";
reg = <0xb>;
battery-name = "battery";
power-supplies = <&charger>;
};
- rt5640: rt5640 {
+ rt5640: rt5640@1c {
compatible = "realtek,rt5640";
reg = <0x1c>;
interrupt-parent = <&gpio>;
};
};
+ hdmi_ddc: i2c@7000c700 {
+ status = "okay";
+ };
+
i2c@7000d000 {
status = "okay";
clock-frequency = <400000>;
- tps51632 {
+ tps51632@43 {
compatible = "ti,tps51632";
reg = <0x43>;
regulator-name = "vdd-cpu";
regulator-always-on;
};
- tps65090 {
+ tps65090@48 {
compatible = "ti,tps65090";
reg = <0x48>;
interrupt-parent = <&gpio>;
regulator-boot-on;
};
- fet1 {
+ vdd_bl_reg: fet1 {
regulator-name = "vdd-lcd-bl";
};
regulator-name = "vdd-modem-3v3";
};
- fet4 {
+ avdd_lcd_reg: fet4 {
regulator-name = "avdd-lcd";
};
};
};
- palmas: tps65913 {
+ palmas: tps65913@58 {
compatible = "ti,palmas";
reg = <0x58>;
interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>;
};
};
- pmc {
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <500>;
nvidia,sys-clock-req-active-high;
};
- ahub {
+ ahub@70080000 {
i2s@70080400 {
status = "okay";
};
vbus-supply = <&usb3_vbus_reg>;
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 1 1000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
gpio = <&gpio TEGRA_GPIO(H, 5) GPIO_ACTIVE_HIGH>;
};
- lcd_bl_en_reg: regulator@2 {
- compatible = "regulator-fixed";
- reg = <2>;
- regulator-name = "lcd_bl_en";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- gpio = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
- };
-
usb1_vbus_reg: regulator@3 {
compatible = "regulator-fixed";
reg = <3>;
#include <dt-bindings/clock/tegra114-car.h>
#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
serial3 = &uartd;
};
- gic: interrupt-controller {
+ host1x@50000000 {
+ compatible = "nvidia,tegra114-host1x", "simple-bus";
+ reg = <0x50000000 0x00028000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+ clocks = <&tegra_car TEGRA114_CLK_HOST1X>;
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x54000000 0x54000000 0x01000000>;
+
+ gr2d@54140000 {
+ compatible = "nvidia,tegra114-gr2d", "nvidia,tegra20-gr2d";
+ reg = <0x54140000 0x00040000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_GR2D>;
+ resets = <&tegra_car 21>;
+ reset-names = "2d";
+ };
+
+ gr3d@54180000 {
+ compatible = "nvidia,tegra114-gr3d", "nvidia,tegra20-gr3d";
+ reg = <0x54180000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_GR3D>;
+ resets = <&tegra_car 24>;
+ reset-names = "3d";
+ };
+
+ dc@54200000 {
+ compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc";
+ reg = <0x54200000 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_DISP1>,
+ <&tegra_car TEGRA114_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 27>;
+ reset-names = "dc";
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ dc@54240000 {
+ compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc";
+ reg = <0x54240000 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_DISP2>,
+ <&tegra_car TEGRA114_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ rgb {
+ status = "disabled";
+ };
+ };
+
+ hdmi@54280000 {
+ compatible = "nvidia,tegra114-hdmi";
+ reg = <0x54280000 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA114_CLK_HDMI>,
+ <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>;
+ clock-names = "hdmi", "parent";
+ resets = <&tegra_car 51>;
+ reset-names = "hdmi";
+ status = "disabled";
+ };
+
+ dsi@54300000 {
+ compatible = "nvidia,tegra114-dsi";
+ reg = <0x54300000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_DSIA>,
+ <&tegra_car TEGRA114_CLK_DSIALP>,
+ <&tegra_car TEGRA114_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x060>; /* DSIA & DSIB pads */
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ dsi@54400000 {
+ compatible = "nvidia,tegra114-dsi";
+ reg = <0x54400000 0x00040000>;
+ clocks = <&tegra_car TEGRA114_CLK_DSIB>,
+ <&tegra_car TEGRA114_CLK_DSIBLP>,
+ <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 82>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x180>; /* DSIC & DSID pads */
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ gic: interrupt-controller@50041000 {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
interrupt-controller;
clocks = <&tegra_car TEGRA114_CLK_TIMER>;
};
- tegra_car: clock {
+ tegra_car: clock@60006000 {
compatible = "nvidia,tegra114-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
- apbdma: dma {
+ apbdma: dma@6000a000 {
compatible = "nvidia,tegra114-apbdma";
reg = <0x6000a000 0x1400>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
<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 {
+ ahb: ahb@6000c004 {
compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
reg = <0x6000c004 0x14c>;
};
- gpio: gpio {
+ gpio: gpio@6000d000 {
compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
reg = <0x6000d000 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
interrupt-controller;
};
- pinmux: pinmux {
+ pinmux: pinmux@70000868 {
compatible = "nvidia,tegra114-pinmux";
reg = <0x70000868 0x148 /* Pad control registers */
0x70003000 0x40c>; /* Mux registers */
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 {
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 {
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 {
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 {
+ pwm: pwm@7000a000 {
compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car TEGRA114_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
status = "disabled";
};
#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";
};
#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";
};
#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";
};
#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";
};
#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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
- rtc {
+ rtc@7000e000 {
compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA114_CLK_RTC>;
};
- kbc {
+ kbc@7000e200 {
compatible = "nvidia,tegra114-kbc";
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";
};
- pmc {
+ pmc@7000e400 {
compatible = "nvidia,tegra114-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
};
- iommu {
+ iommu@70019010 {
compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
reg = <0x70019010 0x02c
0x700191f0 0x010
nvidia,ahb = <&ahb>;
};
- ahub {
+ ahub@70080000 {
compatible = "nvidia,tegra114-ahub";
reg = <0x70080000 0x200>,
<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>;
reg = <0x70080300 0x100>;
nvidia,ahub-cif-ids = <4 4>;
clocks = <&tegra_car TEGRA114_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080400 0x100>;
nvidia,ahub-cif-ids = <5 5>;
clocks = <&tegra_car TEGRA114_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080500 0x100>;
nvidia,ahub-cif-ids = <6 6>;
clocks = <&tegra_car TEGRA114_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080600 0x100>;
nvidia,ahub-cif-ids = <7 7>;
clocks = <&tegra_car TEGRA114_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080700 0x100>;
nvidia,ahub-cif-ids = <8 8>;
clocks = <&tegra_car TEGRA114_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
status = "disabled";
};
};
+ mipi: mipi@700e3000 {
+ compatible = "nvidia,tegra114-mipi";
+ reg = <0x700e3000 0x100>;
+ clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
+ #nvidia,mipi-calibrate-cells = <1>;
+ };
+
sdhci@78000000 {
compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra124.dtsi"
/ {
model = "NVIDIA Tegra124 Venice2";
compatible = "nvidia,venice2", "nvidia,tegra124";
+ aliases {
+ rtc0 = "/i2c@7000d000/as3722@40";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x80000000 0x80000000>;
};
+ pinmux: pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinmux_default>;
+
+ pinmux_default: common {
+ dap_mclk1_pw4 {
+ nvidia,pins = "dap_mclk1_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2",
+ "dap1_fs_pn0",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5",
+ "dap2_fs_pa2",
+ "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0",
+ "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_nxt_py2",
+ "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "spi1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ pg4 {
+ nvidia,pins = "pg4",
+ "pg5",
+ "pg6",
+ "pi3";
+ nvidia,function = "spi4";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pg7 {
+ nvidia,pins = "pg7";
+ nvidia,function = "spi4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0",
+ "kb_row15_ps7",
+ "clk_32k_out_pa0";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0",
+ "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "rtck";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_in {
+ nvidia,pins = "clk_32k_in";
+ nvidia,function = "clk";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5";
+ nvidia,function = "i2s3";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_dout_pp6 {
+ nvidia,pins = "dap4_dout_pp6",
+ "dap4_fs_pp4",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+ gen1_i2c_sda_pc5 {
+ nvidia,pins = "gen1_i2c_sda_pc5",
+ "gen1_i2c_scl_pc4";
+ nvidia,function = "i2c1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7",
+ "pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pb0 {
+ nvidia,pins = "pb0",
+ "pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ph0 {
+ nvidia,pins = "ph0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ kb_row6_pr6 {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "displaya_alt";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en1_pn5 {
+ nvidia,pins = "usb_vbus_en1_pn5";
+ nvidia,function = "usb";
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ };
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <32>;
+ nvidia,pull-up-strength = <42>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <20>;
+ nvidia,pull-up-strength = <36>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ drive_gma {
+ nvidia,pins = "drive_gma";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <1>;
+ nvidia,pull-up-strength = <2>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,drive-type = <1>;
+ };
+ als_irq_l {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ codec_irq_l {
+ nvidia,pins = "ph4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd_bl_en {
+ nvidia,pins = "ph2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ touch_irq_l {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ tpm_davint_l {
+ nvidia,pins = "ph6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ts_irq_l {
+ nvidia,pins = "pk2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ts_reset_l {
+ nvidia,pins = "pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ts_shdn_l {
+ nvidia,pins = "pk1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ph7 {
+ nvidia,pins = "ph7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ kb_col0_ap {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lid_open {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ en_vdd_sd {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ac_ok {
+ nvidia,pins = "pj0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sensor_irq_l {
+ nvidia,pins = "pi6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ wifi_en {
+ nvidia,pins = "gpio_x7_aud_px7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_rst_l {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hp_det_l {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ };
+ };
+
serial@70006000 {
status = "okay";
};
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ acodec: audio-codec@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ as3722: as3722@40 {
+ compatible = "ams,as3722";
+ reg = <0x40>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&as3722_default>;
+
+ as3722_default: pinmux {
+ gpio0 {
+ pins = "gpio0";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ gpio1_2_4_7 {
+ pins = "gpio1", "gpio2", "gpio4", "gpio7";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ gpio3_6 {
+ pins = "gpio3", "gpio6";
+ bias-high-impedance;
+ };
+
+ gpio5 {
+ pins = "gpio5";
+ function = "clk32k-out";
+ };
+ };
+
+ regulators {
+ vsup-sd2-supply = <&vdd_ac_bat_reg>;
+ vsup-sd3-supply = <&vdd_ac_bat_reg>;
+ vsup-sd4-supply = <&vdd_ac_bat_reg>;
+ vsup-sd5-supply = <&vdd_ac_bat_reg>;
+ vin-ldo0-supply = <&as3722_sd2>;
+ vin-ldo1-6-supply = <&vdd_ac_bat_reg>;
+ vin-ldo2-5-7-supply = <&as3722_sd5>;
+ vin-ldo3-4-supply = <&vdd_ac_bat_reg>;
+ vin-ldo9-10-supply = <&vdd_ac_bat_reg>;
+ vin-ldo11-supply = <&vdd_ac_bat_reg>;
+
+ sd0 {
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,external-control = <2>;
+ };
+
+ sd1 {
+ regulator-name = "vdd-core";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microamp = <2500000>;
+ regulator-max-microamp = <2500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,external-control = <1>;
+ };
+
+ as3722_sd2: sd2 {
+ regulator-name = "vddio-ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sd3 {
+ regulator-name = "vddio-ddr-2phase";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sd4 {
+ regulator-name = "avdd-pex-sata";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ as3722_sd5: sd5 {
+ regulator-name = "vddio-sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sd6 {
+ regulator-name = "vdd-gpu";
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo0 {
+ regulator-name = "avdd_pll";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,external-control = <1>;
+ };
+
+ ldo1 {
+ regulator-name = "run-cam-1.8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2 {
+ regulator-name = "gen-avdd,vddio-hsic";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3 {
+ regulator-name = "vdd-rtc";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,enable-tracking;
+ };
+
+ ldo4 {
+ regulator-name = "vdd-cam";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5 {
+ regulator-name = "vdd-cam-front";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo6 {
+ regulator-name = "vddio-sdmmc3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo7 {
+ regulator-name = "vdd-cam-rear";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ ldo9 {
+ regulator-name = "vdd-touch";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo10 {
+ regulator-name = "vdd-cam-af";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo11 {
+ regulator-name = "vpp-fuse";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ spi@7000d400 {
+ status = "okay";
+
+ cros-ec@0 {
+ compatible = "google,cros-ec-spi";
+ spi-max-frequency = <4000000>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
+ reg = <0>;
+
+ google,cros-ec-spi-msg-delay = <2000>;
+
+ cros-ec-keyb {
+ compatible = "google,cros-ec-keyb";
+ keypad,num-rows = <8>;
+ keypad,num-columns = <13>;
+ google,needs-ghost-filter;
+
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
+ MATRIX_KEY(0x00, 0x02, KEY_F1)
+ MATRIX_KEY(0x00, 0x03, KEY_B)
+ MATRIX_KEY(0x00, 0x04, KEY_F10)
+ MATRIX_KEY(0x00, 0x06, KEY_N)
+ MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
+ MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
+
+ MATRIX_KEY(0x01, 0x01, KEY_ESC)
+ MATRIX_KEY(0x01, 0x02, KEY_F4)
+ MATRIX_KEY(0x01, 0x03, KEY_G)
+ MATRIX_KEY(0x01, 0x04, KEY_F7)
+ MATRIX_KEY(0x01, 0x06, KEY_H)
+ MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
+ MATRIX_KEY(0x01, 0x09, KEY_F9)
+ MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
+
+ MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
+ MATRIX_KEY(0x02, 0x01, KEY_TAB)
+ MATRIX_KEY(0x02, 0x02, KEY_F3)
+ MATRIX_KEY(0x02, 0x03, KEY_T)
+ MATRIX_KEY(0x02, 0x04, KEY_F6)
+ MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x02, 0x06, KEY_Y)
+ MATRIX_KEY(0x02, 0x07, KEY_102ND)
+ MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
+ MATRIX_KEY(0x02, 0x09, KEY_F8)
+
+ MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x03, 0x02, KEY_F2)
+ MATRIX_KEY(0x03, 0x03, KEY_5)
+ MATRIX_KEY(0x03, 0x04, KEY_F5)
+ MATRIX_KEY(0x03, 0x06, KEY_6)
+ MATRIX_KEY(0x03, 0x08, KEY_MINUS)
+ MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
+
+ MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x04, 0x01, KEY_A)
+ MATRIX_KEY(0x04, 0x02, KEY_D)
+ MATRIX_KEY(0x04, 0x03, KEY_F)
+ MATRIX_KEY(0x04, 0x04, KEY_S)
+ MATRIX_KEY(0x04, 0x05, KEY_K)
+ MATRIX_KEY(0x04, 0x06, KEY_J)
+ MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
+ MATRIX_KEY(0x04, 0x09, KEY_L)
+ MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+ MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
+
+ MATRIX_KEY(0x05, 0x01, KEY_Z)
+ MATRIX_KEY(0x05, 0x02, KEY_C)
+ MATRIX_KEY(0x05, 0x03, KEY_V)
+ MATRIX_KEY(0x05, 0x04, KEY_X)
+ MATRIX_KEY(0x05, 0x05, KEY_COMMA)
+ MATRIX_KEY(0x05, 0x06, KEY_M)
+ MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x05, 0x08, KEY_SLASH)
+ MATRIX_KEY(0x05, 0x09, KEY_DOT)
+ MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
+
+ MATRIX_KEY(0x06, 0x01, KEY_1)
+ MATRIX_KEY(0x06, 0x02, KEY_3)
+ MATRIX_KEY(0x06, 0x03, KEY_4)
+ MATRIX_KEY(0x06, 0x04, KEY_2)
+ MATRIX_KEY(0x06, 0x05, KEY_8)
+ MATRIX_KEY(0x06, 0x06, KEY_7)
+ MATRIX_KEY(0x06, 0x08, KEY_0)
+ MATRIX_KEY(0x06, 0x09, KEY_9)
+ MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
+ MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
+ MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
+
+ MATRIX_KEY(0x07, 0x01, KEY_Q)
+ MATRIX_KEY(0x07, 0x02, KEY_E)
+ MATRIX_KEY(0x07, 0x03, KEY_R)
+ MATRIX_KEY(0x07, 0x04, KEY_W)
+ MATRIX_KEY(0x07, 0x05, KEY_I)
+ MATRIX_KEY(0x07, 0x06, KEY_U)
+ MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x07, 0x08, KEY_P)
+ MATRIX_KEY(0x07, 0x09, KEY_O)
+ MATRIX_KEY(0x07, 0x0b, KEY_UP)
+ MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
+ >;
+ };
+ };
+ };
+
pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,core-power-req-active-high;
nvidia,sys-clock-req-active-high;
};
+
+ sdhci@700b0400 {
+ cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ bus-width = <4>;
+ };
+
+ sdhci@700b0600 {
+ status = "okay";
+ bus-width = <8>;
+ };
+
+ ahub@70300000 {
+ i2s@70301100 {
+ status = "okay";
+ };
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_ac_bat_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_ac_bat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "vdd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&as3722 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_3v3_modem_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "vdd-modem-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&as3722 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_hdmi_5v0_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "vdd-hdmi-5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+ };
+
+ vdd_bl_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "vdd-bl";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_LOW>;
+ };
+
+ vdd_ts_sw_5v0: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_ts_sw";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_LOW>;
+ };
+
+ usb1_vbus_reg: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ };
+
+ usb3_vbus_reg: regulator@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ regulator-name = "usb3_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+ gpio-open-drain;
+ };
+
+ panel_3v3_reg: regulator@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "panel_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&as3722 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-max98090-venice2",
+ "nvidia,tegra-audio-max98090";
+ nvidia,model = "NVIDIA Tegra Venice2";
+
+ nvidia,audio-routing =
+ "Headphones", "HPR",
+ "Headphones", "HPL",
+ "Speakers", "SPKR",
+ "Speakers", "SPKL",
+ "Mic Jack", "MICBIAS",
+ "IN34", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&acodec>;
+
+ clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
+ <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA124_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
};
+#include <dt-bindings/clock/tegra124-car.h>
#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_TIMER>;
+ };
+
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra124-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
};
gpio: gpio@6000d000 {
interrupt-controller;
};
+ apbdma: dma@60020000 {
+ compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma";
+ reg = <0x60020000 0x1400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_APBDMA>;
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ pinmux: pinmux@70000868 {
+ compatible = "nvidia,tegra124-pinmux";
+ reg = <0x70000868 0x164>, /* Pad control registers */
+ <0x70003000 0x434>; /* Mux registers */
+ };
+
/*
* There are two serial driver i.e. 8250 based simple serial
* driver and APB DMA based serial driver for higher baudrate
reg = <0x70006000 0x40>;
reg-shift = <2>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
status = "disabled";
};
reg = <0x70006040 0x40>;
reg-shift = <2>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
status = "disabled";
};
reg = <0x70006200 0x40>;
reg-shift = <2>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
status = "disabled";
};
reg = <0x70006300 0x40>;
reg-shift = <2>;
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
status = "disabled";
};
reg = <0x70006400 0x40>;
reg-shift = <2>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_UARTE>;
+ resets = <&tegra_car 66>;
+ reset-names = "serial";
+ dmas = <&apbdma 20>, <&apbdma 20>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm@7000a000 {
+ compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA124_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C1>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 12>;
+ reset-names = "i2c";
+ dmas = <&apbdma 21>, <&apbdma 21>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C2>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 54>;
+ reset-names = "i2c";
+ dmas = <&apbdma 22>, <&apbdma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C3>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 67>;
+ reset-names = "i2c";
+ dmas = <&apbdma 23>, <&apbdma 23>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000c700 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000c700 0x100>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C4>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 103>;
+ reset-names = "i2c";
+ dmas = <&apbdma 26>, <&apbdma 26>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000d000 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C5>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 47>;
+ reset-names = "i2c";
+ dmas = <&apbdma 24>, <&apbdma 24>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ i2c@7000d100 {
+ compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+ reg = <0x7000d100 0x100>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_I2C6>;
+ clock-names = "div-clk";
+ resets = <&tegra_car 166>;
+ reset-names = "i2c";
+ dmas = <&apbdma 30>, <&apbdma 30>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d400 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000d400 0x200>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC1>;
+ clock-names = "spi";
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ dmas = <&apbdma 15>, <&apbdma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d600 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000d600 0x200>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC2>;
+ clock-names = "spi";
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000d800 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000d800 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC3>;
+ clock-names = "spi";
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ dmas = <&apbdma 17>, <&apbdma 17>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000da00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000da00 0x200>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC4>;
+ clock-names = "spi";
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000dc00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000dc00 0x200>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC5>;
+ clock-names = "spi";
+ resets = <&tegra_car 104>;
+ reset-names = "spi";
+ dmas = <&apbdma 27>, <&apbdma 27>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi@7000de00 {
+ compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+ reg = <0x7000de00 0x200>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA124_CLK_SBC6>;
+ clock-names = "spi";
+ resets = <&tegra_car 105>;
+ reset-names = "spi";
+ dmas = <&apbdma 28>, <&apbdma 28>;
+ dma-names = "rx", "tx";
status = "disabled";
};
compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_RTC>;
};
pmc@7000e400 {
compatible = "nvidia,tegra124-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ };
+
+ sdhci@700b0000 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x700b0000 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disable";
+ };
+
+ sdhci@700b0200 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x700b0200 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disable";
+ };
+
+ sdhci@700b0400 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x700b0400 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disable";
+ };
+
+ sdhci@700b0600 {
+ compatible = "nvidia,tegra124-sdhci";
+ reg = <0x700b0600 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disable";
+ };
+
+ ahub@70300000 {
+ compatible = "nvidia,tegra124-ahub";
+ reg = <0x70300000 0x200>,
+ <0x70300800 0x800>,
+ <0x70300200 0x600>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>,
+ <&tegra_car TEGRA124_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 185>, /* amx1 */
+ <&tegra_car 154>, /* adx */
+ <&tegra_car 180>, /* adx1 */
+ <&tegra_car 186>, /* afc0 */
+ <&tegra_car 187>, /* afc1 */
+ <&tegra_car 188>, /* afc2 */
+ <&tegra_car 189>, /* afc3 */
+ <&tegra_car 190>, /* afc4 */
+ <&tegra_car 191>; /* afc5 */
+ reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+ "i2s3", "i2s4", "dam0", "dam1", "dam2",
+ "spdif", "amx", "amx1", "adx", "adx1",
+ "afc0", "afc1", "afc2", "afc3", "afc4", "afc5";
+ 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>;
+
+ tegra_i2s0: i2s@70301000 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x70301000 0x100>;
+ nvidia,ahub-cif-ids = <4 4>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s1: i2s@70301100 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x70301100 0x100>;
+ nvidia,ahub-cif-ids = <5 5>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@70301200 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x70301200 0x100>;
+ nvidia,ahub-cif-ids = <6 6>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s3: i2s@70301300 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x70301300 0x100>;
+ nvidia,ahub-cif-ids = <7 7>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
+
+ tegra_i2s4: i2s@70301400 {
+ compatible = "nvidia,tegra124-i2s";
+ reg = <0x70301400 0x100>;
+ nvidia,ahub-cif-ids = <8 8>;
+ clocks = <&tegra_car TEGRA124_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
+ status = "disabled";
+ };
};
cpus {
model = "Toradex Colibri T20 512MB";
compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x20000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
vdd-supply = <&hdmi_vdd_reg>;
pll-supply = <&hdmi_pll_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
audio_refclk {
nvidia,pins = "cdev1";
nvidia,function = "plla_out";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
crt {
nvidia,pins = "crtp";
nvidia,function = "crt";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
dap3 {
nvidia,pins = "dap3";
nvidia,function = "dap3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
displaya {
nvidia,pins = "ld0", "ld1", "ld2", "ld3",
"lhs", "lpw0", "lpw2", "lsc0",
"lsc1", "lsck", "lsda", "lspi", "lvs";
nvidia,function = "displaya";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
gpio_dte {
nvidia,pins = "dte";
nvidia,function = "rsvd1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
gpio_gmi {
nvidia,pins = "ata", "atc", "atd", "ate",
"dap1", "dap2", "dap4", "gpu", "irrx",
"irtx", "spia", "spib", "spic";
nvidia,function = "gmi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
gpio_pta {
nvidia,pins = "pta";
nvidia,function = "rsvd4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
gpio_uac {
nvidia,pins = "uac";
nvidia,function = "rsvd2";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
hdint {
nvidia,pins = "hdint";
nvidia,function = "hdmi";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
i2c1 {
nvidia,pins = "rm";
nvidia,function = "i2c1";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
i2c3 {
nvidia,pins = "dtf";
nvidia,function = "i2c3";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
i2cddc {
nvidia,pins = "ddc";
nvidia,function = "i2c2";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
i2cp {
nvidia,pins = "i2cp";
nvidia,function = "i2cp";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
irda {
nvidia,pins = "uad";
nvidia,function = "irda";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
nand {
nvidia,pins = "kbca", "kbcc", "kbcd",
"kbce", "kbcf";
nvidia,function = "nand";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
owc {
nvidia,pins = "owc";
nvidia,function = "owr";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
pmc {
nvidia,pins = "pmc";
nvidia,function = "pwr_on";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
pwm {
nvidia,pins = "sdb", "sdc", "sdd";
nvidia,function = "pwm";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
sdio4 {
nvidia,pins = "atb", "gma", "gme";
nvidia,function = "sdio4";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
spi1 {
nvidia,pins = "spid", "spie", "spif";
nvidia,function = "spi1";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
spi4 {
nvidia,pins = "slxa", "slxc", "slxd", "slxk";
nvidia,function = "spi4";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
uarta {
nvidia,pins = "sdio1";
nvidia,function = "uarta";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
uartd {
nvidia,pins = "gmc";
nvidia,function = "uartd";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
ulpi {
nvidia,pins = "uaa", "uab", "uda";
nvidia,function = "ulpi";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
ulpi_refclk {
nvidia,pins = "cdev2";
nvidia,function = "pllp_out4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
usb_gpio {
nvidia,pins = "spig", "spih";
nvidia,function = "spi2_alt";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
vi {
nvidia,pins = "dta", "dtb", "dtc", "dtd";
nvidia,function = "vi";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
vi_sc {
nvidia,pins = "csus";
nvidia,function = "vi_sensor_clk";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
};
};
+ ac97: ac97@70002000 {
+ status = "okay";
+ nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+ GPIO_ACTIVE_HIGH>;
+ nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
+ GPIO_ACTIVE_HIGH>;
+ };
+
i2c@7000c000 {
clock-frequency = <400000>;
};
#gpio-cells = <2>;
gpio-controller;
- sys-supply = <&vdd_5v0_reg>;
+ sys-supply = <&vdd_3v3_reg>;
vin-sm0-supply = <&sys_reg>;
vin-sm1-supply = <&sys_reg>;
vin-sm2-supply = <&sys_reg>;
vinldo01-supply = <&sm2_reg>;
- vinldo23-supply = <&sm2_reg>;
- vinldo4-supply = <&sm2_reg>;
- vinldo678-supply = <&sm2_reg>;
- vinldo9-supply = <&sm2_reg>;
+ vinldo23-supply = <&vdd_3v3_reg>;
+ vinldo4-supply = <&vdd_3v3_reg>;
+ vinldo678-supply = <&vdd_3v3_reg>;
+ vinldo9-supply = <&vdd_3v3_reg>;
regulators {
#address-cells = <1>;
reg = <1>;
regulator-compatible = "sm0";
regulator-name = "vdd_sm0,vdd_core";
- regulator-min-microvolt = <1275000>;
- regulator-max-microvolt = <1275000>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
regulator-always-on;
};
reg = <2>;
regulator-compatible = "sm1";
regulator-name = "vdd_sm1,vdd_cpu";
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1100000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
regulator-always-on;
};
reg = <10>;
regulator-compatible = "ldo6";
regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
};
hdmi_vdd_reg: regulator@11 {
};
};
- pmc {
+ pmc@7000e400 {
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <5000>;
nvidia,cpu-pwr-off-time = <5000>;
};
};
- ac97: ac97 {
- status = "okay";
- nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
- GPIO_ACTIVE_HIGH>;
- nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
- GPIO_ACTIVE_HIGH>;
- };
-
usb@c5004000 {
status = "okay";
nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
};
};
- sound {
- compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
- "nvidia,tegra-audio-wm9712";
- nvidia,model = "Colibri T20 AC97 Audio";
-
- nvidia,audio-routing =
- "Headphone", "HPOUTL",
- "Headphone", "HPOUTR",
- "LineIn", "LINEINL",
- "LineIn", "LINEINR",
- "Mic", "MIC1";
-
- nvidia,ac97-controller = <&ac97>;
-
- clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
- <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
- <&tegra_car TEGRA20_CLK_CDEV1>;
- clock-names = "pll_a", "pll_a_out0", "mclk";
- };
-
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
- vdd_5v0_reg: regulator@100 {
+ vdd_3v3_reg: regulator@100 {
compatible = "regulator-fixed";
reg = <100>;
- regulator-name = "vdd_5v0";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
+ regulator-name = "vdd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
regulator-always-on;
};
gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
};
};
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
+ "nvidia,tegra-audio-wm9712";
+ nvidia,model = "Colibri T20 AC97 Audio";
+
+ nvidia,audio-routing =
+ "Headphone", "HPOUTL",
+ "Headphone", "HPOUTR",
+ "LineIn", "LINEINL",
+ "LineIn", "LINEINR",
+ "Mic", "MIC1";
+
+ nvidia,ac97-controller = <&ac97>;
+
+ clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+ <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA20_CLK_CDEV1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "NVIDIA Tegra20 Harmony evaluation board";
compatible = "nvidia,harmony", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x40000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"gmb", "gmc", "gmd", "gme", "gpu7",
"gpv", "i2cp", "pta", "rm", "slxa",
"slxk", "spia", "spib", "uac";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_csus {
nvidia,pins = "csus", "spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_crtp {
nvidia,pins = "crtp", "dap2", "dap3", "dap4",
"dtc", "dte", "dtf", "gpu", "sdio1",
"slxc", "slxd", "spdi", "spdo", "spig",
"uda";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ddc {
nvidia,pins = "ddc", "dta", "dtd", "kbca",
"kbcb", "kbcc", "kbcd", "kbce", "kbcf",
"sdc";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
"lpw1", "lsc1", "lsck", "lsda", "lsdi",
"lvp0", "owc", "sdb";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_irrx {
nvidia,pins = "irrx", "irtx", "sdd", "spic",
"spie", "spih", "uaa", "uab", "uad",
"uca", "ucb";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
"lhp1", "lhp2", "lhs", "lm0", "lpp",
"lpw0", "lpw2", "lsc0", "lspi", "lvp1",
"lvs", "pmc";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
};
};
status = "okay";
};
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
i2c@7000c000 {
status = "okay";
clock-frequency = <400000>;
};
};
- pmc {
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <2>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
+ linux,keymap = <MATRIX_KEY(0x00, 0x02, KEY_W)
+ MATRIX_KEY(0x00, 0x03, KEY_S)
+ MATRIX_KEY(0x00, 0x04, KEY_A)
+ MATRIX_KEY(0x00, 0x05, KEY_Z)
+ MATRIX_KEY(0x00, 0x07, KEY_FN)
+ MATRIX_KEY(0x01, 0x07, KEY_MENU)
+ MATRIX_KEY(0x02, 0x06, KEY_LEFTALT)
+ MATRIX_KEY(0x02, 0x07, KEY_RIGHTALT)
+ MATRIX_KEY(0x03, 0x00, KEY_5)
+ MATRIX_KEY(0x03, 0x01, KEY_4)
+ MATRIX_KEY(0x03, 0x02, KEY_R)
+ MATRIX_KEY(0x03, 0x03, KEY_E)
+ MATRIX_KEY(0x03, 0x04, KEY_F)
+ MATRIX_KEY(0x03, 0x05, KEY_D)
+ MATRIX_KEY(0x03, 0x06, KEY_X)
+ MATRIX_KEY(0x04, 0x00, KEY_7)
+ MATRIX_KEY(0x04, 0x01, KEY_6)
+ MATRIX_KEY(0x04, 0x02, KEY_T)
+ MATRIX_KEY(0x04, 0x03, KEY_H)
+ MATRIX_KEY(0x04, 0x04, KEY_G)
+ MATRIX_KEY(0x04, 0x05, KEY_V)
+ MATRIX_KEY(0x04, 0x06, KEY_C)
+ MATRIX_KEY(0x04, 0x07, KEY_SPACE)
+ MATRIX_KEY(0x05, 0x00, KEY_9)
+ MATRIX_KEY(0x05, 0x01, KEY_8)
+ MATRIX_KEY(0x05, 0x02, KEY_U)
+ MATRIX_KEY(0x05, 0x03, KEY_Y)
+ MATRIX_KEY(0x05, 0x04, KEY_J)
+ MATRIX_KEY(0x05, 0x05, KEY_N)
+ MATRIX_KEY(0x05, 0x06, KEY_B)
+ MATRIX_KEY(0x05, 0x07, KEY_BACKSLASH)
+ MATRIX_KEY(0x06, 0x00, KEY_MINUS)
+ MATRIX_KEY(0x06, 0x01, KEY_0)
+ MATRIX_KEY(0x06, 0x02, KEY_O)
+ MATRIX_KEY(0x06, 0x03, KEY_I)
+ MATRIX_KEY(0x06, 0x04, KEY_L)
+ MATRIX_KEY(0x06, 0x05, KEY_K)
+ MATRIX_KEY(0x06, 0x06, KEY_COMMA)
+ MATRIX_KEY(0x06, 0x07, KEY_M)
+ MATRIX_KEY(0x07, 0x01, KEY_EQUAL)
+ MATRIX_KEY(0x07, 0x02, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x07, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x07, 0x07, KEY_MENU)
+ MATRIX_KEY(0x08, 0x04, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x08, 0x05, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x09, 0x05, KEY_LEFTCTRL)
+ MATRIX_KEY(0x09, 0x07, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x0B, 0x00, KEY_LEFTBRACE)
+ MATRIX_KEY(0x0B, 0x01, KEY_P)
+ MATRIX_KEY(0x0B, 0x02, KEY_APOSTROPHE)
+ MATRIX_KEY(0x0B, 0x03, KEY_SEMICOLON)
+ MATRIX_KEY(0x0B, 0x04, KEY_SLASH)
+ MATRIX_KEY(0x0B, 0x05, KEY_DOT)
+ MATRIX_KEY(0x0C, 0x00, KEY_F10)
+ MATRIX_KEY(0x0C, 0x01, KEY_F9)
+ MATRIX_KEY(0x0C, 0x02, KEY_BACKSPACE)
+ MATRIX_KEY(0x0C, 0x03, KEY_3)
+ MATRIX_KEY(0x0C, 0x04, KEY_2)
+ MATRIX_KEY(0x0C, 0x05, KEY_UP)
+ MATRIX_KEY(0x0C, 0x06, KEY_PRINT)
+ MATRIX_KEY(0x0C, 0x07, KEY_PAUSE)
+ MATRIX_KEY(0x0D, 0x00, KEY_INSERT)
+ MATRIX_KEY(0x0D, 0x01, KEY_DELETE)
+ MATRIX_KEY(0x0D, 0x03, KEY_PAGEUP )
+ MATRIX_KEY(0x0D, 0x04, KEY_PAGEDOWN)
+ MATRIX_KEY(0x0D, 0x05, KEY_RIGHT)
+ MATRIX_KEY(0x0D, 0x06, KEY_DOWN)
+ MATRIX_KEY(0x0D, 0x07, KEY_LEFT)
+ MATRIX_KEY(0x0E, 0x00, KEY_F11)
+ MATRIX_KEY(0x0E, 0x01, KEY_F12)
+ MATRIX_KEY(0x0E, 0x02, KEY_F8)
+ MATRIX_KEY(0x0E, 0x03, KEY_Q)
+ MATRIX_KEY(0x0E, 0x04, KEY_F4)
+ MATRIX_KEY(0x0E, 0x05, KEY_F3)
+ MATRIX_KEY(0x0E, 0x06, KEY_1)
+ MATRIX_KEY(0x0E, 0x07, KEY_F7)
+ MATRIX_KEY(0x0F, 0x00, KEY_ESC)
+ MATRIX_KEY(0x0F, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x0F, 0x02, KEY_F5)
+ MATRIX_KEY(0x0F, 0x03, KEY_TAB)
+ MATRIX_KEY(0x0F, 0x04, KEY_F1)
+ MATRIX_KEY(0x0F, 0x05, KEY_F2)
+ MATRIX_KEY(0x0F, 0x06, KEY_CAPSLOCK)
+ MATRIX_KEY(0x0F, 0x07, KEY_F6)
+ MATRIX_KEY(0x14, 0x00, KEY_KP7)
+ MATRIX_KEY(0x15, 0x00, KEY_KP9)
+ MATRIX_KEY(0x15, 0x01, KEY_KP8)
+ MATRIX_KEY(0x15, 0x02, KEY_KP4)
+ MATRIX_KEY(0x15, 0x04, KEY_KP1)
+ MATRIX_KEY(0x16, 0x01, KEY_KPSLASH)
+ MATRIX_KEY(0x16, 0x02, KEY_KP6)
+ MATRIX_KEY(0x16, 0x03, KEY_KP5)
+ MATRIX_KEY(0x16, 0x04, KEY_KP3)
+ MATRIX_KEY(0x16, 0x05, KEY_KP2)
+ MATRIX_KEY(0x16, 0x07, KEY_KP0)
+ MATRIX_KEY(0x1B, 0x01, KEY_KPASTERISK)
+ MATRIX_KEY(0x1B, 0x03, KEY_KPMINUS)
+ MATRIX_KEY(0x1B, 0x04, KEY_KPPLUS)
+ MATRIX_KEY(0x1B, 0x05, KEY_KPDOT)
+ MATRIX_KEY(0x1C, 0x05, KEY_VOLUMEUP)
+ MATRIX_KEY(0x1D, 0x03, KEY_HOME)
+ MATRIX_KEY(0x1D, 0x04, KEY_END)
+ MATRIX_KEY(0x1D, 0x05, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x1D, 0x06, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x1D, 0x07, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x1E, 0x00, KEY_NUMLOCK)
+ MATRIX_KEY(0x1E, 0x01, KEY_SCROLLLOCK)
+ MATRIX_KEY(0x1E, 0x02, KEY_MUTE)
+ MATRIX_KEY(0x1F, 0x04, KEY_QUESTION)>;
+ };
+
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <5000>;
nvidia,sys-clock-req-active-high;
};
- pcie-controller {
+ pcie-controller@80003000 {
pex-clk-supply = <&pci_clk_reg>;
vdd-supply = <&pci_vdd_reg>;
status = "okay";
bus-width = <8>;
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
- linux,code = <116>; /* KEY_POWER */
+ linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
};
- kbc {
- status = "okay";
- nvidia,debounce-delay-ms = <2>;
- nvidia,repeat-delay-ms = <160>;
- nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
- nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
- linux,keymap = <0x00020011 /* KEY_W */
- 0x0003001F /* KEY_S */
- 0x0004001E /* KEY_A */
- 0x0005002C /* KEY_Z */
- 0x000701D0 /* KEY_FN */
- 0x0107008B /* KEY_MENU */
- 0x02060038 /* KEY_LEFTALT */
- 0x02070064 /* KEY_RIGHTALT */
- 0x03000006 /* KEY_5 */
- 0x03010005 /* KEY_4 */
- 0x03020013 /* KEY_R */
- 0x03030012 /* KEY_E */
- 0x03040021 /* KEY_F */
- 0x03050020 /* KEY_D */
- 0x0306002D /* KEY_X */
- 0x04000008 /* KEY_7 */
- 0x04010007 /* KEY_6 */
- 0x04020014 /* KEY_T */
- 0x04030023 /* KEY_H */
- 0x04040022 /* KEY_G */
- 0x0405002F /* KEY_V */
- 0x0406002E /* KEY_C */
- 0x04070039 /* KEY_SPACE */
- 0x0500000A /* KEY_9 */
- 0x05010009 /* KEY_8 */
- 0x05020016 /* KEY_U */
- 0x05030015 /* KEY_Y */
- 0x05040024 /* KEY_J */
- 0x05050031 /* KEY_N */
- 0x05060030 /* KEY_B */
- 0x0507002B /* KEY_BACKSLASH */
- 0x0600000C /* KEY_MINUS */
- 0x0601000B /* KEY_0 */
- 0x06020018 /* KEY_O */
- 0x06030017 /* KEY_I */
- 0x06040026 /* KEY_L */
- 0x06050025 /* KEY_K */
- 0x06060033 /* KEY_COMMA */
- 0x06070032 /* KEY_M */
- 0x0701000D /* KEY_EQUAL */
- 0x0702001B /* KEY_RIGHTBRACE */
- 0x0703001C /* KEY_ENTER */
- 0x0707008B /* KEY_MENU */
- 0x0804002A /* KEY_LEFTSHIFT */
- 0x08050036 /* KEY_RIGHTSHIFT */
- 0x0905001D /* KEY_LEFTCTRL */
- 0x09070061 /* KEY_RIGHTCTRL */
- 0x0B00001A /* KEY_LEFTBRACE */
- 0x0B010019 /* KEY_P */
- 0x0B020028 /* KEY_APOSTROPHE */
- 0x0B030027 /* KEY_SEMICOLON */
- 0x0B040035 /* KEY_SLASH */
- 0x0B050034 /* KEY_DOT */
- 0x0C000044 /* KEY_F10 */
- 0x0C010043 /* KEY_F9 */
- 0x0C02000E /* KEY_BACKSPACE */
- 0x0C030004 /* KEY_3 */
- 0x0C040003 /* KEY_2 */
- 0x0C050067 /* KEY_UP */
- 0x0C0600D2 /* KEY_PRINT */
- 0x0C070077 /* KEY_PAUSE */
- 0x0D00006E /* KEY_INSERT */
- 0x0D01006F /* KEY_DELETE */
- 0x0D030068 /* KEY_PAGEUP */
- 0x0D04006D /* KEY_PAGEDOWN */
- 0x0D05006A /* KEY_RIGHT */
- 0x0D06006C /* KEY_DOWN */
- 0x0D070069 /* KEY_LEFT */
- 0x0E000057 /* KEY_F11 */
- 0x0E010058 /* KEY_F12 */
- 0x0E020042 /* KEY_F8 */
- 0x0E030010 /* KEY_Q */
- 0x0E04003E /* KEY_F4 */
- 0x0E05003D /* KEY_F3 */
- 0x0E060002 /* KEY_1 */
- 0x0E070041 /* KEY_F7 */
- 0x0F000001 /* KEY_ESC */
- 0x0F010029 /* KEY_GRAVE */
- 0x0F02003F /* KEY_F5 */
- 0x0F03000F /* KEY_TAB */
- 0x0F04003B /* KEY_F1 */
- 0x0F05003C /* KEY_F2 */
- 0x0F06003A /* KEY_CAPSLOCK */
- 0x0F070040 /* KEY_F6 */
- 0x14000047 /* KEY_KP7 */
- 0x15000049 /* KEY_KP9 */
- 0x15010048 /* KEY_KP8 */
- 0x1502004B /* KEY_KP4 */
- 0x1504004F /* KEY_KP1 */
- 0x1601004E /* KEY_KPSLASH */
- 0x1602004D /* KEY_KP6 */
- 0x1603004C /* KEY_KP5 */
- 0x16040051 /* KEY_KP3 */
- 0x16050050 /* KEY_KP2 */
- 0x16070052 /* KEY_KP0 */
- 0x1B010037 /* KEY_KPASTERISK */
- 0x1B03004A /* KEY_KPMINUS */
- 0x1B04004E /* KEY_KPPLUS */
- 0x1B050053 /* KEY_KPDOT */
- 0x1C050073 /* KEY_VOLUMEUP */
- 0x1D030066 /* KEY_HOME */
- 0x1D04006B /* KEY_END */
- 0x1D0500E1 /* KEY_BRIGHTNESSUP */
- 0x1D060072 /* KEY_VOLUMEDOWN */
- 0x1D0700E0 /* KEY_BRIGHTNESSDOWN */
- 0x1E000045 /* KEY_NUMLOCK */
- 0x1E010046 /* KEY_SCROLLLOCK */
- 0x1E020071 /* KEY_MUTE */
- 0x1F0400D6>; /* KEY_QUESTION */
+ panel: panel {
+ compatible = "auo,b101aw03", "simple-panel";
+
+ power-supply = <&vdd_pnl_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
};
regulators {
enable-active-high;
};
- regulator@4 {
+ vdd_pnl_reg: regulator@4 {
compatible = "regulator-fixed";
reg = <4>;
regulator-name = "vdd_pnl";
enable-active-high;
};
- regulator@5 {
+ vdd_bl_reg: regulator@5 {
compatible = "regulator-fixed";
reg = <5>;
regulator-name = "vdd_bl";
model = "Toradex Colibri T20 512MB on Iris";
compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
};
};
- pinmux {
+ pinmux@70000014 {
state_default: pinmux {
hdint {
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
i2cddc {
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdio4 {
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
uarta {
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
uartd {
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
};
};
- usb@c5000000 {
+ serial@70006000 {
status = "okay";
};
- usb-phy@c5000000 {
+ serial@70006300 {
status = "okay";
};
- usb@c5008000 {
+ i2c_ddc: i2c@7000c400 {
status = "okay";
};
- usb-phy@c5008000 {
+ usb@c5000000 {
status = "okay";
};
- serial@70006000 {
+ usb-phy@c5000000 {
status = "okay";
};
- serial@70006300 {
+ usb@c5008000 {
status = "okay";
};
- i2c_ddc: i2c@7000c400 {
+ usb-phy@c5008000 {
status = "okay";
};
model = "Avionic Design Medcom-Wide board";
compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20";
- pwm {
+ pwm@7000a000 {
status = "okay";
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "Toshiba AC100 / Dynabook AZ";
compatible = "compal,paz00", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x20000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"gpu", "gpu7", "gpv", "i2cp", "pta",
"rm", "sdio1", "slxk", "spdo", "uac",
"uda";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_crtp {
nvidia,pins = "crtp", "dap3", "dap4", "dtb",
"dtc", "dte", "slxa", "slxc", "slxd",
"spdi";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_csus {
nvidia,pins = "csus", "spia", "spib", "spid",
"spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ddc {
nvidia,pins = "ddc", "irrx", "irtx", "kbca",
"kbcb", "kbcc", "kbcd", "kbce", "kbcf",
"spic", "spig", "uaa", "uab";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_dta {
nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd",
"spie", "spih", "uad", "uca", "ucb";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "ld0", "ld1", "ld2",
"ld13", "ld14", "ld15", "ld16", "ld17",
"ldc", "ldi", "lhs", "lsc0", "lspi",
"lvs", "pmc";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_lcsn {
nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2",
"lm0", "lm1", "lpp", "lpw0", "lpw1",
"lpw2", "lsc1", "lsck", "lsda", "lsdi",
"lvp0", "lvp1", "sdb";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
};
};
clock-frequency = <100000>;
};
- nvec {
+ nvec@7000c500 {
compatible = "nvidia,nvec";
reg = <0x7000c500 0x100>;
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
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 {
};
};
- pmc {
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <2000>;
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_LOW>;
- linux,code = <116>; /* KEY_POWER */
+ linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
};
model = "Avionic Design Plutux board";
compatible = "ad,plutux", "ad,tamonten", "nvidia,tegra20";
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
};
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "NVIDIA Seaboard";
compatible = "nvidia,seaboard", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x40000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"irtx", "pta", "rm", "sdc", "sdd",
"slxd", "slxk", "spdi", "spdo", "uac",
"uad", "uca", "ucb", "uda";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ate {
nvidia,pins = "ate", "csus", "dap3",
"gpv", "owc", "slxc", "spib", "spid",
"spie";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_crtp {
nvidia,pins = "crtp", "gmb", "slxa", "spia",
"spig", "spih";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_dta {
nvidia,pins = "dta", "dtb", "dtc", "dtd";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_dte {
nvidia,pins = "dte", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
"lpw1", "lsc1", "lsck", "lsda", "lsdi",
"lvp0";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_kbca {
nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
"kbce", "kbcf", "sdio1", "spic", "uaa",
"uab";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
"lhp1", "lhp2", "lhs", "lm0", "lpp",
"lpw0", "lpw2", "lsc0", "lspi", "lvp1",
"lvs", "pmc", "sdb";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
drive_sdio1 {
nvidia,pins = "drive_sdio1";
- nvidia,high-speed-mode = <0>;
- nvidia,schmitt = <0>;
- nvidia,low-power-mode = <3>;
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
nvidia,pull-down-strength = <31>;
nvidia,pull-up-strength = <31>;
- nvidia,slew-rate-rising = <3>;
- nvidia,slew-rate-falling = <3>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
};
};
status = "okay";
clock-frequency = <400000>;
+ magnetometer@c {
+ compatible = "ak,ak8975";
+ reg = <0xc>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(N, 5) IRQ_TYPE_LEVEL_HIGH>;
+ };
+
pmic: tps6586x@34 {
compatible = "ti,tps6586x";
reg = <0x34>;
compatible = "onnn,nct1008";
reg = <0x4c>;
};
+ };
- magnetometer@c {
- compatible = "ak,ak8975";
- reg = <0xc>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(N, 5) IRQ_TYPE_LEVEL_HIGH>;
- };
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <32>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,ghost-filter;
+ nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
+ linux,keymap = <MATRIX_KEY(0x00, 0x02, KEY_W)
+ MATRIX_KEY(0x00, 0x03, KEY_S)
+ MATRIX_KEY(0x00, 0x04, KEY_A)
+ MATRIX_KEY(0x00, 0x05, KEY_Z)
+ MATRIX_KEY(0x00, 0x07, KEY_FN)
+
+ MATRIX_KEY(0x01, 0x07, KEY_LEFTMETA)
+ MATRIX_KEY(0x02, 0x06, KEY_RIGHTALT)
+ MATRIX_KEY(0x02, 0x07, KEY_LEFTALT)
+
+ MATRIX_KEY(0x03, 0x00, KEY_5)
+ MATRIX_KEY(0x03, 0x01, KEY_4)
+ MATRIX_KEY(0x03, 0x02, KEY_R)
+ MATRIX_KEY(0x03, 0x03, KEY_E)
+ MATRIX_KEY(0x03, 0x04, KEY_F)
+ MATRIX_KEY(0x03, 0x05, KEY_D)
+ MATRIX_KEY(0x03, 0x06, KEY_X)
+
+ MATRIX_KEY(0x04, 0x00, KEY_7)
+ MATRIX_KEY(0x04, 0x01, KEY_6)
+ MATRIX_KEY(0x04, 0x02, KEY_T)
+ MATRIX_KEY(0x04, 0x03, KEY_H)
+ MATRIX_KEY(0x04, 0x04, KEY_G)
+ MATRIX_KEY(0x04, 0x05, KEY_V)
+ MATRIX_KEY(0x04, 0x06, KEY_C)
+ MATRIX_KEY(0x04, 0x07, KEY_SPACE)
+
+ MATRIX_KEY(0x05, 0x00, KEY_9)
+ MATRIX_KEY(0x05, 0x01, KEY_8)
+ MATRIX_KEY(0x05, 0x02, KEY_U)
+ MATRIX_KEY(0x05, 0x03, KEY_Y)
+ MATRIX_KEY(0x05, 0x04, KEY_J)
+ MATRIX_KEY(0x05, 0x05, KEY_N)
+ MATRIX_KEY(0x05, 0x06, KEY_B)
+ MATRIX_KEY(0x05, 0x07, KEY_BACKSLASH)
+
+ MATRIX_KEY(0x06, 0x00, KEY_MINUS)
+ MATRIX_KEY(0x06, 0x01, KEY_0)
+ MATRIX_KEY(0x06, 0x02, KEY_O)
+ MATRIX_KEY(0x06, 0x03, KEY_I)
+ MATRIX_KEY(0x06, 0x04, KEY_L)
+ MATRIX_KEY(0x06, 0x05, KEY_K)
+ MATRIX_KEY(0x06, 0x06, KEY_COMMA)
+ MATRIX_KEY(0x06, 0x07, KEY_M)
+
+ MATRIX_KEY(0x07, 0x01, KEY_EQUAL)
+ MATRIX_KEY(0x07, 0x02, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x07, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x07, 0x07, KEY_MENU)
+
+ MATRIX_KEY(0x08, 0x04, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x08, 0x05, KEY_LEFTSHIFT)
+
+ MATRIX_KEY(0x09, 0x05, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x09, 0x07, KEY_LEFTCTRL)
+
+ MATRIX_KEY(0x0B, 0x00, KEY_LEFTBRACE)
+ MATRIX_KEY(0x0B, 0x01, KEY_P)
+ MATRIX_KEY(0x0B, 0x02, KEY_APOSTROPHE)
+ MATRIX_KEY(0x0B, 0x03, KEY_SEMICOLON)
+ MATRIX_KEY(0x0B, 0x04, KEY_SLASH)
+ MATRIX_KEY(0x0B, 0x05, KEY_DOT)
+
+ MATRIX_KEY(0x0C, 0x00, KEY_F10)
+ MATRIX_KEY(0x0C, 0x01, KEY_F9)
+ MATRIX_KEY(0x0C, 0x02, KEY_BACKSPACE)
+ MATRIX_KEY(0x0C, 0x03, KEY_3)
+ MATRIX_KEY(0x0C, 0x04, KEY_2)
+ MATRIX_KEY(0x0C, 0x05, KEY_UP)
+ MATRIX_KEY(0x0C, 0x06, KEY_PRINT)
+ MATRIX_KEY(0x0C, 0x07, KEY_PAUSE)
+
+ MATRIX_KEY(0x0D, 0x00, KEY_INSERT)
+ MATRIX_KEY(0x0D, 0x01, KEY_DELETE)
+ MATRIX_KEY(0x0D, 0x03, KEY_PAGEUP )
+ MATRIX_KEY(0x0D, 0x04, KEY_PAGEDOWN)
+ MATRIX_KEY(0x0D, 0x05, KEY_RIGHT)
+ MATRIX_KEY(0x0D, 0x06, KEY_DOWN)
+ MATRIX_KEY(0x0D, 0x07, KEY_LEFT)
+
+ MATRIX_KEY(0x0E, 0x00, KEY_F11)
+ MATRIX_KEY(0x0E, 0x01, KEY_F12)
+ MATRIX_KEY(0x0E, 0x02, KEY_F8)
+ MATRIX_KEY(0x0E, 0x03, KEY_Q)
+ MATRIX_KEY(0x0E, 0x04, KEY_F4)
+ MATRIX_KEY(0x0E, 0x05, KEY_F3)
+ MATRIX_KEY(0x0E, 0x06, KEY_1)
+ MATRIX_KEY(0x0E, 0x07, KEY_F7)
+
+ MATRIX_KEY(0x0F, 0x00, KEY_ESC)
+ MATRIX_KEY(0x0F, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x0F, 0x02, KEY_F5)
+ MATRIX_KEY(0x0F, 0x03, KEY_TAB)
+ MATRIX_KEY(0x0F, 0x04, KEY_F1)
+ MATRIX_KEY(0x0F, 0x05, KEY_F2)
+ MATRIX_KEY(0x0F, 0x06, KEY_CAPSLOCK)
+ MATRIX_KEY(0x0F, 0x07, KEY_F6)
+
+ /* Software Handled Function Keys */
+ MATRIX_KEY(0x14, 0x00, KEY_KP7)
+
+ MATRIX_KEY(0x15, 0x00, KEY_KP9)
+ MATRIX_KEY(0x15, 0x01, KEY_KP8)
+ MATRIX_KEY(0x15, 0x02, KEY_KP4)
+ MATRIX_KEY(0x15, 0x04, KEY_KP1)
+
+ MATRIX_KEY(0x16, 0x01, KEY_KPSLASH)
+ MATRIX_KEY(0x16, 0x02, KEY_KP6)
+ MATRIX_KEY(0x16, 0x03, KEY_KP5)
+ MATRIX_KEY(0x16, 0x04, KEY_KP3)
+ MATRIX_KEY(0x16, 0x05, KEY_KP2)
+ MATRIX_KEY(0x16, 0x07, KEY_KP0)
+
+ MATRIX_KEY(0x1B, 0x01, KEY_KPASTERISK)
+ MATRIX_KEY(0x1B, 0x03, KEY_KPMINUS)
+ MATRIX_KEY(0x1B, 0x04, KEY_KPPLUS)
+ MATRIX_KEY(0x1B, 0x05, KEY_KPDOT)
+
+ MATRIX_KEY(0x1C, 0x05, KEY_VOLUMEUP)
+
+ MATRIX_KEY(0x1D, 0x03, KEY_HOME)
+ MATRIX_KEY(0x1D, 0x04, KEY_END)
+ MATRIX_KEY(0x1D, 0x05, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x1D, 0x06, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x1D, 0x07, KEY_BRIGHTNESSUP)
+
+ MATRIX_KEY(0x1E, 0x00, KEY_NUMLOCK)
+ MATRIX_KEY(0x1E, 0x01, KEY_SCROLLLOCK)
+ MATRIX_KEY(0x1E, 0x02, KEY_MUTE)
+
+ MATRIX_KEY(0x1F, 0x04, KEY_HELP)>;
};
- pmc {
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <5000>;
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
- linux,code = <116>; /* KEY_POWER */
+ linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
};
};
- kbc {
- status = "okay";
- nvidia,debounce-delay-ms = <32>;
- nvidia,repeat-delay-ms = <160>;
- nvidia,ghost-filter;
- nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
- nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>;
- linux,keymap = <0x00020011 /* KEY_W */
- 0x0003001F /* KEY_S */
- 0x0004001E /* KEY_A */
- 0x0005002C /* KEY_Z */
- 0x000701d0 /* KEY_FN */
-
- 0x0107007D /* KEY_LEFTMETA */
- 0x02060064 /* KEY_RIGHTALT */
- 0x02070038 /* KEY_LEFTALT */
-
- 0x03000006 /* KEY_5 */
- 0x03010005 /* KEY_4 */
- 0x03020013 /* KEY_R */
- 0x03030012 /* KEY_E */
- 0x03040021 /* KEY_F */
- 0x03050020 /* KEY_D */
- 0x0306002D /* KEY_X */
-
- 0x04000008 /* KEY_7 */
- 0x04010007 /* KEY_6 */
- 0x04020014 /* KEY_T */
- 0x04030023 /* KEY_H */
- 0x04040022 /* KEY_G */
- 0x0405002F /* KEY_V */
- 0x0406002E /* KEY_C */
- 0x04070039 /* KEY_SPACE */
-
- 0x0500000A /* KEY_9 */
- 0x05010009 /* KEY_8 */
- 0x05020016 /* KEY_U */
- 0x05030015 /* KEY_Y */
- 0x05040024 /* KEY_J */
- 0x05050031 /* KEY_N */
- 0x05060030 /* KEY_B */
- 0x0507002B /* KEY_BACKSLASH */
-
- 0x0600000C /* KEY_MINUS */
- 0x0601000B /* KEY_0 */
- 0x06020018 /* KEY_O */
- 0x06030017 /* KEY_I */
- 0x06040026 /* KEY_L */
- 0x06050025 /* KEY_K */
- 0x06060033 /* KEY_COMMA */
- 0x06070032 /* KEY_M */
-
- 0x0701000D /* KEY_EQUAL */
- 0x0702001B /* KEY_RIGHTBRACE */
- 0x0703001C /* KEY_ENTER */
- 0x0707008B /* KEY_MENU */
-
- 0x08040036 /* KEY_RIGHTSHIFT */
- 0x0805002A /* KEY_LEFTSHIFT */
-
- 0x09050061 /* KEY_RIGHTCTRL */
- 0x0907001D /* KEY_LEFTCTRL */
-
- 0x0B00001A /* KEY_LEFTBRACE */
- 0x0B010019 /* KEY_P */
- 0x0B020028 /* KEY_APOSTROPHE */
- 0x0B030027 /* KEY_SEMICOLON */
- 0x0B040035 /* KEY_SLASH */
- 0x0B050034 /* KEY_DOT */
-
- 0x0C000044 /* KEY_F10 */
- 0x0C010043 /* KEY_F9 */
- 0x0C02000E /* KEY_BACKSPACE */
- 0x0C030004 /* KEY_3 */
- 0x0C040003 /* KEY_2 */
- 0x0C050067 /* KEY_UP */
- 0x0C0600D2 /* KEY_PRINT */
- 0x0C070077 /* KEY_PAUSE */
-
- 0x0D00006E /* KEY_INSERT */
- 0x0D01006F /* KEY_DELETE */
- 0x0D030068 /* KEY_PAGEUP */
- 0x0D04006D /* KEY_PAGEDOWN */
- 0x0D05006A /* KEY_RIGHT */
- 0x0D06006C /* KEY_DOWN */
- 0x0D070069 /* KEY_LEFT */
-
- 0x0E000057 /* KEY_F11 */
- 0x0E010058 /* KEY_F12 */
- 0x0E020042 /* KEY_F8 */
- 0x0E030010 /* KEY_Q */
- 0x0E04003E /* KEY_F4 */
- 0x0E05003D /* KEY_F3 */
- 0x0E060002 /* KEY_1 */
- 0x0E070041 /* KEY_F7 */
-
- 0x0F000001 /* KEY_ESC */
- 0x0F010029 /* KEY_GRAVE */
- 0x0F02003F /* KEY_F5 */
- 0x0F03000F /* KEY_TAB */
- 0x0F04003B /* KEY_F1 */
- 0x0F05003C /* KEY_F2 */
- 0x0F06003A /* KEY_CAPSLOCK */
- 0x0F070040 /* KEY_F6 */
-
- /* Software Handled Function Keys */
- 0x14000047 /* KEY_KP7 */
-
- 0x15000049 /* KEY_KP9 */
- 0x15010048 /* KEY_KP8 */
- 0x1502004B /* KEY_KP4 */
- 0x1504004F /* KEY_KP1 */
-
- 0x1601004E /* KEY_KPSLASH */
- 0x1602004D /* KEY_KP6 */
- 0x1603004C /* KEY_KP5 */
- 0x16040051 /* KEY_KP3 */
- 0x16050050 /* KEY_KP2 */
- 0x16070052 /* KEY_KP0 */
-
- 0x1B010037 /* KEY_KPASTERISK */
- 0x1B03004A /* KEY_KPMINUS */
- 0x1B04004E /* KEY_KPPLUS */
- 0x1B050053 /* KEY_KPDOT */
-
- 0x1C050073 /* KEY_VOLUMEUP */
-
- 0x1D030066 /* KEY_HOME */
- 0x1D04006B /* KEY_END */
- 0x1D0500E0 /* KEY_BRIGHTNESSDOWN */
- 0x1D060072 /* KEY_VOLUMEDOWN */
- 0x1D0700E1 /* KEY_BRIGHTNESSUP */
-
- 0x1E000045 /* KEY_NUMLOCK */
- 0x1E010046 /* KEY_SCROLLLOCK */
- 0x1E020071 /* KEY_MUTE */
-
- 0x1F04008A>; /* KEY_HELP */
- };
regulators {
compatible = "simple-bus";
#address-cells = <1>;
model = "Avionic Design Tamonten SOM";
compatible = "ad,tamonten", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x20000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
vdd-supply = <&hdmi_vdd_reg>;
pll-supply = <&hdmi_pll_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"gmb", "gmc", "gmd", "gme", "gpu7",
"gpv", "i2cp", "pta", "rm", "slxa",
"slxk", "spia", "spib", "uac";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_csus {
nvidia,pins = "csus", "spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_crtp {
nvidia,pins = "crtp", "dap2", "dap3", "dap4",
"dtc", "dte", "dtf", "gpu", "sdio1",
"slxc", "slxd", "spdi", "spdo", "spig",
"uda";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ddc {
nvidia,pins = "ddc", "dta", "dtd", "kbca",
"kbcb", "kbcc", "kbcd", "kbce", "kbcf",
"sdc";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
"lpw1", "lsc1", "lsck", "lsda", "lsdi",
"lvp0", "owc", "sdb";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_irrx {
nvidia,pins = "irrx", "irtx", "sdd", "spic",
"spie", "spih", "uaa", "uab", "uad",
"uca", "ucb";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
"lhp1", "lhp2", "lhs", "lm0", "lpp",
"lpw0", "lpw2", "lsc0", "lspi", "lvp1",
"lvs", "pmc";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
};
};
};
- pmc {
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <5000>;
nvidia,sys-clock-req-active-high;
};
- pcie-controller {
+ pcie-controller@80003000 {
pex-clk-supply = <&pci_clk_reg>;
vdd-supply = <&pci_vdd_reg>;
};
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
model = "Avionic Design Tamonten Evaluation Carrier";
compatible = "ad,tec", "ad,tamonten", "nvidia,tegra20";
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
};
};
};
};
- pcie-controller {
+ pcie-controller@80003000 {
status = "okay";
pci@1,0 {
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "Compulab TrimSlice board";
compatible = "compulab,trimslice", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000c500/rtc@56";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x40000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"dtb", "dtc", "dtd", "dte", "gmb",
"gme", "i2cp", "pta", "slxc", "slxd",
"spdi", "spdo", "uda";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_atb {
nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
"gma", "gmc", "gmd", "gpu", "gpu7",
"gpv", "sdio1", "slxa", "slxk", "uac";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_csus {
nvidia,pins = "csus", "spia", "spib",
"spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ddc {
nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
"lpw1", "lsc1", "lsck", "lsda", "lsdi",
"lvp0", "pmc";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_irrx {
nvidia,pins = "irrx", "irtx", "kbca", "kbcb",
"kbcc", "kbcd", "kbce", "kbcf", "owc",
"spic", "spie", "spig", "spih", "uaa",
"uab", "uad", "uca", "ucb";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
"lhp1", "lhp2", "lhs", "lm0", "lpp",
"lpw0", "lpw2", "lsc0", "lspi", "lvp1",
"lvs", "sdb";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
conf_spif {
nvidia,pins = "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
};
};
};
};
- pmc {
+ pmc@7000e400 {
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <5000>;
nvidia,cpu-pwr-off-time = <5000>;
nvidia,sys-clock-req-active-high;
};
- pcie-controller {
+ pcie-controller@80003000 {
status = "okay";
pex-clk-supply = <&pci_clk_reg>;
vdd-supply = <&pci_vdd_reg>;
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>;
- linux,code = <116>; /* KEY_POWER */
+ linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "NVIDIA Tegra20 Ventana evaluation board";
compatible = "nvidia,ventana", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x40000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"irtx", "pta", "rm", "sdc", "sdd",
"slxc", "slxd", "slxk", "spdi", "spdo",
"uac", "uad", "uca", "ucb", "uda";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ate {
nvidia,pins = "ate", "csus", "dap3", "gmd",
"gpv", "owc", "spia", "spib", "spic",
"spid", "spie", "spig";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_crtp {
nvidia,pins = "crtp", "gmb", "slxa", "spih";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_dta {
nvidia,pins = "dta", "dtb", "dtc", "dtd";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_dte {
nvidia,pins = "dte", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_hdint {
nvidia,pins = "hdint", "lcsn", "ldc", "lm1",
"lpw1", "lsck", "lsda", "lsdi", "lvp0";
- nvidia,tristate = <1>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_kbca {
nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
"kbce", "kbcf", "sdio1", "uaa", "uab";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_lc {
nvidia,pins = "lc", "ls";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
conf_ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
"lhp1", "lhp2", "lhs", "lm0", "lpp",
"lpw0", "lpw2", "lsc0", "lsc1", "lspi",
"lvp1", "lvs", "pmc", "sdb";
- nvidia,tristate = <0>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
drive_sdio1 {
nvidia,pins = "drive_sdio1";
- nvidia,high-speed-mode = <0>;
- nvidia,schmitt = <1>;
- nvidia,low-power-mode = <3>;
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
nvidia,pull-down-strength = <31>;
nvidia,pull-up-strength = <31>;
- nvidia,slew-rate-rising = <3>;
- nvidia,slew-rate-falling = <3>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
};
};
};
};
- pmc {
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <2000>;
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
- linux,code = <116>; /* KEY_POWER */
+ linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
};
/dts-v1/;
+#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "NVIDIA Tegra20 Whistler evaluation board";
compatible = "nvidia,whistler", "nvidia,tegra20";
+ aliases {
+ rtc0 = "/i2c@7000d000/max8907@3c";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x00000000 0x20000000>;
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&hdmi_vdd_reg>;
};
};
- pinmux {
+ pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
"kbcf", "sdc", "sdd", "spie", "spig",
"spih", "uaa", "uab", "uad", "uca",
"ucb";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_atd {
nvidia,pins = "atd", "ate", "cdev1", "csus",
"dtf", "gpu", "gpu7", "gpv", "i2cp",
"rm", "sdio1", "slxa", "slxc", "slxd",
"slxk", "spdi", "spdo", "uac", "uda";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_cdev2 {
nvidia,pins = "cdev2", "spia", "spib";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "lc", "pmca",
"pmcb", "pmcc", "pmcd", "xm2c",
"xm2d";
- nvidia,pull = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
};
conf_crtp {
nvidia,pins = "crtp";
- nvidia,pull = <0>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_dta {
nvidia,pins = "dta", "dtb", "dtc", "dtd",
"spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf_gme {
nvidia,pins = "gme", "owc", "pta", "spic";
- nvidia,pull = <2>;
- nvidia,tristate = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_ld17_0 {
nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
"ld23_22";
- nvidia,pull = <1>;
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};
conf_ls {
nvidia,pins = "ls", "pmce";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
drive_dap1 {
nvidia,pins = "drive_dap1";
- nvidia,high-speed-mode = <0>;
- nvidia,schmitt = <1>;
- nvidia,low-power-mode = <0>;
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_8>;
nvidia,pull-down-strength = <0>;
nvidia,pull-up-strength = <0>;
- nvidia,slew-rate-rising = <0>;
- nvidia,slew-rate-falling = <0>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
};
};
};
};
};
- pmc {
+ kbc@7000e200 {
+ status = "okay";
+ nvidia,debounce-delay-ms = <20>;
+ nvidia,repeat-delay-ms = <160>;
+ nvidia,kbc-row-pins = <0 1 2>;
+ nvidia,kbc-col-pins = <16 17>;
+ nvidia,wakeup-source;
+ linux,keymap = <MATRIX_KEY(0x00, 0x00, KEY_POWER)
+ MATRIX_KEY(0x01, 0x00, KEY_HOME)
+ MATRIX_KEY(0x01, 0x01, KEY_BACK)
+ MATRIX_KEY(0x02, 0x01, KEY_MENU)>;
+ };
+
+ pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,cpu-pwr-good-time = <2000>;
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
};
};
- kbc {
- status = "okay";
- nvidia,debounce-delay-ms = <20>;
- nvidia,repeat-delay-ms = <160>;
- nvidia,kbc-row-pins = <0 1 2>;
- nvidia,kbc-col-pins = <16 17>;
- nvidia,wakeup-source;
- linux,keymap = <0x00000074 /* KEY_POWER */
- 0x01000066 /* KEY_HOME */
- 0x0101009E /* KEY_BACK */
- 0x0201008B>; /* KEY_MENU */
- };
-
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
- usb0_vbus_reg: regulator {
+ usb0_vbus_reg: regulator@0 {
compatible = "regulator-fixed";
reg = <0>;
regulator-name = "usb0_vbus";
#include <dt-bindings/clock/tegra20-car.h>
#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
serial4 = &uarte;
};
- host1x {
+ host1x@50000000 {
compatible = "nvidia,tegra20-host1x", "simple-bus";
reg = <0x50000000 0x00024000>;
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>;
ranges = <0x54000000 0x54000000 0x04000000>;
- mpe {
+ mpe@54040000 {
compatible = "nvidia,tegra20-mpe";
reg = <0x54040000 0x00040000>;
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_MPE>;
+ resets = <&tegra_car 60>;
+ reset-names = "mpe";
};
- vi {
+ vi@54080000 {
compatible = "nvidia,tegra20-vi";
reg = <0x54080000 0x00040000>;
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_VI>;
+ resets = <&tegra_car 20>;
+ reset-names = "vi";
};
- epp {
+ epp@540c0000 {
compatible = "nvidia,tegra20-epp";
reg = <0x540c0000 0x00040000>;
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_EPP>;
+ resets = <&tegra_car 19>;
+ reset-names = "epp";
};
- isp {
+ isp@54100000 {
compatible = "nvidia,tegra20-isp";
reg = <0x54100000 0x00040000>;
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_ISP>;
+ resets = <&tegra_car 23>;
+ reset-names = "isp";
};
- gr2d {
+ gr2d@54140000 {
compatible = "nvidia,tegra20-gr2d";
reg = <0x54140000 0x00040000>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
+ resets = <&tegra_car 21>;
+ reset-names = "2d";
};
- gr3d {
+ gr3d@54140000 {
compatible = "nvidia,tegra20-gr3d";
- reg = <0x54180000 0x00040000>;
+ reg = <0x54140000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
+ resets = <&tegra_car 24>;
+ reset-names = "3d";
};
dc@54200000 {
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";
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";
};
};
- hdmi {
+ hdmi@54280000 {
compatible = "nvidia,tegra20-hdmi";
reg = <0x54280000 0x00040000>;
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
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";
};
- tvo {
+ tvo@542c0000 {
compatible = "nvidia,tegra20-tvo";
reg = <0x542c0000 0x00040000>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- dsi {
+ dsi@542c0000 {
compatible = "nvidia,tegra20-dsi";
- reg = <0x54300000 0x00040000>;
+ reg = <0x542c0000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_DSI>;
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
status = "disabled";
};
};
clocks = <&tegra_car TEGRA20_CLK_TWD>;
};
- intc: interrupt-controller {
+ intc: interrupt-controller@50041000 {
compatible = "arm,cortex-a9-gic";
reg = <0x50041000 0x1000
0x50040100 0x0100>;
#interrupt-cells = <3>;
};
- cache-controller {
+ cache-controller@50043000 {
compatible = "arm,pl310-cache";
reg = <0x50043000 0x1000>;
arm,data-latency = <5 5 2>;
clocks = <&tegra_car TEGRA20_CLK_TIMER>;
};
- tegra_car: clock {
+ tegra_car: clock@60006000 {
compatible = "nvidia,tegra20-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
- apbdma: dma {
+ apbdma: dma@6000a000 {
compatible = "nvidia,tegra20-apbdma";
reg = <0x6000a000 0x1200>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
<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 {
+ ahb@6000c004 {
compatible = "nvidia,tegra20-ahb";
reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
};
- gpio: gpio {
+ gpio: gpio@6000d000 {
compatible = "nvidia,tegra20-gpio";
reg = <0x6000d000 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
interrupt-controller;
};
- pinmux: pinmux {
+ pinmux: pinmux@70000014 {
compatible = "nvidia,tegra20-pinmux";
reg = <0x70000014 0x10 /* Tri-state registers */
0x70000080 0x20 /* Mux registers */
0x70000868 0xa8>; /* Pad control registers */
};
- das {
+ das@70000c00 {
compatible = "nvidia,tegra20-das";
reg = <0x70000c00 0x80>;
};
- tegra_ac97: ac97 {
+ tegra_ac97: ac97@70002000 {
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
- pwm: pwm {
+ pwm: pwm@7000a000 {
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car TEGRA20_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
status = "disabled";
};
- rtc {
+ rtc@7000e000 {
compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
- kbc {
+ kbc@7000e200 {
compatible = "nvidia,tegra20-kbc";
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";
};
- pmc {
+ pmc@7000e400 {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>;
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
};
- iommu {
+ iommu@7000f024 {
compatible = "nvidia,tegra20-gart";
reg = <0x7000f024 0x00000018 /* controller registers */
0x58000000 0x02000000>; /* GART aperture */
#size-cells = <0>;
};
- pcie-controller {
+ pcie-controller@80003000 {
compatible = "nvidia,tegra20-pcie";
device_type = "pci";
reg = <0x80003000 0x00000800 /* PADS registers */
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 {
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";
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
model = "NVIDIA Tegra30 Beaver evaluation board";
compatible = "nvidia,beaver", "nvidia,tegra30";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps65911@2d";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x80000000 0x7ff00000>;
};
- pcie-controller {
+ pcie-controller@00003000 {
status = "okay";
pex-clk-supply = <&sys_3v3_pexs_reg>;
vdd-supply = <&ldo1_reg>;
};
};
- host1x {
- hdmi {
+ host1x@50000000 {
+ hdmi@54280000 {
status = "okay";
vdd-supply = <&sys_3v3_reg>;
};
};
- pinmux {
+ pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
sdmmc1_clk_pz0 {
nvidia,pins = "sdmmc1_clk_pz0";
nvidia,function = "sdmmc1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc1_cmd_pz1 {
nvidia,pins = "sdmmc1_cmd_pz1",
"sdmmc1_dat2_py5",
"sdmmc1_dat3_py4";
nvidia,function = "sdmmc1";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc3_clk_pa6 {
nvidia,pins = "sdmmc3_clk_pa6";
nvidia,function = "sdmmc3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc3_cmd_pa7 {
nvidia,pins = "sdmmc3_cmd_pa7",
"sdmmc3_dat2_pb5",
"sdmmc3_dat3_pb4";
nvidia,function = "sdmmc3";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc4_clk_pcc4 {
nvidia,pins = "sdmmc4_clk_pcc4",
"sdmmc4_rst_n_pcc3";
nvidia,function = "sdmmc4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc4_dat0_paa0 {
nvidia,pins = "sdmmc4_dat0_paa0",
"sdmmc4_dat6_paa6",
"sdmmc4_dat7_paa7";
nvidia,function = "sdmmc4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
dap2_fs_pa2 {
nvidia,pins = "dap2_fs_pa2",
"dap2_din_pa4",
"dap2_dout_pa5";
nvidia,function = "i2s1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
pex_l1_prsnt_n_pdd4 {
nvidia,pins = "pex_l1_prsnt_n_pdd4",
"pex_l1_clkreq_n_pdd6";
- nvidia,pull = <2>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
};
sdio3 {
nvidia,pins = "drive_sdio3";
- nvidia,high-speed-mode = <0>;
- nvidia,schmitt = <0>;
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
nvidia,pull-down-strength = <46>;
nvidia,pull-up-strength = <42>;
nvidia,slew-rate-rising = <1>;
status = "okay";
clock-frequency = <100000>;
- rt5640: rt5640 {
+ rt5640: rt5640@1c {
compatible = "realtek,rt5640";
reg = <0x1c>;
interrupt-parent = <&gpio>;
<&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>;
};
- tps62361 {
- compatible = "ti,tps62361";
- reg = <0x60>;
-
- regulator-name = "tps62361-vout";
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1500000>;
- regulator-boot-on;
- regulator-always-on;
- ti,vsel0-state-high;
- ti,vsel1-state-high;
- };
-
pmic: tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
};
};
};
+
+ tps62361@60 {
+ compatible = "ti,tps62361";
+ reg = <0x60>;
+
+ regulator-name = "tps62361-vout";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ };
};
spi@7000da00 {
};
};
- ahub {
- i2s@70080400 {
- status = "okay";
- };
- };
-
- pmc {
+ pmc@7000e400 {
status = "okay";
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,sys-clock-req-active-high;
};
+ ahub@70080000 {
+ i2s@70080400 {
+ status = "okay";
+ };
+ };
+
sdhci@78000000 {
status = "okay";
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
non-removable;
};
+ usb@7d004000 {
+ status = "okay";
+ };
+
+ phy2: usb-phy@7d004000 {
+ vbus-supply = <&sys_3v3_reg>;
+ status = "okay";
+ };
+
usb@7d008000 {
status = "okay";
};
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
};
};
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ gpled1 {
+ label = "LED1"; /* CR5A1 (blue) */
+ gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>;
+ };
+ gpled2 {
+ label = "LED2"; /* CR4A2 (green) */
+ gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
};
};
- gpio-leds {
- compatible = "gpio-leds";
-
- gpled1 {
- label = "LED1"; /* CR5A1 (blue) */
- gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>;
- };
- gpled2 {
- label = "LED2"; /* CR4A2 (green) */
- gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>;
- };
- };
-
sound {
compatible = "nvidia,tegra-audio-rt5640-beaver",
"nvidia,tegra-audio-rt5640";
model = "NVIDIA Tegra30 Cardhu A02 evaluation board";
compatible = "nvidia,cardhu-a02", "nvidia,cardhu", "nvidia,tegra30";
+ sdhci@78000400 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
};
};
-
- sdhci@78000400 {
- status = "okay";
- power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
- bus-width = <4>;
- keep-power-in-suspend;
- };
};
model = "NVIDIA Tegra30 Cardhu A04 (A05, A06, A07) evaluation board";
compatible = "nvidia,cardhu-a04", "nvidia,cardhu", "nvidia,tegra30";
+ sdhci@78000400 {
+ status = "okay";
+ power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
gpio = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>;
};
};
-
- sdhci@78000400 {
- status = "okay";
- power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>;
- bus-width = <4>;
- keep-power-in-suspend;
- };
};
model = "NVIDIA Tegra30 Cardhu evaluation board";
compatible = "nvidia,cardhu", "nvidia,tegra30";
+ aliases {
+ rtc0 = "/i2c@7000d000/tps6586x@34";
+ rtc1 = "/rtc@7000e000";
+ };
+
memory {
reg = <0x80000000 0x40000000>;
};
- pcie-controller {
+ pcie-controller@00003000 {
status = "okay";
pex-clk-supply = <&pex_hvdd_3v3_reg>;
vdd-supply = <&ldo1_reg>;
};
};
- pinmux {
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ nvidia,panel = <&panel>;
+ };
+ };
+ };
+
+ pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
sdmmc1_clk_pz0 {
nvidia,pins = "sdmmc1_clk_pz0";
nvidia,function = "sdmmc1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc1_cmd_pz1 {
nvidia,pins = "sdmmc1_cmd_pz1",
"sdmmc1_dat2_py5",
"sdmmc1_dat3_py4";
nvidia,function = "sdmmc1";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc3_clk_pa6 {
nvidia,pins = "sdmmc3_clk_pa6";
nvidia,function = "sdmmc3";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc3_cmd_pa7 {
nvidia,pins = "sdmmc3_cmd_pa7",
"sdmmc3_dat2_pb5",
"sdmmc3_dat3_pb4";
nvidia,function = "sdmmc3";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc4_clk_pcc4 {
nvidia,pins = "sdmmc4_clk_pcc4",
"sdmmc4_rst_n_pcc3";
nvidia,function = "sdmmc4";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdmmc4_dat0_paa0 {
nvidia,pins = "sdmmc4_dat0_paa0",
"sdmmc4_dat6_paa6",
"sdmmc4_dat7_paa7";
nvidia,function = "sdmmc4";
- nvidia,pull = <2>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
dap2_fs_pa2 {
nvidia,pins = "dap2_fs_pa2",
"dap2_din_pa4",
"dap2_dout_pa5";
nvidia,function = "i2s1";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
sdio3 {
nvidia,pins = "drive_sdio3";
- nvidia,high-speed-mode = <0>;
- nvidia,schmitt = <0>;
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
nvidia,pull-down-strength = <46>;
nvidia,pull-up-strength = <42>;
- nvidia,slew-rate-rising = <1>;
- nvidia,slew-rate-falling = <1>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FAST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FAST>;
};
uart3_txd_pw6 {
nvidia,pins = "uart3_txd_pw6",
"uart3_rts_n_pc0",
"uart3_rxd_pw7";
nvidia,function = "uartc";
- nvidia,pull = <0>;
- nvidia,tristate = <0>;
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
};
};
status = "okay";
};
- i2c@7000c000 {
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ panelddc: i2c@7000c000 {
status = "okay";
clock-frequency = <100000>;
};
interrupts = <TEGRA_GPIO(CC, 2) IRQ_TYPE_LEVEL_LOW>;
};
- tps62361 {
+ tps62361@60 {
compatible = "ti,tps62361";
reg = <0x60>;
};
};
- ahub {
- i2s@70080400 {
- status = "okay";
- };
- };
-
- pmc {
+ pmc@7000e400 {
status = "okay";
nvidia,invert-interrupt;
nvidia,suspend-mode = <1>;
nvidia,sys-clock-req-active-high;
};
+ ahub@70080000 {
+ i2s@70080400 {
+ status = "okay";
+ };
+ };
+
sdhci@78000000 {
status = "okay";
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
status = "okay";
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_bl_reg>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ };
+
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
- clk32k_in: clock {
+ clk32k_in: clock@0 {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
};
};
+ panel: panel {
+ compatible = "chunghwa,claa101wb01", "simple-panel";
+ ddc-i2c-bus = <&panelddc>;
+
+ power-supply = <&vdd_pnl1_reg>;
+ enable-gpios = <&gpio TEGRA_GPIO(L, 2) GPIO_ACTIVE_HIGH>;
+
+ backlight = <&backlight>;
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#include <dt-bindings/clock/tegra30-car.h>
#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
serial4 = &uarte;
};
- pcie-controller {
+ pcie-controller@00003000 {
compatible = "nvidia,tegra30-pcie";
device_type = "pci";
reg = <0x00003000 0x00000800 /* PADS registers */
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 {
};
};
- host1x {
+ host1x@50000000 {
compatible = "nvidia,tegra30-host1x", "simple-bus";
reg = <0x50000000 0x00024000>;
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>;
ranges = <0x54000000 0x54000000 0x04000000>;
- mpe {
+ mpe@54040000 {
compatible = "nvidia,tegra30-mpe";
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 {
+ vi@54080000 {
compatible = "nvidia,tegra30-vi";
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 {
+ epp@540c0000 {
compatible = "nvidia,tegra30-epp";
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 {
+ isp@54100000 {
compatible = "nvidia,tegra30-isp";
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 {
+ gr2d@54140000 {
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>;
};
- gr3d {
+ gr3d@54180000 {
compatible = "nvidia,tegra30-gr3d";
reg = <0x54180000 0x00040000>;
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 {
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";
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";
};
};
- hdmi {
+ hdmi@54280000 {
compatible = "nvidia,tegra30-hdmi";
reg = <0x54280000 0x00040000>;
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
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";
};
- tvo {
+ tvo@542c0000 {
compatible = "nvidia,tegra30-tvo";
reg = <0x542c0000 0x00040000>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
- dsi {
+ dsi@54300000 {
compatible = "nvidia,tegra30-dsi";
reg = <0x54300000 0x00040000>;
clocks = <&tegra_car TEGRA30_CLK_DSIA>;
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
status = "disabled";
};
};
clocks = <&tegra_car TEGRA30_CLK_TWD>;
};
- intc: interrupt-controller {
+ intc: interrupt-controller@50041000 {
compatible = "arm,cortex-a9-gic";
reg = <0x50041000 0x1000
0x50040100 0x0100>;
#interrupt-cells = <3>;
};
- cache-controller {
+ cache-controller@50043000 {
compatible = "arm,pl310-cache";
reg = <0x50043000 0x1000>;
arm,data-latency = <6 6 2>;
clocks = <&tegra_car TEGRA30_CLK_TIMER>;
};
- tegra_car: clock {
+ tegra_car: clock@60006000 {
compatible = "nvidia,tegra30-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
- apbdma: dma {
+ apbdma: dma@6000a000 {
compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
reg = <0x6000a000 0x1400>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
<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 {
+ ahb: ahb@6000c004 {
compatible = "nvidia,tegra30-ahb";
reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
};
- gpio: gpio {
+ gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio";
reg = <0x6000d000 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
interrupt-controller;
};
- pinmux: pinmux {
+ pinmux: pinmux@70000868 {
compatible = "nvidia,tegra30-pinmux";
reg = <0x70000868 0xd4 /* Pad control registers */
0x70003000 0x3e4>; /* Mux registers */
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";
};
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";
};
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";
};
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";
};
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";
};
- pwm: pwm {
+ pwm: pwm@7000a000 {
compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car TEGRA30_CLK_PWM>;
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
status = "disabled";
};
- rtc {
+ rtc@7000e000 {
compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
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";
};
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";
};
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";
};
#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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
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";
};
- kbc {
+ kbc@7000e200 {
compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc";
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";
};
- pmc {
+ pmc@7000e400 {
compatible = "nvidia,tegra30-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
};
- memory-controller {
+ memory-controller@7000f000 {
compatible = "nvidia,tegra30-mc";
reg = <0x7000f000 0x010
0x7000f03c 0x1b4
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
};
- iommu {
+ iommu@7000f010 {
compatible = "nvidia,tegra30-smmu";
reg = <0x7000f010 0x02c
0x7000f1f0 0x010
nvidia,ahb = <&ahb>;
};
- ahub {
+ ahub@70080000 {
compatible = "nvidia,tegra30-ahub";
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>;
reg = <0x70080300 0x100>;
nvidia,ahub-cif-ids = <4 4>;
clocks = <&tegra_car TEGRA30_CLK_I2S0>;
+ resets = <&tegra_car 30>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080400 0x100>;
nvidia,ahub-cif-ids = <5 5>;
clocks = <&tegra_car TEGRA30_CLK_I2S1>;
+ resets = <&tegra_car 11>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080500 0x100>;
nvidia,ahub-cif-ids = <6 6>;
clocks = <&tegra_car TEGRA30_CLK_I2S2>;
+ resets = <&tegra_car 18>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080600 0x100>;
nvidia,ahub-cif-ids = <7 7>;
clocks = <&tegra_car TEGRA30_CLK_I2S3>;
+ resets = <&tegra_car 101>;
+ reset-names = "i2s";
status = "disabled";
};
reg = <0x70080700 0x100>;
nvidia,ahub-cif-ids = <8 8>;
clocks = <&tegra_car TEGRA30_CLK_I2S4>;
+ resets = <&tegra_car 102>;
+ reset-names = "i2s";
status = "disabled";
};
};
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";
};
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";
};
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";
};
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";
};
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";
compatible = "nvidia,tegra30-ehci", "usb-ehci";
reg = <0x7d004000 0x4000>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
- phy_type = "ulpi";
+ phy_type = "utmi";
clocks = <&tegra_car TEGRA30_CLK_USB2>;
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
nvidia,phy = <&phy2>;
status = "disabled";
};
phy2: usb-phy@7d004000 {
compatible = "nvidia,tegra30-usb-phy";
- reg = <0x7d004000 0x4000>;
- phy_type = "ulpi";
+ reg = <0x7d004000 0x4000 0x7d000000 0x4000>;
+ phy_type = "utmi";
clocks = <&tegra_car TEGRA30_CLK_USB2>,
<&tegra_car TEGRA30_CLK_PLL_U>,
- <&tegra_car TEGRA30_CLK_CDEV2>;
- clock-names = "reg", "pll_u", "ulpi-link";
+ <&tegra_car TEGRA30_CLK_USBD>;
+ clock-names = "reg", "pll_u", "utmi-pads";
+ nvidia,hssync-start-delay = <9>;
+ nvidia,idle-wait-delay = <17>;
+ nvidia,elastic-limit = <16>;
+ nvidia,term-range-adj = <6>;
+ nvidia,xcvr-setup = <51>;
+ nvidia.xcvr-setup-use-fuses;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ nvidia,xcvr-hsslew = <32>;
+ nvidia,hssquelch-level = <2>;
+ nvidia,hsdiscon-level = <5>;
status = "disabled";
};
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";
};
/ {
compatible = "xlnx,zynq-7000";
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <0>;
+ clocks = <&clkc 3>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ device_type = "cpu";
+ reg = <1>;
+ clocks = <&clkc 3>;
+ };
+ };
+
pmu {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 5 4>, <0 6 4>;
interrupts = <0 50 4>;
};
+ gem0: ethernet@e000b000 {
+ compatible = "cdns,gem";
+ reg = <0xe000b000 0x4000>;
+ status = "disabled";
+ interrupts = <0 22 4>;
+ clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
+ clock-names = "pclk", "hclk", "tx_clk";
+ };
+
+ gem1: ethernet@e000c000 {
+ compatible = "cdns,gem";
+ reg = <0xe000c000 0x4000>;
+ status = "disabled";
+ interrupts = <0 45 4>;
+ clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
+ clock-names = "pclk", "hclk", "tx_clk";
+ };
+
slcr: slcr@f8000000 {
compatible = "xlnx,zynq-slcr";
reg = <0xF8000000 0x1000>;
compatible = "cdns,ttc";
clocks = <&clkc 6>;
reg = <0xF8001000 0x1000>;
- clock-ranges;
};
ttc1: ttc1@f8002000 {
compatible = "cdns,ttc";
clocks = <&clkc 6>;
reg = <0xF8002000 0x1000>;
- clock-ranges;
};
scutimer: scutimer@f8f00600 {
interrupt-parent = <&intc>;
};
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii";
+};
+
&uart1 {
status = "okay";
};
};
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii";
+};
+
&uart1 {
status = "okay";
};
};
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii";
+};
+
&uart1 {
status = "okay";
};
CONFIG_PERF_EVENTS=y
CONFIG_SLAB=y
# CONFIG_BLOCK is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A73A4=y
CONFIG_MACH_APE6EVM=y
# CONFIG_ARM_THUMB is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A7740=y
CONFIG_MACH_ARMADILLO800EVA=y
# CONFIG_SH_TIMER_TMU is not set
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A7778=y
CONFIG_MACH_BOCKW=y
CONFIG_MEMORY_START=0x60000000
CONFIG_PERF_EVENTS=y
CONFIG_SLAB=y
# CONFIG_BLOCK is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A7791=y
CONFIG_MACH_KOELSCH=y
# CONFIG_SWP_EMULATE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_EMEV2=y
CONFIG_MACH_KZM9D=y
CONFIG_MEMORY_START=0x40000000
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_SH73A0=y
CONFIG_MACH_KZM9G=y
CONFIG_MEMORY_START=0x41000000
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A7790=y
CONFIG_MACH_LAGER=y
# CONFIG_SH_TIMER_TMU is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_SH7372=y
CONFIG_MACH_MACKEREL=y
CONFIG_MEMORY_SIZE=0x10000000
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
CONFIG_ARCH_R8A7779=y
CONFIG_MACH_MARZEN=y
CONFIG_MEMORY_START=0x60000000
CONFIG_SMSC911X=y
CONFIG_STMMAC_ETH=y
CONFIG_MDIO_SUN4I=y
+CONFIG_TI_CPSW=y
CONFIG_KEYBOARD_SPEAR=y
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIAL_8250=y
CONFIG_USB_ISP1301=y
CONFIG_USB_MXS_PHY=y
CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
CONFIG_EDAC=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65910=y
CONFIG_TWL6040_CORE=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_COMMON_CLK_DEBUG=y
# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
CONFIG_NLS=y
+CONFIG_PRINTK_TIME=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_IDLE=y
+CONFIG_ARM_U8500_CPUIDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_PM_RUNTIME=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_VFAT_FS=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_MISC_FILESYSTEMS is not set
* mapping to be mapped at. This is particularly important for
* non-high vector CPUs.
*/
-#define FIRST_USER_ADDRESS PAGE_SIZE
+#define FIRST_USER_ADDRESS (PAGE_SIZE * 2)
/*
* Use TASK_SIZE as the ceiling argument for free_pgtables() and
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
#include <asm/mach-types.h>
#include <asm/smp_plat.h>
#include <asm/system_misc.h>
-extern const unsigned char relocate_new_kernel[];
+extern void relocate_new_kernel(void);
extern const unsigned int relocate_new_kernel_size;
extern unsigned long kexec_start_address;
{
unsigned long page_list;
unsigned long reboot_code_buffer_phys;
+ unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
+ unsigned long reboot_entry_phys;
void *reboot_code_buffer;
/*
/* copy our kernel relocation code to the control code page */
- memcpy(reboot_code_buffer,
- relocate_new_kernel, relocate_new_kernel_size);
+ reboot_entry = fncpy(reboot_code_buffer,
+ reboot_entry,
+ relocate_new_kernel_size);
+ reboot_entry_phys = (unsigned long)reboot_entry +
+ (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
-
- flush_icache_range((unsigned long) reboot_code_buffer,
- (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
printk(KERN_INFO "Bye!\n");
if (kexec_reinit)
kexec_reinit();
- soft_restart(reboot_code_buffer_phys);
+ soft_restart(reboot_entry_phys);
}
* relocate_kernel.S - put the kernel image in place to boot
*/
+#include <linux/linkage.h>
#include <asm/kexec.h>
- .globl relocate_new_kernel
-relocate_new_kernel:
+ .align 3 /* not needed for this code, but keeps fncpy() happy */
+
+ENTRY(relocate_new_kernel)
ldr r0,kexec_indirection_page
ldr r1,kexec_start_address
kexec_boot_atags:
.long 0x0
+ENDPROC(relocate_new_kernel)
+
relocate_new_kernel_end:
.globl relocate_new_kernel_size
* snippets.
*/
+/*
+ * In CPU_THUMBONLY case kernel arm opcodes are not allowed.
+ * Note in this case codes skips those instructions but it uses .org
+ * directive to keep correct layout of sigreturn_codes array.
+ */
+#ifndef CONFIG_CPU_THUMBONLY
+#define ARM_OK(code...) code
+#else
+#define ARM_OK(code...)
+#endif
+
+ .macro arm_slot n
+ .org sigreturn_codes + 12 * (\n)
+ARM_OK( .arm )
+ .endm
+
+ .macro thumb_slot n
+ .org sigreturn_codes + 12 * (\n) + 8
+ .thumb
+ .endm
+
#if __LINUX_ARM_ARCH__ <= 4
/*
* Note we manually set minimally required arch that supports
.global sigreturn_codes
.type sigreturn_codes, #object
- .arm
+ .align
sigreturn_codes:
/* ARM sigreturn syscall code snippet */
- mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
- swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)
+ arm_slot 0
+ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) )
+ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
/* Thumb sigreturn syscall code snippet */
- .thumb
+ thumb_slot 0
movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
swi #0
/* ARM sigreturn_rt syscall code snippet */
- .arm
- mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
- swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)
+ arm_slot 1
+ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) )
+ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
/* Thumb sigreturn_rt syscall code snippet */
- .thumb
+ thumb_slot 1
movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
swi #0
* it is thumb case or not, so we need additional
* word after real last entry.
*/
- .arm
+ arm_slot 2
.space 4
.size sigreturn_codes, . - sigreturn_codes
/*
* loops = r0 * HZ * loops_per_jiffy / 1000000
*/
+ .align 3
@ Delay routine
ENTRY(__loop_delay)
if ARCH_AT91
+config HAVE_AT91_UTMI
+ bool
+
+config HAVE_AT91_USB_CLK
+ bool
+
config HAVE_AT91_DBGU0
bool
config HAVE_AT91_DBGU1
bool
+config AT91_USE_OLD_CLK
+ bool
+
config AT91_PMC_UNIT
bool
default !ARCH_AT91X40
+config COMMON_CLK_AT91
+ bool
+ default AT91_PMC_UNIT && USE_OF && !AT91_USE_OLD_CLK
+ select COMMON_CLK
+
+config OLD_CLK_AT91
+ bool
+ default AT91_PMC_UNIT && AT91_USE_OLD_CLK
+
config AT91_SAM9_ALT_RESET
bool
default !ARCH_AT91X40
config AT91_SAM9_TIME
bool
+config HAVE_AT91_SMD
+ bool
+
config SOC_AT91SAM9
bool
select AT91_SAM9_TIME
select SOC_SAMA5
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU1
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
help
Select this if you are using one of Atmel's SAMA5D3 family SoC.
This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
select HAVE_AT91_DBGU0
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_USB_CLK
config SOC_AT91SAM9260
bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
select HAVE_AT91_DBGU0
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_USB_CLK
help
Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
or AT91SAM9G20 SoC.
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_USB_CLK
help
Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_USB_CLK
config SOC_AT91SAM9RL
bool "AT91SAM9RL"
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_UTMI
config SOC_AT91SAM9G45
bool "AT91SAM9G45 or AT91SAM9M10 families"
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_USB_CLK
help
Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11.
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
help
Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
This means that your SAM9 name finishes with a '5' (except if it is
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+ select AT91_USE_OLD_CLK
+ select HAVE_AT91_USB_CLK
help
Select this if you are using Atmel's AT91SAM9N12 SoC.
config ARCH_AT91RM9200
bool "AT91RM9200"
select SOC_AT91RM9200
+ select AT91_USE_OLD_CLK
config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
select SOC_AT91SAM9260
+ select AT91_USE_OLD_CLK
config ARCH_AT91SAM9261
bool "AT91SAM9261 or AT91SAM9G10"
select SOC_AT91SAM9261
+ select AT91_USE_OLD_CLK
config ARCH_AT91SAM9263
bool "AT91SAM9263"
select SOC_AT91SAM9263
+ select AT91_USE_OLD_CLK
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
select SOC_AT91SAM9RL
+ select AT91_USE_OLD_CLK
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
select SOC_AT91SAM9G45
+ select AT91_USE_OLD_CLK
config ARCH_AT91X40
bool "AT91x40"
obj-n :=
obj- :=
-obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
+obj-$(CONFIG_OLD_CLK_AT91) += clock.o
obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o
#include <linux/module.h>
#include <linux/reboot.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
#include <mach/at91rm9200.h>
-#include <mach/at91_pmc.h>
#include <mach/at91_st.h>
#include <mach/cpu.h>
static struct clock_event_device clkevt = {
.name = "at91_tick",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .shift = 32,
.rating = 150,
.set_next_event = clkevt32k_next_event,
.set_mode = clkevt32k_mode,
at91_st_write(AT91_ST_RTMR, 1);
/* Setup timer clockevent, with minimum of two ticks (important!!) */
- clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
- clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
- clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
clkevt.cpumask = cpumask_of(0);
- clockevents_register_device(&clkevt);
+ clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+ 2, AT91_ST_ALMV);
/* register clocksource */
clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
*/
#include <linux/module.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91sam9260.h>
-#include <mach/at91_pmc.h>
#include "at91_aic.h"
#include "at91_rstc.h"
*/
#include <linux/module.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/system_misc.h>
#include <mach/cpu.h>
#include <mach/at91sam9261.h>
-#include <mach/at91_pmc.h>
#include "at91_aic.h"
#include "at91_rstc.h"
*/
#include <linux/module.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
#include <mach/at91sam9263.h>
-#include <mach/at91_pmc.h>
#include "at91_aic.h"
#include "at91_rstc.h"
static u32 pit_cycle; /* write-once */
static u32 pit_cnt; /* access only w/system irq blocked */
static void __iomem *pit_base_addr __read_mostly;
+static struct clk *mck;
static inline unsigned int pit_read(unsigned int reg_offset)
{
if (!pit_base_addr)
goto node_err;
+ mck = of_clk_get(np, 0);
+
/* Get the interrupts property */
ret = irq_of_parse_and_map(np, 0);
if (!ret) {
pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
+ if (!IS_ERR(mck))
+ clk_put(mck);
goto ioremap_err;
}
at91sam926x_pit_irq.irq = ret;
unsigned bits;
int ret;
+ mck = ERR_PTR(-ENOENT);
+
/* For device tree enabled device: initialize here */
of_at91sam926x_pit_init();
* Use our actual MCK to figure out how many MCK/16 ticks per
* 1/HZ period (instead of a compile-time constant LATCH).
*/
- pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16;
+ if (IS_ERR(mck))
+ mck = clk_get(NULL, "mck");
+
+ if (IS_ERR(mck))
+ panic("AT91: PIT: Unable to get mck clk\n");
+ pit_rate = clk_get_rate(mck) / 16;
pit_cycle = (pit_rate + HZ/2) / HZ;
WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
#include <linux/module.h>
#include <linux/dma-mapping.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
#include <mach/at91sam9g45.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "at91_aic.h"
#include <linux/module.h>
#include <linux/dma-mapping.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/at91sam9n12.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "board.h"
*/
#include <linux/module.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91sam9rl.h>
-#include <mach/at91_pmc.h>
#include "at91_aic.h"
#include "at91_rstc.h"
#include <linux/module.h>
#include <linux/dma-mapping.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/at91sam9x5.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "board.h"
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
+#include <linux/clk-provider.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include "at91_aic.h"
#include "generic.h"
+static void __init sama5_dt_timer_init(void)
+{
+#if defined(CONFIG_COMMON_CLK)
+ of_clk_init(NULL);
+#endif
+ at91sam926x_pit_init();
+}
static const struct of_device_id irq_of_match[] __initconst = {
DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = sama5_dt_timer_init,
.map_io = at91_map_io,
.handle_irq = at91_aic5_handle_irq,
.init_early = at91_dt_initialize,
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of_address.h>
+#include <linux/clk/at91_pmc.h>
#include <mach/hardware.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include <asm/proc-fns.h>
#if defined(CONFIG_OF)
static struct of_device_id pmc_ids[] = {
{ .compatible = "atmel,at91rm9200-pmc" },
+ { .compatible = "atmel,at91sam9260-pmc" },
+ { .compatible = "atmel,at91sam9g45-pmc" },
+ { .compatible = "atmel,at91sam9n12-pmc" },
+ { .compatible = "atmel,at91sam9x5-pmc" },
+ { .compatible = "atmel,sama5d3-pmc" },
{ /*sentinel*/ }
};
extern void at91x40_timer_init(void);
/* Clocks */
-#ifdef CONFIG_AT91_PMC_UNIT
+#ifdef CONFIG_OLD_CLK_AT91
extern int __init at91_clock_init(unsigned long main_clock);
extern int __init at91_dt_clock_init(void);
#else
static int inline at91_clock_init(unsigned long main_clock) { return 0; }
+static int inline at91_dt_clock_init(void) { return 0; }
#endif
struct device;
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <linux/atomic.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "at91_aic.h"
#include <mach/at91_ramc.h>
#include <mach/at91rm9200_sdramc.h>
+#ifdef CONFIG_PM
extern void at91_pm_set_standby(void (*at91_standby)(void));
+#else
+static inline void at91_pm_set_standby(void (*at91_standby)(void)) { }
+#endif
/*
* The AT91RM9200 goes into self-refresh mode with this command, and will
*/
#include <linux/linkage.h>
+#include <linux/clk/at91_pmc.h>
#include <mach/hardware.h>
-#include <mach/at91_pmc.h>
#include <mach/at91_ramc.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/sama5d3.h>
-#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "soc.h"
#include "generic.h"
-#include "clock.h"
#include "sam9_smc.h"
-/* --------------------------------------------------------------------
- * Clocks
- * -------------------------------------------------------------------- */
-
-/*
- * The peripheral clocks.
- */
-
-static struct clk pioA_clk = {
- .name = "pioA_clk",
- .pid = SAMA5D3_ID_PIOA,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pioB_clk = {
- .name = "pioB_clk",
- .pid = SAMA5D3_ID_PIOB,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pioC_clk = {
- .name = "pioC_clk",
- .pid = SAMA5D3_ID_PIOC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pioD_clk = {
- .name = "pioD_clk",
- .pid = SAMA5D3_ID_PIOD,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pioE_clk = {
- .name = "pioE_clk",
- .pid = SAMA5D3_ID_PIOE,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart0_clk = {
- .name = "usart0_clk",
- .pid = SAMA5D3_ID_USART0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk usart1_clk = {
- .name = "usart1_clk",
- .pid = SAMA5D3_ID_USART1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk usart2_clk = {
- .name = "usart2_clk",
- .pid = SAMA5D3_ID_USART2,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk usart3_clk = {
- .name = "usart3_clk",
- .pid = SAMA5D3_ID_USART3,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk uart0_clk = {
- .name = "uart0_clk",
- .pid = SAMA5D3_ID_UART0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk uart1_clk = {
- .name = "uart1_clk",
- .pid = SAMA5D3_ID_UART1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk twi0_clk = {
- .name = "twi0_clk",
- .pid = SAMA5D3_ID_TWI0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk twi1_clk = {
- .name = "twi1_clk",
- .pid = SAMA5D3_ID_TWI1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk twi2_clk = {
- .name = "twi2_clk",
- .pid = SAMA5D3_ID_TWI2,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk mmc0_clk = {
- .name = "mci0_clk",
- .pid = SAMA5D3_ID_HSMCI0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc1_clk = {
- .name = "mci1_clk",
- .pid = SAMA5D3_ID_HSMCI1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc2_clk = {
- .name = "mci2_clk",
- .pid = SAMA5D3_ID_HSMCI2,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi0_clk = {
- .name = "spi0_clk",
- .pid = SAMA5D3_ID_SPI0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi1_clk = {
- .name = "spi1_clk",
- .pid = SAMA5D3_ID_SPI1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk tcb0_clk = {
- .name = "tcb0_clk",
- .pid = SAMA5D3_ID_TC0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk tcb1_clk = {
- .name = "tcb1_clk",
- .pid = SAMA5D3_ID_TC1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk adc_clk = {
- .name = "adc_clk",
- .pid = SAMA5D3_ID_ADC,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk adc_op_clk = {
- .name = "adc_op_clk",
- .type = CLK_TYPE_PERIPHERAL,
- .rate_hz = 5000000,
-};
-static struct clk dma0_clk = {
- .name = "dma0_clk",
- .pid = SAMA5D3_ID_DMA0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk dma1_clk = {
- .name = "dma1_clk",
- .pid = SAMA5D3_ID_DMA1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk uhphs_clk = {
- .name = "uhphs",
- .pid = SAMA5D3_ID_UHPHS,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk udphs_clk = {
- .name = "udphs_clk",
- .pid = SAMA5D3_ID_UDPHS,
- .type = CLK_TYPE_PERIPHERAL,
-};
-/* gmac only for sama5d33, sama5d34, sama5d35 */
-static struct clk macb0_clk = {
- .name = "macb0_clk",
- .pid = SAMA5D3_ID_GMAC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-/* emac only for sama5d31, sama5d35 */
-static struct clk macb1_clk = {
- .name = "macb1_clk",
- .pid = SAMA5D3_ID_EMAC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-/* lcd only for sama5d31, sama5d33, sama5d34 */
-static struct clk lcdc_clk = {
- .name = "lcdc_clk",
- .pid = SAMA5D3_ID_LCDC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-/* isi only for sama5d33, sama5d35 */
-static struct clk isi_clk = {
- .name = "isi_clk",
- .pid = SAMA5D3_ID_ISI,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk can0_clk = {
- .name = "can0_clk",
- .pid = SAMA5D3_ID_CAN0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk can1_clk = {
- .name = "can1_clk",
- .pid = SAMA5D3_ID_CAN1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk ssc0_clk = {
- .name = "ssc0_clk",
- .pid = SAMA5D3_ID_SSC0,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk ssc1_clk = {
- .name = "ssc1_clk",
- .pid = SAMA5D3_ID_SSC1,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV2,
-};
-static struct clk sha_clk = {
- .name = "sha_clk",
- .pid = SAMA5D3_ID_SHA,
- .type = CLK_TYPE_PERIPHERAL,
- .div = AT91_PMC_PCR_DIV8,
-};
-static struct clk aes_clk = {
- .name = "aes_clk",
- .pid = SAMA5D3_ID_AES,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk tdes_clk = {
- .name = "tdes_clk",
- .pid = SAMA5D3_ID_TDES,
- .type = CLK_TYPE_PERIPHERAL,
-};
-
-static struct clk *periph_clocks[] __initdata = {
- &pioA_clk,
- &pioB_clk,
- &pioC_clk,
- &pioD_clk,
- &pioE_clk,
- &usart0_clk,
- &usart1_clk,
- &usart2_clk,
- &usart3_clk,
- &uart0_clk,
- &uart1_clk,
- &twi0_clk,
- &twi1_clk,
- &twi2_clk,
- &mmc0_clk,
- &mmc1_clk,
- &mmc2_clk,
- &spi0_clk,
- &spi1_clk,
- &tcb0_clk,
- &tcb1_clk,
- &adc_clk,
- &adc_op_clk,
- &dma0_clk,
- &dma1_clk,
- &uhphs_clk,
- &udphs_clk,
- &macb0_clk,
- &macb1_clk,
- &lcdc_clk,
- &isi_clk,
- &can0_clk,
- &can1_clk,
- &ssc0_clk,
- &ssc1_clk,
- &sha_clk,
- &aes_clk,
- &tdes_clk,
-};
-
-static struct clk pck0 = {
- .name = "pck0",
- .pmc_mask = AT91_PMC_PCK0,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 0,
-};
-
-static struct clk pck1 = {
- .name = "pck1",
- .pmc_mask = AT91_PMC_PCK1,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 1,
-};
-
-static struct clk pck2 = {
- .name = "pck2",
- .pmc_mask = AT91_PMC_PCK2,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 2,
-};
-
-static struct clk_lookup periph_clocks_lookups[] = {
- /* lookup table for DT entries */
- CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
- CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
- CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
- CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk),
- CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioD_clk),
- CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioE_clk),
- CLKDEV_CON_DEV_ID("usart", "f001c000.serial", &usart0_clk),
- CLKDEV_CON_DEV_ID("usart", "f0020000.serial", &usart1_clk),
- CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart2_clk),
- CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart3_clk),
- CLKDEV_CON_DEV_ID(NULL, "f0014000.i2c", &twi0_clk),
- CLKDEV_CON_DEV_ID(NULL, "f0018000.i2c", &twi1_clk),
- CLKDEV_CON_DEV_ID(NULL, "f801c000.i2c", &twi2_clk),
- CLKDEV_CON_DEV_ID("mci_clk", "f0000000.mmc", &mmc0_clk),
- CLKDEV_CON_DEV_ID("mci_clk", "f8000000.mmc", &mmc1_clk),
- CLKDEV_CON_DEV_ID("mci_clk", "f8004000.mmc", &mmc2_clk),
- CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi0_clk),
- CLKDEV_CON_DEV_ID("spi_clk", "f8008000.spi", &spi1_clk),
- CLKDEV_CON_DEV_ID("t0_clk", "f0010000.timer", &tcb0_clk),
- CLKDEV_CON_DEV_ID("t0_clk", "f8014000.timer", &tcb1_clk),
- CLKDEV_CON_DEV_ID("tsc_clk", "f8018000.tsadcc", &adc_clk),
- CLKDEV_CON_DEV_ID("dma_clk", "ffffe600.dma-controller", &dma0_clk),
- CLKDEV_CON_DEV_ID("dma_clk", "ffffe800.dma-controller", &dma1_clk),
- CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
- CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
- CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
- CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
- CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
- CLKDEV_CON_DEV_ID("hclk", "f0028000.ethernet", &macb0_clk),
- CLKDEV_CON_DEV_ID("pclk", "f0028000.ethernet", &macb0_clk),
- CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb1_clk),
- CLKDEV_CON_DEV_ID("pclk", "f802c000.ethernet", &macb1_clk),
- CLKDEV_CON_DEV_ID("pclk", "f0008000.ssc", &ssc0_clk),
- CLKDEV_CON_DEV_ID("pclk", "f000c000.ssc", &ssc1_clk),
- CLKDEV_CON_DEV_ID("can_clk", "f000c000.can", &can0_clk),
- CLKDEV_CON_DEV_ID("can_clk", "f8010000.can", &can1_clk),
- CLKDEV_CON_DEV_ID("sha_clk", "f8034000.sha", &sha_clk),
- CLKDEV_CON_DEV_ID("aes_clk", "f8038000.aes", &aes_clk),
- CLKDEV_CON_DEV_ID("tdes_clk", "f803c000.tdes", &tdes_clk),
-};
-
-static void __init sama5d3_register_clocks(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
- clk_register(periph_clocks[i]);
-
- clkdev_add_table(periph_clocks_lookups,
- ARRAY_SIZE(periph_clocks_lookups));
-
- clk_register(&pck0);
- clk_register(&pck1);
- clk_register(&pck2);
-}
-
/* --------------------------------------------------------------------
* AT91SAM9x5 processor initialization
* -------------------------------------------------------------------- */
AT91_SOC_START(sama5d3)
.map_io = sama5d3_map_io,
- .register_clocks = sama5d3_register_clocks,
.init = sama5d3_initialize,
AT91_SOC_END
#include <linux/pm.h>
#include <linux/of_address.h>
#include <linux/pinctrl/machine.h>
+#include <linux/clk/at91_pmc.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
-#include <mach/at91_pmc.h>
#include "at91_shdwc.h"
#include "soc.h"
at91_dt_clock_init();
/* Register the processor-specific clocks */
- at91_boot_soc.register_clocks();
+ if (at91_boot_soc.register_clocks)
+ at91_boot_soc.register_clocks();
at91_boot_soc.init();
}
at91_dt_clock_init();
/* Register the processor-specific clocks */
- at91_boot_soc.register_clocks();
+ if (at91_boot_soc.register_clocks)
+ at91_boot_soc.register_clocks();
if (at91_boot_soc.init)
at91_boot_soc.init();
/*****************************************************************************
* SoC RTC
****************************************************************************/
-void __init dove_rtc_init(void)
+static void __init dove_rtc_init(void)
{
orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);
}
IRQ_DOVE_BRIDGE, dove_tclk);
}
-/*****************************************************************************
- * Cryptographic Engines and Security Accelerator (CESA)
- ****************************************************************************/
-void __init dove_crypto_init(void)
-{
- orion_crypto_init(DOVE_CRYPT_PHYS_BASE, DOVE_CESA_PHYS_BASE,
- DOVE_CESA_SIZE, IRQ_DOVE_CRYPTO);
-}
-
/*****************************************************************************
* XOR 0
****************************************************************************/
-void __init dove_xor0_init(void)
+static void __init dove_xor0_init(void)
{
orion_xor0_init(DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
/*****************************************************************************
* XOR 1
****************************************************************************/
-void __init dove_xor1_init(void)
+static void __init dove_xor1_init(void)
{
orion_xor1_init(DOVE_XOR1_PHYS_BASE, DOVE_XOR1_HIGH_PHYS_BASE,
IRQ_DOVE_XOR_10, IRQ_DOVE_XOR_11);
#include <linux/init.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <video/vga.h>
#include <asm/pgtable.h>
#include <asm/page.h>
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
}
+
+ vga_base = PCIMEM_BASE;
}
void footbridge_restart(enum reboot_mode mode, const char *cmd)
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/spinlock.h>
-#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
int cfn_mode;
pcibios_min_mem = 0x81000000;
- vga_base = PCIMEM_BASE;
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
const char *name;
const char *trigger;
} ebsa285_leds[] = {
- { "ebsa285:amber", "heartbeat", },
- { "ebsa285:green", "cpu0", },
+ { "ebsa285:amber", "cpu0", },
+ { "ebsa285:green", "heartbeat", },
{ "ebsa285:red",},
};
+static unsigned char hw_led_state;
+
static void ebsa285_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct ebsa285_led *led = container_of(cdev,
struct ebsa285_led, cdev);
- if (b != LED_OFF)
- *XBUS_LEDS |= led->mask;
+ if (b == LED_OFF)
+ hw_led_state |= led->mask;
else
- *XBUS_LEDS &= ~led->mask;
+ hw_led_state &= ~led->mask;
+ *XBUS_LEDS = hw_led_state;
}
static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
struct ebsa285_led *led = container_of(cdev,
struct ebsa285_led, cdev);
- return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF;
+ return hw_led_state & led->mask ? LED_OFF : LED_FULL;
}
static int __init ebsa285_leds_init(void)
{
int i;
- if (machine_is_ebsa285())
+ if (!machine_is_ebsa285())
return -ENODEV;
- /* 3 LEDS All ON */
- *XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
+ /* 3 LEDS all off */
+ hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
+ *XBUS_LEDS = hw_led_state;
for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
struct ebsa285_led *led;
/* Base address to the AP system controller */
void __iomem *ap_syscon_base;
+/* Base address to the external bus interface */
+static void __iomem *ebi_base;
+
/*
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
* just for now).
*/
#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
-#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
-#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
/*
* Logical Physical
* ef000000 Cache flush
- * f1000000 10000000 Core module registers
* f1100000 11000000 System controller registers
- * f1200000 12000000 EBI registers
* f1300000 13000000 Counter/Timer
* f1400000 14000000 Interrupt controller
* f1600000 16000000 UART 0
static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
{
- .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
- .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
.virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
.pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
.length = SZ_4K,
/*
* Flash handling.
*/
-#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
-#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
-
static int ap_flash_init(struct platform_device *dev)
{
u32 tmp;
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
- tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
- writel(tmp, EBI_CSR1);
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) |
+ INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
- if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
- writel(0xa05f, EBI_LOCK);
- writel(tmp, EBI_CSR1);
- writel(0, EBI_LOCK);
+ if (!(readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET)
+ & INTEGRATOR_EBI_WRITE_ENABLE)) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
}
return 0;
}
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
- tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
- writel(tmp, EBI_CSR1);
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ ~INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
- if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
- writel(0xa05f, EBI_LOCK);
- writel(tmp, EBI_CSR1);
- writel(0, EBI_LOCK);
+ if (readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ INTEGRATOR_EBI_WRITE_ENABLE) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
}
}
{ },
};
+static const struct of_device_id ebi_match[] = {
+ { .compatible = "arm,external-bus-interface"},
+ { },
+};
+
static void __init ap_init_of(void)
{
unsigned long sc_dec;
struct device_node *root;
struct device_node *syscon;
+ struct device_node *ebi;
struct device *parent;
struct soc_device *soc_dev;
struct soc_device_attribute *soc_dev_attr;
syscon = of_find_matching_node(root, ap_syscon_match);
if (!syscon)
return;
+ ebi = of_find_matching_node(root, ebi_match);
+ if (!ebi)
+ return;
ap_syscon_base = of_iomap(syscon, 0);
if (!ap_syscon_base)
return;
+ ebi_base = of_iomap(ebi, 0);
+ if (!ebi_base)
+ return;
ap_sc_id = readl(ap_syscon_base);
/*
* Logical Physical
- * f1000000 10000000 Core module registers
- * f1100000 11000000 System controller registers
- * f1200000 12000000 EBI registers
* f1300000 13000000 Counter/Timer
* f1400000 14000000 Interrupt controller
* f1600000 16000000 UART 0
* f1a00000 1a000000 Debug LEDs
* fc900000 c9000000 GPIO
* fca00000 ca000000 SIC
- * fcb00000 cb000000 CP system control
*/
static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
{
- .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
- .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
.virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
.pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
.length = SZ_4K,
* warranty of any kind, whether express or implied.
*/
+#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
-#include <linux/clk-provider.h>
#include <linux/dma-mapping.h>
#include <linux/irqchip.h>
#include <linux/kexec.h>
#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
-#include <linux/platform_data/usb-ehci-orion.h>
-#include <plat/irq.h>
#include <plat/common.h>
#include "common.h"
-/*
- * There are still devices that doesn't know about DT yet. Get clock
- * gates here and add a clock lookup alias, so that old platform
- * devices still work.
-*/
-
-static void __init kirkwood_legacy_clk_init(void)
-{
-
- struct device_node *np = of_find_compatible_node(
- NULL, NULL, "marvell,kirkwood-gating-clock");
- struct of_phandle_args clkspec;
- struct clk *clk;
-
- clkspec.np = np;
- clkspec.args_count = 1;
-
- /*
- * The ethernet interfaces forget the MAC address assigned by
- * u-boot if the clocks are turned off. Until proper DT support
- * is available we always enable them for now.
- */
- clkspec.args[0] = CGC_BIT_GE0;
- clk = of_clk_get_from_provider(&clkspec);
- clk_prepare_enable(clk);
-
- clkspec.args[0] = CGC_BIT_GE1;
- clk = of_clk_get_from_provider(&clkspec);
- clk_prepare_enable(clk);
-}
-
#define MV643XX_ETH_MAC_ADDR_LOW 0x0414
#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418
static void __init kirkwood_dt_init(void)
{
- pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
+ pr_info("Kirkwood: %s.\n", kirkwood_id());
/*
* Disable propagation of mbus errors to the CPU local bus,
kirkwood_cpufreq_init();
kirkwood_cpuidle_init();
- /* Setup clocks for legacy devices */
- kirkwood_legacy_clk_init();
kirkwood_pm_init();
kirkwood_dt_eth_fixup();
config ARCH_MSM8X60
bool "MSM8X60"
+ select ARCH_MSM_DT
select ARM_GIC
select CPU_V7
select GPIO_MSM_V2
config ARCH_MSM8960
bool "MSM8960"
+ select ARCH_MSM_DT
select ARM_GIC
select CPU_V7
select HAVE_SMP
select GPIO_MSM_V2
select MSM_SCM if SMP
+config ARCH_MSM8974
+ bool "MSM8974"
+ select ARCH_MSM_DT
+ select ARM_GIC
+ select CPU_V7
+ select HAVE_ARM_ARCH_TIMER
+ select HAVE_SMP
+ select MSM_SCM if SMP
+ select USE_OF
+
config ARCH_MSM_DT
- def_bool y
- depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+ bool
select SPARSE_IRQ
select USE_OF
* GNU General Public License for more details.
*
*/
+#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/kernel.h>
#include <linux/init.h>
platform_add_devices(devices, ARRAY_SIZE(devices));
-#ifdef CONFIG_MMC
- rc = trout_init_mmc(system_rev);
- if (rc)
- printk(KERN_CRIT "%s: MMC init failure (%d)\n", __func__, rc);
-#endif
-
+ if (IS_ENABLED(CONFIG_MMC)) {
+ rc = trout_init_mmc(system_rev);
+ if (rc)
+ pr_crit("MMC init failure (%d)\n", rc);
+ }
}
static struct map_desc trout_io_desc[] __initdata = {
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
#include "armada-370-xp.h"
+#include "coherency.h"
unsigned long coherency_phys_base;
static void __iomem *coherency_base;
#ifndef __MACH_370_XP_COHERENCY_H
#define __MACH_370_XP_COHERENCY_H
-int set_cpu_coherent(int cpu_id, int smp_group_id);
+extern unsigned long coherency_phys_base;
+
+int set_cpu_coherent(unsigned int cpu_id, int smp_group_id);
int coherency_init(void);
#endif /* __MACH_370_XP_COHERENCY_H */
void armada_xp_cpu_die(unsigned int cpu);
int armada_370_xp_coherency_init(void);
-int armada_370_xp_pmsu_init(void);
void armada_xp_secondary_startup(void);
extern struct smp_operations armada_xp_smp_ops;
#endif
#include <linux/errno.h>
#include <linux/smp.h>
#include <asm/proc-fns.h>
+#include "common.h"
/*
* platform-specific code to shutdown a CPU
return cpu_clk;
}
-void __init set_secondary_cpus_clock(void)
+static void __init set_secondary_cpus_clock(void)
{
int thiscpu, cpu;
unsigned long rate;
set_smp_cross_call(armada_mpic_send_doorbell);
}
-void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
+static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
{
struct device_node *node;
struct resource res;
#include <linux/io.h>
#include <linux/smp.h>
#include <asm/smp_plat.h>
+#include "pmsu.h"
static void __iomem *pmsu_mp_base;
static void __iomem *pmsu_reset_base;
}
#endif
-int __init armada_370_xp_pmsu_init(void)
+static int __init armada_370_xp_pmsu_init(void)
{
struct device_node *np;
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/reboot.h>
+#include "common.h"
static void __iomem *system_controller_base;
};
static struct mvebu_system_controller *mvebu_sc;
-const struct mvebu_system_controller armada_370_xp_system_controller = {
+static const struct mvebu_system_controller armada_370_xp_system_controller = {
.rstoutn_mask_offset = 0x60,
.system_soft_reset_offset = 0x64,
.rstoutn_mask_reset_out_en = 0x1,
.system_soft_reset = 0x1,
};
-const struct mvebu_system_controller orion_system_controller = {
+static const struct mvebu_system_controller orion_system_controller = {
.rstoutn_mask_offset = 0x108,
.system_soft_reset_offset = 0x10c,
.rstoutn_mask_reset_out_en = 0x4,
writel(1, srcbase + 0x18);
}
-/*
- * The SMSC911x IRQ is connected to a GPIO pin, but the driver expects
- * to simply request an IRQ passed as a resource. So the GPIO pin needs
- * to be requested by this hog and set as input.
- */
-static int __init cpu8815_eth_init(void)
-{
- struct device_node *eth;
- int gpio, irq, err;
-
- eth = of_find_node_by_path("/usb-s8815/ethernet-gpio");
- if (!eth) {
- pr_info("could not find any ethernet GPIO\n");
- return 0;
- }
- gpio = of_get_gpio(eth, 0);
- err = gpio_request(gpio, "eth_irq");
- if (err) {
- pr_info("failed to request ethernet GPIO\n");
- return -ENODEV;
- }
- err = gpio_direction_input(gpio);
- if (err) {
- pr_info("failed to set ethernet GPIO as input\n");
- return -ENODEV;
- }
- irq = gpio_to_irq(gpio);
- pr_info("enabled USB-S8815 ethernet GPIO %d, IRQ %d\n", gpio, irq);
- return 0;
-}
-device_initcall(cpu8815_eth_init);
-
/*
* This GPIO pin turns on a line that is used to detect card insertion
* on this board.
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
-obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
-obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
-obj-$(CONFIG_SOC_DRA7XX) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
obj-y += mcbsp.o
extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1);
struct omap2_hsmmc_info;
-extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers);
extern void omap_reserve(void);
struct omap_hwmod;
#include "soc.h"
#include "iomap.h"
-#include "mux.h"
#include "control.h"
#include "display.h"
#include "prm.h"
{ "dss_hdmi", "omapdss_hdmi", -1 },
};
-static void __init omap4_tpd12s015_mux_pads(void)
-{
- omap_mux_init_signal("hdmi_cec",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_scl",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_sda",
- OMAP_PIN_INPUT_PULLUP);
-}
-
-static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
-{
- u32 reg;
- u16 control_i2c_1;
-
- /*
- * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
- * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable
- * internal pull up resistor.
- */
- if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) {
- control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1;
- reg = omap4_ctrl_pad_readl(control_i2c_1);
- reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK |
- OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK);
- omap4_ctrl_pad_writel(reg, control_i2c_1);
- }
-}
-
-static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
-{
- u32 enable_mask, enable_shift;
- u32 pipd_mask, pipd_shift;
- u32 reg;
-
- if (dsi_id == 0) {
- enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
- enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
- pipd_mask = OMAP4_DSI1_PIPD_MASK;
- pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
- } else if (dsi_id == 1) {
- enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
- enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
- pipd_mask = OMAP4_DSI2_PIPD_MASK;
- pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
- } else {
- return -ENODEV;
- }
-
- reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
-
- reg &= ~enable_mask;
- reg &= ~pipd_mask;
-
- reg |= (lanes << enable_shift) & enable_mask;
- reg |= (lanes << pipd_shift) & pipd_mask;
-
- omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
-
- return 0;
-}
-
-int __init omap_hdmi_init(enum omap_hdmi_flags flags)
-{
- if (cpu_is_omap44xx()) {
- omap4_hdmi_mux_pads(flags);
- omap4_tpd12s015_mux_pads();
- }
-
- return 0;
-}
-
static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
{
- if (cpu_is_omap44xx())
- return omap4_dsi_mux_pads(dsi_id, lane_mask);
-
return 0;
}
static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
{
- if (cpu_is_omap44xx())
- omap4_dsi_mux_pads(dsi_id, 0);
}
static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = {
.name = "dvi",
.source = "tfp410.0",
- .i2c_bus_num = 3,
+ .i2c_bus_num = 2,
};
static struct platform_device omap3_igep2_dvi_connector_device = {
return ret;
}
+ /*
+ * For some GPMC devices we still need to rely on the bootloader
+ * timings because the devices can be connected via FPGA. So far
+ * the list is smc91x on the omap2 SDP boards, and 8250 on zooms.
+ * REVISIT: Add timing support from slls644g.pdf and from the
+ * lan91c96 manual.
+ */
+ if (of_device_is_compatible(child, "ns16550a") ||
+ of_device_is_compatible(child, "smsc,lan91c94") ||
+ of_device_is_compatible(child, "smsc,lan91c111")) {
+ dev_warn(&pdev->dev,
+ "%s using bootloader timings on CS%d\n",
+ child->name, cs);
+ goto no_timings;
+ }
+
/*
* FIXME: gpmc_cs_request() will map the CS to an arbitary
* location in the gpmc address space. When booting with
gpmc_read_timings_dt(child, &gpmc_t);
gpmc_cs_set_timings(cs, &gpmc_t);
+no_timings:
if (of_platform_device_create(child, NULL, &pdev->dev))
return 0;
return ret;
}
-/*
- * REVISIT: Add timing support from slls644g.pdf
- */
-static int gpmc_probe_8250(struct platform_device *pdev,
- struct device_node *child)
-{
- struct resource res;
- unsigned long base;
- int ret, cs;
-
- if (of_property_read_u32(child, "reg", &cs) < 0) {
- dev_err(&pdev->dev, "%s has no 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- if (of_address_to_resource(child, 0, &res) < 0) {
- dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- ret = gpmc_cs_request(cs, resource_size(&res), &base);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
- return ret;
- }
-
- if (of_platform_device_create(child, NULL, &pdev->dev))
- return 0;
-
- dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
-
- return -ENODEV;
-}
-
static int gpmc_probe_dt(struct platform_device *pdev)
{
int ret;
else if (of_node_cmp(child->name, "onenand") == 0)
ret = gpmc_probe_onenand_child(pdev, child);
else if (of_node_cmp(child->name, "ethernet") == 0 ||
- of_node_cmp(child->name, "nor") == 0)
+ of_node_cmp(child->name, "nor") == 0 ||
+ of_node_cmp(child->name, "uart") == 0)
ret = gpmc_probe_generic_child(pdev, child);
- else if (of_node_cmp(child->name, "8250") == 0)
- ret = gpmc_probe_8250(pdev, child);
if (WARN(ret < 0, "%s: probing gpmc child %s failed\n",
__func__, child->full_name))
{ }
#endif
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void set_cntfreq(void);
+#else
+static inline void set_cntfreq(void)
+{
+}
+#endif
+
#endif /* __ASSEMBLER__ */
#endif /* OMAP_ARCH_OMAP_SECURE_H */
#include "iomap.h"
#include "common.h"
#include "mmc.h"
-#include "hsmmc.h"
#include "prminst44xx.h"
#include "prcm_mpu44xx.h"
#include "omap4-sar-layout.h"
omap_wakeupgen_init();
irqchip_init();
}
-
-#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-static int omap4_twl6030_hsmmc_late_init(struct device *dev)
-{
- int irq = 0;
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct omap_mmc_platform_data *pdata = dev->platform_data;
-
- /* Setting MMC1 Card detect Irq */
- if (pdev->id == 0) {
- irq = twl6030_mmc_card_detect_config();
- if (irq < 0) {
- dev_err(dev, "%s: Error card detect config(%d)\n",
- __func__, irq);
- return irq;
- }
- pdata->slots[0].card_detect_irq = irq;
- pdata->slots[0].card_detect = twl6030_mmc_card_detect;
- }
- return 0;
-}
-
-static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
-{
- struct omap_mmc_platform_data *pdata;
-
- /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
- if (!dev) {
- pr_err("Failed %s\n", __func__);
- return;
- }
- pdata = dev->platform_data;
- pdata->init = omap4_twl6030_hsmmc_late_init;
-}
-
-int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
- struct omap2_hsmmc_info *c;
-
- omap_hsmmc_init(controllers);
- for (c = controllers; c->mmc; c++) {
- /* pdev can be null if CONFIG_MMC_OMAP_HS is not set */
- if (!c->pdev)
- continue;
- omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
- }
-
- return 0;
-}
-#else
-int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
- return 0;
-}
-#endif
static struct pdata_init pdata_quirks[] __initdata = {
#ifdef CONFIG_ARCH_OMAP3
+ { "nokia,omap3-n900", hsmmc2_internal_input_clk, },
{ "nokia,omap3-n9", hsmmc2_internal_input_clk, },
{ "nokia,omap3-n950", hsmmc2_internal_input_clk, },
{ "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
* will hang the system.
*/
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
- ret = _omap_save_secure_sram((u32 *)
+ ret = _omap_save_secure_sram((u32 *)(unsigned long)
__pa(omap3_secure_ram_storage));
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
/* Following is for error tracking, it should not happen */
for (i = 0; i < pwrdm->banks; i++)
pwrdm->ret_mem_off_counter[i] = 0;
- arch_pwrdm->pwrdm_wait_transition(pwrdm);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
+ arch_pwrdm->pwrdm_wait_transition(pwrdm);
pwrdm->state = pwrdm_read_pwrst(pwrdm);
pwrdm->state_counter[pwrdm->state] = 1;
extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
- defined(CONFIG_SOC_DRA7XX)
+ defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
void omap44xx_prm_reconfigure_io_chain(void);
#else
static inline void omap44xx_prm_reconfigure_io_chain(void)
#include <plat/irq.h>
#include "common.h"
-struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
+static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
NULL),
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/system_misc.h>
-#include <asm/timex.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
/*****************************************************************************
* SPI
****************************************************************************/
-void __init orion5x_spi_init()
+void __init orion5x_spi_init(void)
{
orion_spi_init(SPI_PHYS_BASE);
}
/*****************************************************************************
* Watchdog
****************************************************************************/
-void __init orion5x_wdt_init(void)
+static void __init orion5x_wdt_init(void)
{
orion_wdt_init();
}
int orion5x_tclk;
-int __init orion5x_find_tclk(void)
+static int __init orion5x_find_tclk(void)
{
u32 dev, rev;
* PCI
****************************************************************************/
-void __init db88f5281_pci_preinit(void)
+static void __init db88f5281_pci_preinit(void)
{
int pin;
#include <mach/bridge-regs.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
+#include "common.h"
static int __initdata gpio0_irqs[4] = {
IRQ_ORION5X_GPIO_0_7,
#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
- ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
+ ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : NULL)
#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
- ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
+ ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : NULL)
#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
* PCI
****************************************************************************/
-void __init rd88f5182_pci_preinit(void)
+static void __init rd88f5182_pci_preinit(void)
{
int pin;
#define TSP2_PCI_SLOT0_OFFS 7
#define TSP2_PCI_SLOT0_IRQ_PIN 11
-void __init tsp2_pci_preinit(void)
+static void __init tsp2_pci_preinit(void)
{
int pin;
#define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6
#define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7
-void __init qnap_ts209_pci_preinit(void)
+static void __init qnap_ts209_pci_preinit(void)
{
int pin;
},
};
-void __init ts78xx_map_io(void)
+static void __init ts78xx_map_io(void)
{
orion5x_map_io();
iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
#include <plat/devs.h>
#include <plat/fb.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/mmc-sdhci-s3c.h>
#include <plat/regs-serial.h>
+#include <plat/sdhci.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <video/platform_lcd.h>
.dev.platform_data = &mini6410_lcd_power_data,
};
+static struct s3c_sdhci_platdata mini6410_hsmmc1_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S3C64XX_GPN(10),
+ .ext_cd_gpio_invert = true,
+};
+
static struct platform_device *mini6410_devices[] __initdata = {
&mini6410_device_eth,
&s3c_device_hsmmc0,
s3c_nand_set_platdata(&mini6410_nand_info);
s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]);
+ s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);
s3c24xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
+config ARCH_SHMOBILE
+ bool
+
config ARCH_SHMOBILE_MULTI
bool "SH-Mobile Series" if ARCH_MULTI_V7
depends on MMU
+ select ARCH_SHMOBILE
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU if SMP
select HAVE_SMP
select ARM_GIC
select MIGHT_HAVE_CACHE_L2X0
+ select MIGHT_HAVE_PCI
select NO_IOPORT
select PINCTRL
select ARCH_REQUIRE_GPIOLIB
comment "SH-Mobile System Configuration"
endif
-if ARCH_SHMOBILE
+if ARCH_SHMOBILE_LEGACY
comment "SH-Mobile System Type"
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
select CPU_V7
+ select MIGHT_HAVE_PCI
select SH_CLK_CPG
select RENESAS_IRQC
config ARCH_R8A7791
bool "R-Car M2 (R8A77910)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
select CPU_V7
+ select MIGHT_HAVE_PCI
select SH_CLK_CPG
+ select RENESAS_IRQC
config ARCH_EMEV2
bool "Emma Mobile EV2"
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
select CPU_V7
+ select MIGHT_HAVE_PCI
+ select USE_OF
+ select AUTO_ZRELADDR
config ARCH_R7S72100
bool "RZ/A1H (R7S72100)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
select CPU_V7
select SH_CLK_CPG
bool "Koelsch board"
depends on ARCH_R8A7791
select USE_OF
-
-config MACH_KZM9D
- bool "KZM9D board"
- depends on ARCH_EMEV2
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
- select USE_OF
+ select MICREL_PHY if SH_ETH
config MACH_KZM9G
bool "KZM-A9-GT board"
endif
-if ARCH_SHMOBILE || ARCH_SHMOBILE_MULTI
+if ARCH_SHMOBILE
menu "Timer and clock configuration"
obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o
obj-$(CONFIG_MACH_KOELSCH) += board-koelsch.o
-obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o
obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o
endif
loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
loadaddr-$(CONFIG_MACH_GENMAI) += 0x8008000
loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000
-loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000
loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
};
static const struct resource mmcif0_resources[] __initconst = {
- DEFINE_RES_MEM_NAMED(0xee200000, 0x100, "MMCIF0"),
+ DEFINE_RES_MEM(0xee200000, 0x100),
DEFINE_RES_IRQ(gic_spi(169)),
};
};
static const struct resource sdhi0_resources[] __initconst = {
- DEFINE_RES_MEM_NAMED(0xee100000, 0x100, "SDHI0"),
+ DEFINE_RES_MEM(0xee100000, 0x100),
DEFINE_RES_IRQ(gic_spi(165)),
};
};
static const struct resource sdhi1_resources[] __initconst = {
- DEFINE_RES_MEM_NAMED(0xee120000, 0x100, "SDHI1"),
+ DEFINE_RES_MEM(0xee120000, 0x100),
DEFINE_RES_IRQ(gic_spi(166)),
};
*/
#include <linux/of_platform.h>
-#include <linux/pinctrl/machine.h>
#include <mach/common.h>
#include <mach/r8a7778.h>
#include <asm/mach/arch.h>
* see board-bock.c for checking detail of dip-switch
*/
-static const struct pinctrl_map bockw_pinctrl_map[] = {
- /* SCIF0 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
- "scif0_data_a", "scif0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
- "scif0_ctrl", "scif0"),
-};
-
#define FPGA 0x18200000
#define IRQ0MR 0x30
#define COMCTLR 0x101c
r8a7778_clock_init();
r8a7778_init_irq_extpin_dt(1);
-
- pinctrl_register_mappings(bockw_pinctrl_map,
- ARRAY_SIZE(bockw_pinctrl_map));
- r8a7778_pinmux_init();
r8a7778_add_dt_devices();
fpga = ioremap_nocache(FPGA, SZ_1M);
#include <linux/mmc/sh_mmcif.h>
#include <linux/mtd/partitions.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
#include <linux/platform_data/usb-rcar-phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/fixed.h>
+++ /dev/null
-/*
- * kzm9d board support
- *
- * Copyright (C) 2012 Renesas Solutions Corp.
- * Copyright (C) 2012 Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that 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, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/smsc911x.h>
-#include <mach/common.h>
-#include <mach/emev2.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-/* Dummy supplies, where voltage doesn't matter */
-static struct regulator_consumer_supply dummy_supplies[] = {
- REGULATOR_SUPPLY("vddvario", "smsc911x"),
- REGULATOR_SUPPLY("vdd33a", "smsc911x"),
-};
-
-/* Ether */
-static struct resource smsc911x_resources[] = {
- [0] = {
- .start = 0x20000000,
- .end = 0x2000ffff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = EMEV2_GPIO_IRQ(1),
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
- },
-};
-
-static struct smsc911x_platform_config smsc911x_platdata = {
- .flags = SMSC911X_USE_32BIT,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-};
-
-static struct platform_device smsc91x_device = {
- .name = "smsc911x",
- .id = -1,
- .dev = {
- .platform_data = &smsc911x_platdata,
- },
- .num_resources = ARRAY_SIZE(smsc911x_resources),
- .resource = smsc911x_resources,
-};
-
-static struct platform_device *kzm9d_devices[] __initdata = {
- &smsc91x_device,
-};
-
-void __init kzm9d_add_standard_devices(void)
-{
- regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-
- emev2_add_standard_devices();
-
- platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
-}
-
-static const char *kzm9d_boards_compat_dt[] __initdata = {
- "renesas,kzm9d",
- NULL,
-};
-
-DT_MACHINE_START(KZM9D_DT, "kzm9d")
- .smp = smp_ops(emev2_smp_ops),
- .map_io = emev2_map_io,
- .init_early = emev2_init_delay,
- .init_machine = kzm9d_add_standard_devices,
- .init_late = shmobile_init_late,
- .dt_compat = kzm9d_boards_compat_dt,
-MACHINE_END
#include <linux/init.h>
#include <linux/of_platform.h>
+#include <mach/rcar-gen2.h>
#include <mach/r8a7790.h>
#include <asm/mach/arch.h>
static void __init lager_add_standard_devices(void)
{
- /* clocks are setup late during boot in the case of DT */
r8a7790_clock_init();
-
r8a7790_add_dt_devices();
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char *lager_boards_compat_dt[] __initdata = {
};
static const struct resource mmcif1_resources[] __initconst = {
- DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"),
+ DEFINE_RES_MEM(0xee220000, 0x80),
DEFINE_RES_IRQ(gic_spi(170)),
};
#include <linux/leds.h>
#include <linux/dma-mapping.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
#include <linux/platform_data/gpio-rcar.h>
#include <linux/platform_data/rcar-du.h>
#include <linux/platform_data/usb-rcar-phy.h>
},
};
+/* VIN */
static struct rcar_vin_platform_data vin_platform_data __initdata = {
.flags = RCAR_VIN_BT656,
};
+#define MARZEN_VIN(idx) \
+static struct resource vin##idx##_resources[] __initdata = { \
+ DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
+ DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \
+}; \
+ \
+static struct platform_device_info vin##idx##_info __initdata = { \
+ .parent = &platform_bus, \
+ .name = "r8a7779-vin", \
+ .id = idx, \
+ .res = vin##idx##_resources, \
+ .num_res = ARRAY_SIZE(vin##idx##_resources), \
+ .dma_mask = DMA_BIT_MASK(32), \
+ .data = &vin_platform_data, \
+ .size_data = sizeof(vin_platform_data), \
+}
+MARZEN_VIN(1);
+MARZEN_VIN(3);
+
#define MARZEN_CAMERA(idx) \
static struct i2c_board_info camera##idx##_info = { \
I2C_BOARD_INFO("adv7180", 0x20 + (idx)), \
"sdhi0_ctrl", "sdhi0"),
PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
"sdhi0_cd", "sdhi0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
- "sdhi0_wp", "sdhi0"),
/* SMSC */
PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
"intc_irq1_b", "intc"),
r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
r8a7779_add_standard_devices();
- r8a7779_add_vin_device(1, &vin_platform_data);
- r8a7779_add_vin_device(3, &vin_platform_data);
+ platform_device_register_full(&vin1_info);
+ platform_device_register_full(&vin3_info);
platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
marzen_add_du_device();
}
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP clocks */
+ CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]),
+
+ /* ICK */
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]),
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
- CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+ CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
- CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+ CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]),
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
- CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
- CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]),
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
- CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
+ CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]),
CLKDEV_DEV_ID("e6550000.i2c", &mstp_clks[MSTP316]),
CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("fe1f0000.sound", &mstp_clks[MSTP328]),
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]),
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
- CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("e6850000.sd", &mstp_clks[MSTP314]),
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
- CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("e6860000.sd", &mstp_clks[MSTP313]),
CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
- CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]),
+ CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]),
CLKDEV_DEV_ID("r8a7740-gether", &mstp_clks[MSTP309]),
CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]),
CLKDEV_DEV_ID("renesas-tpu-pwm", &mstp_clks[MSTP304]),
CLKDEV_DEV_ID("e6600000.pwm", &mstp_clks[MSTP304]),
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
- CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]),
+ CLKDEV_DEV_ID("e6870000.sd", &mstp_clks[MSTP415]),
/* ICK */
CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
+ CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */
CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */
CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */
CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+ CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+ CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+ CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+ CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+ CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+ CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+ CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+ CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+ CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+ CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
+ CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
};
#define SMSTPCR7 0xe615014c
#define SMSTPCR8 0xe6150990
#define SMSTPCR9 0xe6150994
+#define SMSTPCR10 0xe6150998
#define SDCKCR 0xE6150074
#define SD2CKCR 0xE6150078
};
static struct clk main_clk = {
- /* .parent will be set r8a73a4_clock_init */
+ /* .parent will be set r8a7790_clock_init */
.ops = &followparent_clk_ops,
};
/* MSTP */
enum {
+ MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010,
+ MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005,
MSTP931, MSTP930, MSTP929, MSTP928,
+ MSTP917,
MSTP813,
MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
MSTP717, MSTP716,
+ MSTP704,
MSTP522,
MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
};
static struct clk mstp_clks[MSTP_NR] = {
- [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */
- [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */
- [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */
- [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */
+ [MSTP1015] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 15, 0), /* SSI0 */
+ [MSTP1014] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 14, 0), /* SSI1 */
+ [MSTP1013] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 13, 0), /* SSI2 */
+ [MSTP1012] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 12, 0), /* SSI3 */
+ [MSTP1011] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 11, 0), /* SSI4 */
+ [MSTP1010] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 10, 0), /* SSI5 */
+ [MSTP1009] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 9, 0), /* SSI6 */
+ [MSTP1008] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 8, 0), /* SSI7 */
+ [MSTP1007] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 7, 0), /* SSI8 */
+ [MSTP1006] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 6, 0), /* SSI9 */
+ [MSTP1005] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 5, 0), /* SSI ALL */
+ [MSTP931] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 31, 0), /* I2C0 */
+ [MSTP930] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 30, 0), /* I2C1 */
+ [MSTP929] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 29, 0), /* I2C2 */
+ [MSTP928] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 28, 0), /* I2C3 */
+ [MSTP917] = SH_CLK_MSTP32(&qspi_clk, SMSTPCR9, 17, 0), /* QSPI */
[MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
[MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
[MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
[MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
[MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
[MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
+ [MSTP704] = SH_CLK_MSTP32(&mp_clk, SMSTPCR7, 4, 0), /* HSUSB */
[MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
[MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
[MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]),
/* MSTP */
- CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
- CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
- CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
- CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
- CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
+ CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP1005]),
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
+ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP931]),
CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
+ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP930]),
CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
+ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP929]),
CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
+ CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP928]),
CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
+ CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
- CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
+ CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]),
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
- CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
- CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]),
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
- CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+ CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]),
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
- CLKDEV_DEV_ID("ee160000.sdhi", &mstp_clks[MSTP311]),
+ CLKDEV_DEV_ID("ee160000.sd", &mstp_clks[MSTP311]),
CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
- CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+ CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+ CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
+
+ /* ICK */
+ CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]),
+ CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
+ CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
+ CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
+ CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
+ CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
+ CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]),
+ CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]),
+ CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]),
+ CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP1012]),
+ CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP1011]),
+ CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP1010]),
+ CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP1009]),
+ CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP1008]),
+ CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP1007]),
+ CLKDEV_ICK_ID("ssi.9", "rcar_sound", &mstp_clks[MSTP1006]),
+
};
#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
break;
case MD(14):
- R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
+ R8A7790_CLOCK_ROOT(26 / 2, &extal_div2_clk, 200, 240, 122, 102);
break;
case MD(13) | MD(14):
- R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
+ R8A7790_CLOCK_ROOT(30 / 2, &extal_div2_clk, 172, 208, 106, 88);
break;
}
SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
+SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
static struct clk *main_clks[] = {
&extal_clk,
&rclk_clk,
&mp_clk,
&cp_clk,
+ &zx_clk,
};
/* MSTP */
enum {
- MSTP721, MSTP720,
+ MSTP813,
+ MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
MSTP719, MSTP718, MSTP715, MSTP714,
+ MSTP522,
MSTP216, MSTP207, MSTP206,
MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
MSTP124,
};
static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
+ [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
+ [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
+ [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
[MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
[MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
[MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */
[MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */
[MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */
[MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */
+ [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
[MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
[MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
[MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
CLKDEV_CON_ID("peripheral_clk", &hp_clk),
/* MSTP */
+ CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
+ CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
+ CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+ CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
+ CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
+ CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
};
#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
- CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
- CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
+ /* ICK */
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
&div6_reparent_clks[DIV6_HDMI]),
CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
- CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
- CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
- CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
- CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
+ CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
- CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
- CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
- CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
- CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */
+ CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */
CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */
CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+
+ /* ICK */
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
};
void __init sh73a0_clock_init(void)
extern void emev2_map_io(void);
extern void emev2_init_delay(void);
-extern void emev2_add_standard_devices(void);
extern void emev2_clock_init(void);
-
-#define EMEV2_GPIO_BASE 200
-#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
-
extern struct smp_operations emev2_smp_ops;
#endif /* __ASM_EMEV2_H__ */
#define __ASM_R8A7778_H__
#include <linux/sh_eth.h>
-#include <linux/platform_data/camera-rcar.h>
/* HPB-DMA slave IDs */
enum {
HPBDMA_SLAVE_DUMMY,
HPBDMA_SLAVE_SDHI0_TX,
HPBDMA_SLAVE_SDHI0_RX,
+ HPBDMA_SLAVE_SSI0_TX,
+ HPBDMA_SLAVE_SSI0_RX,
+ HPBDMA_SLAVE_SSI1_TX,
+ HPBDMA_SLAVE_SSI1_RX,
+ HPBDMA_SLAVE_SSI2_TX,
+ HPBDMA_SLAVE_SSI2_RX,
+ HPBDMA_SLAVE_SSI3_TX,
+ HPBDMA_SLAVE_SSI3_RX,
+ HPBDMA_SLAVE_SSI4_TX,
+ HPBDMA_SLAVE_SSI4_RX,
+ HPBDMA_SLAVE_SSI5_TX,
+ HPBDMA_SLAVE_SSI5_RX,
+ HPBDMA_SLAVE_SSI6_TX,
+ HPBDMA_SLAVE_SSI6_RX,
+ HPBDMA_SLAVE_SSI7_TX,
+ HPBDMA_SLAVE_SSI7_RX,
+ HPBDMA_SLAVE_SSI8_TX,
+ HPBDMA_SLAVE_SSI8_RX,
+ HPBDMA_SLAVE_HPBIF0_TX,
+ HPBDMA_SLAVE_HPBIF0_RX,
+ HPBDMA_SLAVE_HPBIF1_TX,
+ HPBDMA_SLAVE_HPBIF1_RX,
+ HPBDMA_SLAVE_HPBIF2_TX,
+ HPBDMA_SLAVE_HPBIF2_RX,
+ HPBDMA_SLAVE_HPBIF3_TX,
+ HPBDMA_SLAVE_HPBIF3_RX,
+ HPBDMA_SLAVE_HPBIF4_TX,
+ HPBDMA_SLAVE_HPBIF4_RX,
+ HPBDMA_SLAVE_HPBIF5_TX,
+ HPBDMA_SLAVE_HPBIF5_RX,
+ HPBDMA_SLAVE_HPBIF6_TX,
+ HPBDMA_SLAVE_HPBIF6_RX,
+ HPBDMA_SLAVE_HPBIF7_TX,
+ HPBDMA_SLAVE_HPBIF7_RX,
+ HPBDMA_SLAVE_HPBIF8_TX,
+ HPBDMA_SLAVE_HPBIF8_RX,
+ HPBDMA_SLAVE_USBFUNC_TX,
+ HPBDMA_SLAVE_USBFUNC_RX,
};
extern void r8a7778_add_standard_devices(void);
#include <linux/sh_clk.h>
#include <linux/pm_domain.h>
-#include <linux/sh_eth.h>
-#include <linux/platform_data/camera-rcar.h>
/* HPB-DMA slave IDs */
enum {
extern void r8a7779_add_early_devices(void);
extern void r8a7779_add_standard_devices(void);
extern void r8a7779_add_standard_devices_dt(void);
-extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
-extern void r8a7779_add_vin_device(int idx,
- struct rcar_vin_platform_data *pdata);
extern void r8a7779_init_late(void);
extern void r8a7779_clock_init(void);
extern void r8a7779_pinmux_init(void);
void r8a7791_add_standard_devices(void);
void r8a7791_add_dt_devices(void);
void r8a7791_clock_init(void);
+void r8a7791_pinmux_init(void);
void r8a7791_init_early(void);
extern struct smp_operations r8a7791_smp_ops;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/gpio-em.h>
#include <linux/of_platform.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/irqchip/arm-gic.h>
#include <mach/common.h>
#include <mach/emev2.h>
-#include <mach/irqs.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <asm/mach/time.h>
static struct map_desc emev2_io_desc[] __initdata = {
#ifdef CONFIG_SMP
iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
}
-/* UART */
-static struct resource uart0_resources[] = {
- DEFINE_RES_MEM(0xe1020000, 0x38),
- DEFINE_RES_IRQ(40),
-};
-
-static struct resource uart1_resources[] = {
- DEFINE_RES_MEM(0xe1030000, 0x38),
- DEFINE_RES_IRQ(41),
-};
-
-static struct resource uart2_resources[] = {
- DEFINE_RES_MEM(0xe1040000, 0x38),
- DEFINE_RES_IRQ(42),
-};
-
-static struct resource uart3_resources[] = {
- DEFINE_RES_MEM(0xe1050000, 0x38),
- DEFINE_RES_IRQ(43),
-};
-
-#define emev2_register_uart(idx) \
- platform_device_register_simple("serial8250-em", idx, \
- uart##idx##_resources, \
- ARRAY_SIZE(uart##idx##_resources))
-
-/* STI */
-static struct resource sti_resources[] = {
- DEFINE_RES_MEM(0xe0180000, 0x54),
- DEFINE_RES_IRQ(157),
-};
-
-#define emev2_register_sti() \
- platform_device_register_simple("em_sti", 0, \
- sti_resources, \
- ARRAY_SIZE(sti_resources))
-
-/* GIO */
-static struct gpio_em_config gio0_config = {
- .gpio_base = 0,
- .irq_base = EMEV2_GPIO_IRQ(0),
- .number_of_pins = 32,
-};
-
-static struct resource gio0_resources[] = {
- DEFINE_RES_MEM(0xe0050000, 0x2c),
- DEFINE_RES_MEM(0xe0050040, 0x20),
- DEFINE_RES_IRQ(99),
- DEFINE_RES_IRQ(100),
-};
-
-static struct gpio_em_config gio1_config = {
- .gpio_base = 32,
- .irq_base = EMEV2_GPIO_IRQ(32),
- .number_of_pins = 32,
-};
-
-static struct resource gio1_resources[] = {
- DEFINE_RES_MEM(0xe0050080, 0x2c),
- DEFINE_RES_MEM(0xe00500c0, 0x20),
- DEFINE_RES_IRQ(101),
- DEFINE_RES_IRQ(102),
-};
-
-static struct gpio_em_config gio2_config = {
- .gpio_base = 64,
- .irq_base = EMEV2_GPIO_IRQ(64),
- .number_of_pins = 32,
-};
-
-static struct resource gio2_resources[] = {
- DEFINE_RES_MEM(0xe0050100, 0x2c),
- DEFINE_RES_MEM(0xe0050140, 0x20),
- DEFINE_RES_IRQ(103),
- DEFINE_RES_IRQ(104),
-};
-
-static struct gpio_em_config gio3_config = {
- .gpio_base = 96,
- .irq_base = EMEV2_GPIO_IRQ(96),
- .number_of_pins = 32,
-};
-
-static struct resource gio3_resources[] = {
- DEFINE_RES_MEM(0xe0050180, 0x2c),
- DEFINE_RES_MEM(0xe00501c0, 0x20),
- DEFINE_RES_IRQ(105),
- DEFINE_RES_IRQ(106),
-};
-
-static struct gpio_em_config gio4_config = {
- .gpio_base = 128,
- .irq_base = EMEV2_GPIO_IRQ(128),
- .number_of_pins = 31,
-};
-
-static struct resource gio4_resources[] = {
- DEFINE_RES_MEM(0xe0050200, 0x2c),
- DEFINE_RES_MEM(0xe0050240, 0x20),
- DEFINE_RES_IRQ(107),
- DEFINE_RES_IRQ(108),
-};
-
-#define emev2_register_gio(idx) \
- platform_device_register_resndata(&platform_bus, "em_gio", \
- idx, gio##idx##_resources, \
- ARRAY_SIZE(gio##idx##_resources), \
- &gio##idx##_config, \
- sizeof(struct gpio_em_config))
-
-static struct resource pmu_resources[] = {
- DEFINE_RES_IRQ(152),
- DEFINE_RES_IRQ(153),
-};
-
-#define emev2_register_pmu() \
- platform_device_register_simple("arm-pmu", -1, \
- pmu_resources, \
- ARRAY_SIZE(pmu_resources))
-
-void __init emev2_add_standard_devices(void)
-{
- if (!IS_ENABLED(CONFIG_COMMON_CLK))
- emev2_clock_init();
-
- emev2_register_uart(0);
- emev2_register_uart(1);
- emev2_register_uart(2);
- emev2_register_uart(3);
- emev2_register_sti();
- emev2_register_gio(0);
- emev2_register_gio(1);
- emev2_register_gio(2);
- emev2_register_gio(3);
- emev2_register_gio(4);
- emev2_register_pmu();
-}
-
void __init emev2_init_delay(void)
{
shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
}
-#ifdef CONFIG_USE_OF
+static void __init emev2_add_standard_devices_dt(void)
+{
+#ifdef CONFIG_COMMON_CLK
+ of_clk_init(NULL);
+#else
+ emev2_clock_init();
+#endif
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
static const char *emev2_boards_compat_dt[] __initdata = {
"renesas,emev2",
.smp = smp_ops(emev2_smp_ops),
.map_io = emev2_map_io,
.init_early = emev2_init_delay,
+ .init_machine = emev2_add_standard_devices_dt,
+ .init_late = shmobile_init_late,
.dt_compat = emev2_boards_compat_dt,
MACHINE_END
-
-#endif /* CONFIG_USE_OF */
#include <linux/kernel.h>
#include <linux/of_platform.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/r7s72100.h>
sizeof(struct plat_sci_port));
}
+
+static struct sh_timer_config mtu2_0_platform_data __initdata = {
+ .name = "MTU2_0",
+ .timer_bit = 0,
+ .channel_offset = -0x80,
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] __initdata = {
+ DEFINE_RES_MEM(0xfcff0300, 0x27),
+ DEFINE_RES_IRQ(gic_iid(139)), /* MTU2 TGI0A */
+};
+
+#define r7s72100_register_mtu2(idx) \
+ platform_device_register_resndata(&platform_bus, "sh_mtu2", \
+ idx, mtu2_##idx##_resources, \
+ ARRAY_SIZE(mtu2_##idx##_resources), \
+ &mtu2_##idx##_platform_data, \
+ sizeof(struct sh_timer_config))
+
void __init r7s72100_add_dt_devices(void)
{
r7s72100_register_scif(SCIF0);
r7s72100_register_scif(SCIF5);
r7s72100_register_scif(SCIF6);
r7s72100_register_scif(SCIF7);
+ r7s72100_register_mtu2(0);
}
void __init r7s72100_init_early(void)
static struct resource dma_resources[] = {
DEFINE_RES_MEM(0xe6700020, 0x89e0),
- DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"),
+ DEFINE_RES_IRQ(gic_spi(220)),
{
/* IRQ for channels 0-19 */
.start = gic_spi(200),
#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */
#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
+#define HPBDMA_SSI(_id) \
+{ \
+ .id = HPBDMA_SLAVE_SSI## _id ##_TX, \
+ .addr = 0xffd91008 + (_id * 0x40), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DMDL | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = _id + (_id << 8), \
+ .dma_ch = (28 + _id), \
+}, { \
+ .id = HPBDMA_SLAVE_SSI## _id ##_RX, \
+ .addr = 0xffd9100c + (_id * 0x40), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SMDL | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = _id + (_id << 8), \
+ .dma_ch = (28 + _id), \
+}
+
+#define HPBDMA_HPBIF(_id) \
+{ \
+ .id = HPBDMA_SLAVE_HPBIF## _id ##_TX, \
+ .addr = 0xffda0000 + (_id * 0x1000), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DMDL | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = 0x1111, \
+ .dma_ch = (28 + _id), \
+}, { \
+ .id = HPBDMA_SLAVE_HPBIF## _id ##_RX, \
+ .addr = 0xffda0000 + (_id * 0x1000), \
+ .dcr = HPB_DMAE_DCR_CT | \
+ HPB_DMAE_DCR_DIP | \
+ HPB_DMAE_DCR_SMDL | \
+ HPB_DMAE_DCR_SPDS_32BIT | \
+ HPB_DMAE_DCR_DPDS_32BIT, \
+ .port = 0x1111, \
+ .dma_ch = (28 + _id), \
+}
+
static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
{
.id = HPBDMA_SLAVE_SDHI0_TX,
.port = 0x0D0C,
.flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
.dma_ch = 22,
+ }, {
+ .id = HPBDMA_SLAVE_USBFUNC_TX, /* for D0 */
+ .addr = 0xffe60018,
+ .dcr = HPB_DMAE_DCR_SPDS_32BIT |
+ HPB_DMAE_DCR_DMDL |
+ HPB_DMAE_DCR_DPDS_32BIT,
+ .port = 0x0000,
+ .dma_ch = 14,
+ }, {
+ .id = HPBDMA_SLAVE_USBFUNC_RX, /* for D1 */
+ .addr = 0xffe6001c,
+ .dcr = HPB_DMAE_DCR_SMDL |
+ HPB_DMAE_DCR_SPDS_32BIT |
+ HPB_DMAE_DCR_DPDS_32BIT,
+ .port = 0x0101,
+ .dma_ch = 15,
},
+
+ HPBDMA_SSI(0),
+ HPBDMA_SSI(1),
+ HPBDMA_SSI(2),
+ HPBDMA_SSI(3),
+ HPBDMA_SSI(4),
+ HPBDMA_SSI(5),
+ HPBDMA_SSI(6),
+ HPBDMA_SSI(7),
+ HPBDMA_SSI(8),
+
+ HPBDMA_HPBIF(0),
+ HPBDMA_HPBIF(1),
+ HPBDMA_HPBIF(2),
+ HPBDMA_HPBIF(3),
+ HPBDMA_HPBIF(4),
+ HPBDMA_HPBIF(5),
+ HPBDMA_HPBIF(6),
+ HPBDMA_HPBIF(7),
+ HPBDMA_HPBIF(8),
};
static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+ HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_TX), /* ch. 14 */
+ HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_RX), /* ch. 15 */
HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_TX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_RX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_TX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_RX), /* ch. 28 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_TX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_RX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_TX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_RX), /* ch. 29 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_TX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_RX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_TX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_RX), /* ch. 30 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_TX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_RX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_TX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_RX), /* ch. 31 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_TX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_RX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_TX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_RX), /* ch. 32 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_TX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_RX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_TX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_RX), /* ch. 33 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_TX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_RX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_TX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_RX), /* ch. 34 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_TX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_RX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_TX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_RX), /* ch. 35 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_TX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_RX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_TX), /* ch. 36 */
+ HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_RX), /* ch. 36 */
};
static struct hpb_dmae_pdata dma_platform_data __initdata = {
.resource = ohci1_resources,
};
-/* Ether */
-static struct resource ether_resources[] __initdata = {
- {
- .start = 0xfde00000,
- .end = 0xfde003ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = gic_iid(0xb4),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-#define R8A7779_VIN(idx) \
-static struct resource vin##idx##_resources[] __initdata = { \
- DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
- DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \
-}; \
- \
-static struct platform_device_info vin##idx##_info __initdata = { \
- .parent = &platform_bus, \
- .name = "r8a7779-vin", \
- .id = idx, \
- .res = vin##idx##_resources, \
- .num_res = ARRAY_SIZE(vin##idx##_resources), \
- .dma_mask = DMA_BIT_MASK(32), \
-}
-
-R8A7779_VIN(0);
-R8A7779_VIN(1);
-R8A7779_VIN(2);
-R8A7779_VIN(3);
-
-static struct platform_device_info *vin_info_table[] __initdata = {
- &vin0_info,
- &vin1_info,
- &vin2_info,
- &vin3_info,
-};
-
/* HPB-DMA */
/* Asynchronous mode register bits */
r8a7779_register_hpb_dmae();
}
-void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
-{
- platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
- ether_resources,
- ARRAY_SIZE(ether_resources),
- pdata, sizeof(*pdata));
-}
-
-void __init r8a7779_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
-{
- BUG_ON(id < 0 || id > 3);
-
- vin_info_table[id]->data = pdata;
- vin_info_table[id]->size_data = sizeof(*pdata);
-
- platform_device_register_full(vin_info_table[id]);
-}
-
/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
void __init __weak r8a7779_register_twd(void) { }
DEFINE_RES_MEM(0xe6060000, 0x250),
};
+#define r8a7790_register_pfc() \
+ platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, \
+ ARRAY_SIZE(pfc_resources))
+
#define R8A7790_GPIO(idx) \
static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \
&r8a7790_gpio##idx##_platform_data, \
sizeof(r8a7790_gpio##idx##_platform_data))
+static struct resource i2c_resources[] __initdata = {
+ /* I2C0 */
+ DEFINE_RES_MEM(0xE6508000, 0x40),
+ DEFINE_RES_IRQ(gic_spi(287)),
+ /* I2C1 */
+ DEFINE_RES_MEM(0xE6518000, 0x40),
+ DEFINE_RES_IRQ(gic_spi(288)),
+ /* I2C2 */
+ DEFINE_RES_MEM(0xE6530000, 0x40),
+ DEFINE_RES_IRQ(gic_spi(286)),
+ /* I2C3 */
+ DEFINE_RES_MEM(0xE6540000, 0x40),
+ DEFINE_RES_IRQ(gic_spi(290)),
+
+};
+
+#define r8a7790_register_i2c(idx) \
+ platform_device_register_simple( \
+ "i2c-rcar", idx, \
+ i2c_resources + (2 * idx), 2); \
+
void __init r8a7790_pinmux_init(void)
{
- platform_device_register_simple("pfc-r8a7790", -1, pfc_resources,
- ARRAY_SIZE(pfc_resources));
+ r8a7790_register_pfc();
r8a7790_register_gpio(0);
r8a7790_register_gpio(1);
r8a7790_register_gpio(2);
r8a7790_register_gpio(3);
r8a7790_register_gpio(4);
r8a7790_register_gpio(5);
+ r8a7790_register_i2c(0);
+ r8a7790_register_i2c(1);
+ r8a7790_register_i2c(2);
+ r8a7790_register_i2c(3);
}
#define SCIF_COMMON(scif_type, baseaddr, irq) \
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/of_platform.h>
+#include <linux/platform_data/gpio-rcar.h>
#include <linux/platform_data/irq-renesas-irqc.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <mach/rcar-gen2.h>
#include <asm/mach/arch.h>
+static const struct resource pfc_resources[] __initconst = {
+ DEFINE_RES_MEM(0xe6060000, 0x250),
+};
+
+#define r8a7791_register_pfc() \
+ platform_device_register_simple("pfc-r8a7791", -1, pfc_resources, \
+ ARRAY_SIZE(pfc_resources))
+
+#define R8A7791_GPIO(idx, base, nr) \
+static const struct resource r8a7791_gpio##idx##_resources[] __initconst = { \
+ DEFINE_RES_MEM((base), 0x50), \
+ DEFINE_RES_IRQ(gic_spi(4 + (idx))), \
+}; \
+ \
+static const struct gpio_rcar_config \
+r8a7791_gpio##idx##_platform_data __initconst = { \
+ .gpio_base = 32 * (idx), \
+ .irq_base = 0, \
+ .number_of_pins = (nr), \
+ .pctl_name = "pfc-r8a7791", \
+ .has_both_edge_trigger = 1, \
+}; \
+
+R8A7791_GPIO(0, 0xe6050000, 32);
+R8A7791_GPIO(1, 0xe6051000, 32);
+R8A7791_GPIO(2, 0xe6052000, 32);
+R8A7791_GPIO(3, 0xe6053000, 32);
+R8A7791_GPIO(4, 0xe6054000, 32);
+R8A7791_GPIO(5, 0xe6055000, 32);
+R8A7791_GPIO(6, 0xe6055400, 32);
+R8A7791_GPIO(7, 0xe6055800, 26);
+
+#define r8a7791_register_gpio(idx) \
+ platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \
+ r8a7791_gpio##idx##_resources, \
+ ARRAY_SIZE(r8a7791_gpio##idx##_resources), \
+ &r8a7791_gpio##idx##_platform_data, \
+ sizeof(r8a7791_gpio##idx##_platform_data))
+
+void __init r8a7791_pinmux_init(void)
+{
+ r8a7791_register_pfc();
+ r8a7791_register_gpio(0);
+ r8a7791_register_gpio(1);
+ r8a7791_register_gpio(2);
+ r8a7791_register_gpio(3);
+ r8a7791_register_gpio(4);
+ r8a7791_register_gpio(5);
+ r8a7791_register_gpio(6);
+ r8a7791_register_gpio(7);
+}
+
#define SCIF_COMMON(scif_type, baseaddr, irq) \
.type = scif_type, \
.mapbase = baseaddr, \
&irqc##idx##_data, \
sizeof(struct renesas_irqc_config))
+static const struct resource thermal_resources[] __initconst = {
+ DEFINE_RES_MEM(0xe61f0000, 0x14),
+ DEFINE_RES_MEM(0xe61f0100, 0x38),
+ DEFINE_RES_IRQ(gic_spi(69)),
+};
+
+#define r8a7791_register_thermal() \
+ platform_device_register_simple("rcar_thermal", -1, \
+ thermal_resources, \
+ ARRAY_SIZE(thermal_resources))
+
void __init r8a7791_add_dt_devices(void)
{
r8a7791_register_scif(SCIFA0);
{
r8a7791_add_dt_devices();
r8a7791_register_irqc(0);
+ r8a7791_register_thermal();
}
void __init r8a7791_init_early(void)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/clk/shmobile.h>
#include <linux/clocksource.h>
#include <linux/io.h>
#include <linux/kernel.h>
void __init rcar_gen2_timer_init(void)
{
-#ifdef CONFIG_ARM_ARCH_TIMER
+#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
u32 mode = rcar_gen2_read_mode_pins();
+#endif
+#ifdef CONFIG_ARM_ARCH_TIMER
void __iomem *base;
int extal_mhz = 0;
u32 freq;
/* Remap "armgcnt address map" space */
base = ioremap(0xe6080000, PAGE_SIZE);
- /* Update registers with correct frequency */
- iowrite32(freq, base + CNTFID0);
- asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+ /*
+ * Update the timer if it is either not running, or is not at the
+ * right frequency. The timer is only configurable in secure mode
+ * so this avoids an abort if the loader started the timer and
+ * entered the kernel in non-secure mode.
+ */
+
+ if ((ioread32(base + CNTCR) & 1) == 0 ||
+ ioread32(base + CNTFID0) != freq) {
+ /* Update registers with correct frequency */
+ iowrite32(freq, base + CNTFID0);
+ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+ /* make sure arch timer is started by setting bit 0 of CNTCR */
+ iowrite32(1, base + CNTCR);
+ }
- /* make sure arch timer is started by setting bit 0 of CNTCR */
- iowrite32(1, base + CNTCR);
iounmap(base);
#endif /* CONFIG_ARM_ARCH_TIMER */
+#ifdef CONFIG_COMMON_CLK
+ rcar_gen2_clocks_init(mode);
+#endif
clocksource_of_init();
}
};
static struct resource tmu00_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"),
+ [0] = DEFINE_RES_MEM(0xfff60008, 0xc),
[1] = {
.start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
.flags = IORESOURCE_IRQ,
};
static struct resource tmu01_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"),
+ [0] = DEFINE_RES_MEM(0xfff60014, 0xc),
[1] = {
.start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
.flags = IORESOURCE_IRQ,
};
static struct resource i2c0_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"),
+ [0] = DEFINE_RES_MEM(0xe6820000, 0x426),
[1] = {
.start = gic_spi(167),
.end = gic_spi(170),
};
static struct resource i2c1_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"),
+ [0] = DEFINE_RES_MEM(0xe6822000, 0x426),
[1] = {
.start = gic_spi(51),
.end = gic_spi(54),
};
static struct resource i2c2_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"),
+ [0] = DEFINE_RES_MEM(0xe6824000, 0x426),
[1] = {
.start = gic_spi(171),
.end = gic_spi(174),
};
static struct resource i2c3_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"),
+ [0] = DEFINE_RES_MEM(0xe6826000, 0x426),
[1] = {
.start = gic_spi(183),
.end = gic_spi(186),
};
static struct resource i2c4_resources[] = {
- [0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"),
+ [0] = DEFINE_RES_MEM(0xe6828000, 0x426),
[1] = {
.start = gic_spi(187),
.end = gic_spi(190),
/* an IPMMU module for ICB */
static struct resource ipmmu_resources[] = {
- DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"),
+ DEFINE_RES_MEM(0xfe951000, 0x100),
};
static const char * const ipmmu_dev_names[] = {
select GENERIC_CLOCKEVENTS
select GPIO_PL061 if GPIOLIB
select HAVE_ARM_SCU
+ select HAVE_ARM_TWD if SMP
select HAVE_SMP
select MFD_SYSCON
select SPARSE_IRQ
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
tegra_sku_id, tegra_cpu_process_id,
tegra_core_process_id);
}
-
-unsigned long long tegra_chip_uid(void)
-{
- unsigned long long lo, hi;
-
- lo = tegra_fuse_readl(FUSE_UID_LOW);
- hi = tegra_fuse_readl(FUSE_UID_HIGH);
- return (hi << 32ull) | lo;
-}
-EXPORT_SYMBOL(tegra_chip_uid);
#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>
}
/* 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)
goto err_clamp;
udelay(10);
- tegra_periph_reset_deassert(clk);
+ reset_control_deassert(rst);
return 0;
/* Requires call-back bindings. */
OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
/* Requires DMA bindings. */
+ OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", &mop500_sdi0_data),
+ OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", &mop500_sdi1_data),
+ OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", &mop500_sdi2_data),
+ OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", &mop500_sdi4_data),
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
"ux500-msp-i2s.0", &msp0_platform_data),
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
#define A15_BX_ADDR0 0x68
#define A7_BX_ADDR0 0x78
+/* SPC CPU/cluster reset statue */
+#define STANDBYWFI_STAT 0x3c
+#define STANDBYWFI_STAT_A15_CPU_MASK(cpu) (1 << (cpu))
+#define STANDBYWFI_STAT_A7_CPU_MASK(cpu) (1 << (3 + (cpu)))
+
/* SPC system config interface registers */
#define SYSCFG_WDATA 0x70
#define SYSCFG_RDATA 0x74
writel_relaxed(enable, info->baseaddr + pwdrn_reg);
}
+static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
+{
+ return cluster_is_a15(cluster) ?
+ STANDBYWFI_STAT_A15_CPU_MASK(cpu)
+ : STANDBYWFI_STAT_A7_CPU_MASK(cpu);
+}
+
+/**
+ * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+ *
+ * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ *
+ * @return: non-zero if and only if the specified CPU is in WFI
+ *
+ * Take care when interpreting the result of this function: a CPU might
+ * be in WFI temporarily due to idle, and is not necessarily safely
+ * parked.
+ */
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+{
+ int ret;
+ u32 mask = standbywfi_cpu_mask(cpu, cluster);
+
+ if (cluster >= MAX_CLUSTERS)
+ return 1;
+
+ ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
+
+ pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
+ __func__, STANDBYWFI_STAT, ret, mask);
+
+ return ret & mask;
+}
+
static int ve_spc_get_performance(int cluster, u32 *freq)
{
struct ve_spc_opp *opps = info->opps[cluster];
void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
void ve_spc_powerdown(u32 cluster, bool enable);
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
#endif
* published by the Free Software Foundation.
*/
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include "spc.h"
/* SCC conf registers */
+#define RESET_CTRL 0x018
+#define RESET_A15_NCORERESET(cpu) (1 << (2 + (cpu)))
+#define RESET_A7_NCORERESET(cpu) (1 << (16 + (cpu)))
+
#define A15_CONF 0x400
#define A7_CONF 0x500
#define SYS_INFO 0x700
#define SPC_BASE 0xb00
+static void __iomem *scc;
+
/*
* We can't use regular spinlocks. In the switcher case, it is possible
* for an outbound CPU to call power_down() after its inbound counterpart
tc2_pm_down(0);
}
+static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
+{
+ u32 mask = cluster ?
+ RESET_A7_NCORERESET(cpu)
+ : RESET_A15_NCORERESET(cpu);
+
+ return !(readl_relaxed(scc + RESET_CTRL) & mask);
+}
+
+#define POLL_MSEC 10
+#define TIMEOUT_MSEC 1000
+
+static int tc2_pm_power_down_finish(unsigned int cpu, unsigned int cluster)
+{
+ unsigned tries;
+
+ pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+ BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+
+ for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
+ /*
+ * Only examine the hardware state if the target CPU has
+ * caught up at least as far as tc2_pm_down():
+ */
+ if (ACCESS_ONCE(tc2_pm_use_count[cpu][cluster]) == 0) {
+ pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
+ __func__, cpu, cluster,
+ readl_relaxed(scc + RESET_CTRL));
+
+ /*
+ * We need the CPU to reach WFI, but the power
+ * controller may put the cluster in reset and
+ * power it off as soon as that happens, before
+ * we have a chance to see STANDBYWFI.
+ *
+ * So we need to check for both conditions:
+ */
+ if (tc2_core_in_reset(cpu, cluster) ||
+ ve_spc_cpu_in_wfi(cpu, cluster))
+ return 0; /* success: the CPU is halted */
+ }
+
+ /* Otherwise, wait and retry: */
+ msleep(POLL_MSEC);
+ }
+
+ return -ETIMEDOUT; /* timeout */
+}
+
static void tc2_pm_suspend(u64 residency)
{
unsigned int mpidr, cpu, cluster;
}
static const struct mcpm_platform_ops tc2_pm_power_ops = {
- .power_up = tc2_pm_power_up,
- .power_down = tc2_pm_power_down,
- .suspend = tc2_pm_suspend,
- .powered_up = tc2_pm_powered_up,
+ .power_up = tc2_pm_power_up,
+ .power_down = tc2_pm_power_down,
+ .power_down_finish = tc2_pm_power_down_finish,
+ .suspend = tc2_pm_suspend,
+ .powered_up = tc2_pm_powered_up,
};
static bool __init tc2_pm_usage_count_init(void)
static int __init tc2_pm_init(void)
{
int ret, irq;
- void __iomem *scc;
u32 a15_cluster_id, a7_cluster_id, sys_info;
struct device_node *np;
*
* DMA uncached mapping support.
*/
+#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/gfp.h>
u64 mask = (u64)DMA_BIT_MASK(32);
if (dev) {
+ unsigned long max_dma_pfn;
+
mask = dev->coherent_dma_mask;
/*
return 0;
}
+ max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+
/*
* If the mask allows for more memory than we can address,
* and we actually have that much memory, then fail the
*/
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
- dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) {
+ dma_to_pfn(dev, ~0) > max_dma_pfn) {
dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
mask);
dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
* fits within the allowable addresses which we can
* allocate.
*/
- if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) {
+ if (dma_to_pfn(dev, mask) < max_dma_pfn) {
dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
mask,
dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.length = len;
- info.low_limit = PAGE_SIZE;
+ info.low_limit = FIRST_USER_ADDRESS;
info.high_limit = mm->mmap_base;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
init_pud = pud_offset(init_pgd, 0);
init_pmd = pmd_offset(init_pud, 0);
init_pte = pte_offset_map(init_pmd, 0);
- set_pte_ext(new_pte, *init_pte, 0);
+ set_pte_ext(new_pte + 0, init_pte[0], 0);
+ set_pte_ext(new_pte + 1, init_pte[1], 0);
pte_unmap(init_pte);
pte_unmap(new_pte);
}
if (timer->posted)
return;
- if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) {
+ timer->posted = OMAP_TIMER_NONPOSTED;
+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0);
return;
+ }
__omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
OMAP_TIMER_CTRL_POSTED, 0);
#include <linux/platform_data/dma-mv_xor.h>
#include <linux/platform_data/usb-ehci-orion.h>
#include <mach/bridge-regs.h>
+#include <plat/common.h>
/* Create a clkdev entry for a given device/clk */
void __init orion_clkdev_add(const char *con_id, const char *dev_id,
/*****************************************************************************
* GE00
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
static struct resource orion_ge00_shared_resources[] = {
{
/*****************************************************************************
* GE01
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
static struct resource orion_ge01_shared_resources[] = {
{
/*****************************************************************************
* GE10
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
static struct resource orion_ge10_shared_resources[] = {
{
/*****************************************************************************
* GE11
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
static struct resource orion_ge11_shared_resources[] = {
{
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched_clock.h>
+#include <plat/time.h>
/*
* MBus bridge block registers.
static struct irqaction orion_timer_irq = {
.name = "orion_tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.handler = orion_timer_interrupt
};
if (!(fifocon & S3C2410_UFCON_RESETBOTH))
break;
}
+
+ uart_wr(S3C2410_UFCON, S3C2410_UFCON_FIFOMODE);
}
}
#else
struct rb_node rbnode_phys;
};
-rwlock_t p2m_lock;
+static rwlock_t p2m_lock;
struct rb_root phys_to_mach = RB_ROOT;
+EXPORT_SYMBOL_GPL(phys_to_mach);
static struct rb_root mach_to_phys = RB_ROOT;
static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new)
}
EXPORT_SYMBOL_GPL(__set_phys_to_machine);
-int p2m_init(void)
+static int p2m_init(void)
{
rwlock_init(&p2m_lock);
return 0;
/dts-v1/;
+/memreserve/ 0x80000000 0x00010000;
+
/ {
model = "Foundation-v8A";
compatible = "arm,foundation-aarch64", "arm,vexpress";
#define local_fiq_enable() asm("msr daifclr, #1" : : : "memory")
#define local_fiq_disable() asm("msr daifset, #1" : : : "memory")
+#define local_async_enable() asm("msr daifclr, #4" : : : "memory")
+#define local_async_disable() asm("msr daifset, #4" : : : "memory")
+
/*
* Save the current interrupt enable state.
*/
* Software defined PTE bits definition.
*/
#define PTE_VALID (_AT(pteval_t, 1) << 0)
-#define PTE_PROT_NONE (_AT(pteval_t, 1) << 2) /* only when !PTE_VALID */
-#define PTE_FILE (_AT(pteval_t, 1) << 3) /* only when !pte_present() */
+#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
+ /* bit 57 for PMD_SECT_SPLITTING */
+#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
/*
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
#define pgprot_noncached(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
#define pgprot_writecombine(prot) \
- __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE))
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
#define __HAVE_PHYS_MEM_ACCESS_PROT
/*
* Encode and decode a swap entry:
- * bits 0, 2: present (must both be zero)
- * bit 3: PTE_FILE
- * bits 4-8: swap type
- * bits 9-63: swap offset
+ * bits 0-1: present (must be zero)
+ * bit 2: PTE_FILE
+ * bits 3-8: swap type
+ * bits 9-57: swap offset
*/
-#define __SWP_TYPE_SHIFT 4
+#define __SWP_TYPE_SHIFT 3
#define __SWP_TYPE_BITS 6
+#define __SWP_OFFSET_BITS 49
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1)
#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
-#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
+#define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK)
#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
/*
* Encode and decode a file entry:
- * bits 0, 2: present (must both be zero)
- * bit 3: PTE_FILE
- * bits 4-63: file offset / PAGE_SIZE
+ * bits 0-1: present (must be zero)
+ * bit 2: PTE_FILE
+ * bits 3-57: file offset / PAGE_SIZE
*/
#define pte_file(pte) (pte_val(pte) & PTE_FILE)
-#define pte_to_pgoff(x) (pte_val(x) >> 4)
-#define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE)
+#define pte_to_pgoff(x) (pte_val(x) >> 3)
+#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE)
-#define PTE_FILE_MAX_BITS 60
+#define PTE_FILE_MAX_BITS 55
extern int kern_addr_valid(unsigned long addr);
int aarch32_break_handler(struct pt_regs *regs)
{
siginfo_t info;
- unsigned int instr;
+ u32 arm_instr;
+ u16 thumb_instr;
bool bp = false;
void __user *pc = (void __user *)instruction_pointer(regs);
if (compat_thumb_mode(regs)) {
/* get 16-bit Thumb instruction */
- get_user(instr, (u16 __user *)pc);
- if (instr == AARCH32_BREAK_THUMB2_LO) {
+ get_user(thumb_instr, (u16 __user *)pc);
+ thumb_instr = le16_to_cpu(thumb_instr);
+ if (thumb_instr == AARCH32_BREAK_THUMB2_LO) {
/* get second half of 32-bit Thumb-2 instruction */
- get_user(instr, (u16 __user *)(pc + 2));
- bp = instr == AARCH32_BREAK_THUMB2_HI;
+ get_user(thumb_instr, (u16 __user *)(pc + 2));
+ thumb_instr = le16_to_cpu(thumb_instr);
+ bp = thumb_instr == AARCH32_BREAK_THUMB2_HI;
} else {
- bp = instr == AARCH32_BREAK_THUMB;
+ bp = thumb_instr == AARCH32_BREAK_THUMB;
}
} else {
/* 32-bit ARM instruction */
- get_user(instr, (u32 __user *)pc);
- bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
+ get_user(arm_instr, (u32 __user *)pc);
+ arm_instr = le32_to_cpu(arm_instr);
+ bp = (arm_instr & ~0xf0000000) == AARCH32_BREAK_ARM;
}
if (!bp)
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_off
#endif
-#ifdef CONFIG_PREEMPT
- get_thread_info tsk
- ldr w24, [tsk, #TI_PREEMPT] // get preempt count
- add w0, w24, #1 // increment it
- str w0, [tsk, #TI_PREEMPT]
-#endif
+
irq_handler
+
#ifdef CONFIG_PREEMPT
- str w24, [tsk, #TI_PREEMPT] // restore preempt count
+ get_thread_info tsk
+ ldr w24, [tsk, #TI_PREEMPT] // restore preempt count
cbnz w24, 1f // preempt count != 0
ldr x0, [tsk, #TI_FLAGS] // get flags
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_off
#endif
- get_thread_info tsk
-#ifdef CONFIG_PREEMPT
- ldr w24, [tsk, #TI_PREEMPT] // get preempt count
- add w23, w24, #1 // increment it
- str w23, [tsk, #TI_PREEMPT]
-#endif
+
irq_handler
-#ifdef CONFIG_PREEMPT
- ldr w0, [tsk, #TI_PREEMPT]
- str w24, [tsk, #TI_PREEMPT]
- cmp w0, w23
- b.eq 1f
- mov x1, #0
- str x1, [x1] // BUG
-1:
-#endif
+ get_thread_info tsk
+
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on
#endif
for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i;
- void *reg;
+ compat_ulong_t reg;
switch (idx) {
case 15:
- reg = (void *)&task_pt_regs(target)->pc;
+ reg = task_pt_regs(target)->pc;
break;
case 16:
- reg = (void *)&task_pt_regs(target)->pstate;
+ reg = task_pt_regs(target)->pstate;
break;
case 17:
- reg = (void *)&task_pt_regs(target)->orig_x0;
+ reg = task_pt_regs(target)->orig_x0;
break;
default:
- reg = (void *)&task_pt_regs(target)->regs[idx];
+ reg = task_pt_regs(target)->regs[idx];
}
- ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
-
+ ret = copy_to_user(ubuf, ®, sizeof(reg));
if (ret)
break;
- else
- ubuf += sizeof(compat_ulong_t);
+
+ ubuf += sizeof(reg);
}
return ret;
for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i;
- void *reg;
+ compat_ulong_t reg;
+
+ ret = copy_from_user(®, ubuf, sizeof(reg));
+ if (ret)
+ return ret;
+
+ ubuf += sizeof(reg);
switch (idx) {
case 15:
- reg = (void *)&newregs.pc;
+ newregs.pc = reg;
break;
case 16:
- reg = (void *)&newregs.pstate;
+ newregs.pstate = reg;
break;
case 17:
- reg = (void *)&newregs.orig_x0;
+ newregs.orig_x0 = reg;
break;
default:
- reg = (void *)&newregs.regs[idx];
+ newregs.regs[idx] = reg;
}
- ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
-
- if (ret)
- goto out;
- else
- ubuf += sizeof(compat_ulong_t);
}
if (valid_user_regs(&newregs.user_regs))
else
ret = -EINVAL;
-out:
return ret;
}
void __init setup_arch(char **cmdline_p)
{
+ /*
+ * Unmask asynchronous aborts early to catch possible system errors.
+ */
+ local_async_enable();
+
setup_processor();
setup_machine_fdt(__fdt_pointer);
local_irq_enable();
local_fiq_enable();
+ local_async_enable();
/*
* OK, it's off to the idle thread for us
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_NS87415=y
-CONFIG_BLK_DEV_SIIMAGE=m
+CONFIG_PATA_SIL680=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_MODVERSIONS=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_PA8X00=y
-CONFIG_MLONGCALLS=y
CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_PLATFORM=y
CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_SIIMAGE=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
CONFIG_SCSI_SAS_LIBSAS=m
CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
+CONFIG_ATA=y
+CONFIG_PATA_SIL680=y
CONFIG_FUSION=y
CONFIG_FUSION_SPI=y
CONFIG_FUSION_SAS=y
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_KEYBOARD_HIL_OLD is not set
# CONFIG_KEYBOARD_HIL is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_CM109=m
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_PARKBD=m
CONFIG_SERIO_GSCPS2=m
CONFIG_SND_AD1889=m
# CONFIG_SND_USB is not set
# CONFIG_SND_GSC is not set
-CONFIG_HID_A4TECH=m
-CONFIG_HID_APPLE=m
-CONFIG_HID_BELKIN=m
-CONFIG_HID_CHERRY=m
-CONFIG_HID_CHICONY=m
-CONFIG_HID_CYPRESS=m
-CONFIG_HID_DRAGONRISE=m
-CONFIG_HID_EZKEY=m
-CONFIG_HID_KYE=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_TWINHAN=m
-CONFIG_HID_KENSINGTON=m
-CONFIG_HID_LOGITECH=m
-CONFIG_HID_LOGITECH_DJ=m
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
-CONFIG_HID_NTRIG=m
-CONFIG_HID_ORTEK=m
-CONFIG_HID_PANTHERLORD=m
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SUNPLUS=m
-CONFIG_HID_GREENASIA=m
-CONFIG_HID_SMARTJOYPLUS=m
-CONFIG_HID_TOPSEED=m
-CONFIG_HID_THRUSTMASTER=m
-CONFIG_HID_ZEROPLUS=m
-CONFIG_USB_HID=m
CONFIG_USB=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_PA8X00=y
-CONFIG_MLONGCALLS=y
CONFIG_64BIT=y
CONFIG_SMP=y
# CONFIG_COMPACTION is not set
CONFIG_IDE_GD_ATAPI=y
CONFIG_BLK_DEV_IDECD=m
CONFIG_BLK_DEV_NS87415=y
-CONFIG_BLK_DEV_SIIMAGE=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_DH=y
CONFIG_ATA=y
+CONFIG_PATA_SIL680=y
CONFIG_ATA_GENERIC=y
CONFIG_MD=y
CONFIG_MD_LINEAR=m
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_HIL_OLD is not set
# CONFIG_KEYBOARD_HIL is not set
-# CONFIG_INPUT_MOUSE is not set
+# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_MISC=y
CONFIG_SERIO_SERPORT=m
# CONFIG_HP_SDC is not set
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
-CONFIG_HID=m
CONFIG_HIDRAW=y
-CONFIG_HID_DRAGONRISE=m
-CONFIG_DRAGONRISE_FF=y
-CONFIG_HID_KYE=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_TWINHAN=m
-CONFIG_LOGITECH_FF=y
-CONFIG_LOGIRUMBLEPAD2_FF=y
-CONFIG_HID_NTRIG=m
-CONFIG_HID_PANTHERLORD=m
-CONFIG_PANTHERLORD_FF=y
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SONY=m
-CONFIG_HID_SUNPLUS=m
-CONFIG_HID_GREENASIA=m
-CONFIG_GREENASIA_FF=y
-CONFIG_HID_SMARTJOYPLUS=m
-CONFIG_SMARTJOYPLUS_FF=y
-CONFIG_HID_TOPSEED=m
-CONFIG_HID_THRUSTMASTER=m
-CONFIG_THRUSTMASTER_FF=y
-CONFIG_HID_ZEROPLUS=m
-CONFIG_ZEROPLUS_FF=y
-CONFIG_USB_HID=m
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y
CONFIG_USB=y
CONFIG_USB_MON=m
CONFIG_USB_WUSB_CBAF=m
CONFIG_USB_XHCI_HCD=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_R8A66597_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_WDM=m
-CONFIG_USB_TMC=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y
* This is used for 16550-compatible UARTs
*/
#define BASE_BAUD ( 1843200 / 16 )
-
-#define SERIAL_PORT_DFNS
* HP PARISC Hardware Database
* Access to this database is only possible during bootup
* so don't reference this table after starting the init process
+ *
+ * NOTE: Product names which are listed here and ends with a '?'
+ * are guessed. If you know the correct name, please let us know.
*/
static struct hp_hardware hp_hardware_list[] = {
{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
- {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
+ {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+ (rp5470)?"},
{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
{HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
{HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
{HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"},
+ {HPHW_NPROC,0x88B,0x4,0x91,"Crestone Peak Fast?"},
{HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"},
{HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"},
{HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"},
+ {HPHW_NPROC,0x892,0x4,0x91,"Mt. Hamilton Slow Mako+?"},
{HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"},
{HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"},
{HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"},
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */
.import $global$ /* forward declaration */
#endif /*!CONFIG_64BIT*/
- .export _stext,data /* Kernel want it this way! */
-_stext:
-ENTRY(stext)
+ENTRY(parisc_kernel_start)
.proc
.callinfo
.procend
#endif /* CONFIG_SMP */
-ENDPROC(stext)
+ENDPROC(parisc_kernel_start)
#ifndef CONFIG_64BIT
.section .data..read_mostly
return (unsigned long) mapping >> 8;
}
-static unsigned long get_shared_area(struct address_space *mapping,
- unsigned long addr, unsigned long len, unsigned long pgoff)
+static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff)
+{
+ struct address_space *mapping = filp ? filp->f_mapping : NULL;
+
+ return (get_offset(mapping) + pgoff) << PAGE_SHIFT;
+}
+
+static unsigned long get_shared_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff)
{
struct vm_unmapped_area_info info;
info.low_limit = PAGE_ALIGN(addr);
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & (SHMLBA - 1);
- info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
+ info.align_offset = shared_align_offset(filp, pgoff);
return vm_unmapped_area(&info);
}
return -ENOMEM;
if (flags & MAP_FIXED) {
if ((flags & MAP_SHARED) &&
- (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+ (addr - shared_align_offset(filp, pgoff)) & (SHMLBA - 1))
return -EINVAL;
return addr;
}
if (!addr)
addr = TASK_UNMAPPED_BASE;
- if (filp) {
- addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
- } else if(flags & MAP_SHARED) {
- addr = get_shared_area(NULL, addr, len, pgoff);
- } else {
+ if (filp || (flags & MAP_SHARED))
+ addr = get_shared_area(filp, addr, len, pgoff);
+ else
addr = get_unshared_area(addr, len);
- }
+
return addr;
}
}
/* Called from setup_arch to import the kernel unwind info */
-int unwind_init(void)
+int __init unwind_init(void)
{
long start, stop;
register unsigned long gp __asm__ ("r27");
e = find_unwind_entry(info->ip);
if (e == NULL) {
unsigned long sp;
- extern char _stext[], _etext[];
dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip);
break;
info->prev_ip = tmp;
sp = info->prev_sp;
- } while (info->prev_ip < (unsigned long)_stext ||
- info->prev_ip > (unsigned long)_etext);
+ } while (!kernel_text_address(info->prev_ip));
info->rp = 0;
do {
if (unwind_once(&info) < 0 || info.ip == 0)
return 0;
- if (!__kernel_text_address(info.ip)) {
+ if (!kernel_text_address(info.ip))
return 0;
- }
} while (info.ip && level--);
return info.ip;
* Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
* Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
* Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
- * Copyright (C) 2006 Helge Deller <deller@gmx.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Copyright (C) 2006-2013 Helge Deller <deller@gmx.de>
+ */
+
+/*
+ * Put page table entries (swapper_pg_dir) as the first thing in .bss. This
+ * will ensure that it has .bss alignment (PAGE_SIZE).
*/
+#define BSS_FIRST_SECTIONS *(.data..vm0.pmd) \
+ *(.data..vm0.pgd) \
+ *(.data..vm0.pte)
+
#include <asm-generic/vmlinux.lds.h>
+
/* needed for the processor specific cache alignment size */
#include <asm/cache.h>
#include <asm/page.h>
OUTPUT_ARCH(hppa:hppa2.0w)
#endif
-ENTRY(_stext)
+ENTRY(parisc_kernel_start)
#ifndef CONFIG_64BIT
jiffies = jiffies_64 + 4;
#else
{
. = KERNEL_BINARY_TEXT_START;
+ __init_begin = .;
+ HEAD_TEXT_SECTION
+ INIT_TEXT_SECTION(8)
+
+ . = ALIGN(PAGE_SIZE);
+ INIT_DATA_SECTION(PAGE_SIZE)
+ /* we have to discard exit text and such at runtime, not link time */
+ .exit.text :
+ {
+ EXIT_TEXT
+ }
+ .exit.data :
+ {
+ EXIT_DATA
+ }
+ PERCPU_SECTION(8)
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+ /* freed after init ends here */
+
_text = .; /* Text and read-only data */
- .head ALIGN(16) : {
- HEAD_TEXT
- } = 0
- .text ALIGN(16) : {
+ _stext = .;
+ .text ALIGN(PAGE_SIZE) : {
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
*(.lock.text) /* out-of-line lock text */
*(.gnu.warning)
}
- /* End of text section */
+ . = ALIGN(PAGE_SIZE);
_etext = .;
+ /* End of text section */
/* Start of data section */
_sdata = .;
- RODATA
+ RO_DATA_SECTION(8)
- /* writeable */
- /* Make sure this is page aligned so
- * that we can properly leave these
- * as writable
- */
- . = ALIGN(PAGE_SIZE);
- data_start = .;
+#ifdef CONFIG_64BIT
+ . = ALIGN(16);
+ /* Linkage tables */
+ .opd : {
+ *(.opd)
+ } PROVIDE (__gp = .);
+ .plt : {
+ *(.plt)
+ }
+ .dlt : {
+ *(.dlt)
+ }
+#endif
/* unwind info */
.PARISC.unwind : {
__stop___unwind = .;
}
- EXCEPTION_TABLE(16)
+ /* writeable */
+ /* Make sure this is page aligned so
+ * that we can properly leave these
+ * as writable
+ */
+ . = ALIGN(PAGE_SIZE);
+ data_start = .;
+
+ EXCEPTION_TABLE(8)
NOTES
/* Data */
_edata = .;
/* BSS */
- __bss_start = .;
- /* page table entries need to be PAGE_SIZE aligned */
- . = ALIGN(PAGE_SIZE);
- .data..vmpages : {
- *(.data..vm0.pmd)
- *(.data..vm0.pgd)
- *(.data..vm0.pte)
- }
- .bss : {
- *(.bss)
- *(COMMON)
- }
- __bss_stop = .;
-
-#ifdef CONFIG_64BIT
- . = ALIGN(16);
- /* Linkage tables */
- .opd : {
- *(.opd)
- } PROVIDE (__gp = .);
- .plt : {
- *(.plt)
- }
- .dlt : {
- *(.dlt)
- }
-#endif
+ BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8)
- /* reserve space for interrupt stack by aligning __init* to 16k */
- . = ALIGN(16384);
- __init_begin = .;
- INIT_TEXT_SECTION(16384)
- . = ALIGN(PAGE_SIZE);
- INIT_DATA_SECTION(16)
- /* we have to discard exit text and such at runtime, not link time */
- .exit.text :
- {
- EXIT_TEXT
- }
- .exit.data :
- {
- EXIT_DATA
- }
-
- PERCPU_SECTION(L1_CACHE_BYTES)
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
- /* freed after init ends here */
_end = . ;
STABS_DEBUG
#include <asm/sections.h>
extern int data_start;
+extern void parisc_kernel_start(void); /* Kernel entry point in head.S */
#if PT_NLEVELS == 3
/* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout
reserve_bootmem_node(NODE_DATA(0), 0UL,
(unsigned long)(PAGE0->mem_free +
PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT);
- reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
- (unsigned long)(_end - _text), BOOTMEM_DEFAULT);
+ reserve_bootmem_node(NODE_DATA(0), __pa(KERNEL_BINARY_TEXT_START),
+ (unsigned long)(_end - KERNEL_BINARY_TEXT_START),
+ BOOTMEM_DEFAULT);
reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
BOOTMEM_DEFAULT);
request_resource(&sysram_resources[0], &pdcdata_resource);
}
+static int __init parisc_text_address(unsigned long vaddr)
+{
+ static unsigned long head_ptr __initdata;
+
+ if (!head_ptr)
+ head_ptr = PAGE_MASK & (unsigned long)
+ dereference_function_descriptor(&parisc_kernel_start);
+
+ return core_kernel_text(vaddr) || vaddr == head_ptr;
+}
+
static void __init map_pages(unsigned long start_vaddr,
unsigned long start_paddr, unsigned long size,
pgprot_t pgprot, int force)
*/
if (force)
pte = __mk_pte(address, pgprot);
- else if (core_kernel_text(vaddr) &&
+ else if (parisc_text_address(vaddr) &&
address != fv_addr)
pte = __mk_pte(address, PAGE_KERNEL_EXEC);
else
GNUTARGET := powerpcle
MULTIPLEWORD := -mno-multiple
else
+ifeq ($(call cc-option-yn,-mbig-endian),y)
override CC += -mbig-endian
override AS += -mbig-endian
+endif
override LD += -EB
LDEMULATION := ppc
GNUTARGET := powerpc
CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6)
CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7)
+# Altivec option not allowed with e500mc64 in GCC.
+ifeq ($(CONFIG_ALTIVEC),y)
+E5500_CPU := -mcpu=powerpc64
+else
E5500_CPU := $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64)
+endif
CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU)
CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU))
tlu@2f000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x2f000 0x1000>;
- interupts = <61 2 >;
+ interrupts = <61 2>;
interrupt-parent = <&mpic>;
};
tlu@15000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x15000 0x1000>;
- interupts = <75 2>;
+ interrupts = <75 2>;
interrupt-parent = <&mpic>;
};
};
tlu@2f000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x2f000 0x1000>;
- interupts = <61 2 >;
+ interrupts = <61 2>;
interrupt-parent = <&mpic>;
};
tlu@15000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x15000 0x1000>;
- interupts = <75 2>;
+ interrupts = <75 2>;
interrupt-parent = <&mpic>;
};
};
tlu@2f000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x2f000 0x1000>;
- interupts = <61 2 >;
+ interrupts = <61 2>;
interrupt-parent = <&mpic>;
};
tlu@15000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x15000 0x1000>;
- interupts = <75 2>;
+ interrupts = <75 2>;
interrupt-parent = <&mpic>;
};
};
tlu@2f000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x2f000 0x1000>;
- interupts = <61 2 >;
+ interrupts = <61 2>;
interrupt-parent = <&mpic>;
};
tlu@15000 {
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
reg = <0x15000 0x1000>;
- interupts = <75 2>;
+ interrupts = <75 2>;
interrupt-parent = <&mpic>;
};
};
add r4,r4,r5
addi r4,r4,-1
divw r4,r4,r5 /* BUS ticks */
+#ifdef CONFIG_8xx
+1: mftbu r5
+ mftb r6
+ mftbu r7
+#else
1: mfspr r5, SPRN_TBRU
mfspr r6, SPRN_TBRL
mfspr r7, SPRN_TBRU
+#endif
cmpw 0,r5,r7
bne 1b /* Get [synced] base time */
addc r9,r6,r4 /* Compute end time */
addze r8,r5
+#ifdef CONFIG_8xx
+2: mftbu r5
+#else
2: mfspr r5, SPRN_TBRU
+#endif
cmpw 0,r5,r8
blt 2b
bgt 3f
+#ifdef CONFIG_8xx
+ mftb r6
+#else
mfspr r6, SPRN_TBRL
+#endif
cmpw 0,r6,r9
blt 2b
3: blr
unsigned long phys;
unsigned long virt_addr;
};
+extern struct vmemmap_backing *vmemmap_list;
/*
* Functions that deal with pagetables that could be at any level of
cmpwi dest,0; \
beq- 90b; \
END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#elif defined(CONFIG_8xx)
+#define MFTB(dest) mftb dest
#else
#define MFTB(dest) mfspr dest, SPRN_TBRL
#endif
#else /* __powerpc64__ */
+#if defined(CONFIG_8xx)
+#define mftbl() ({unsigned long rval; \
+ asm volatile("mftbl %0" : "=r" (rval)); rval;})
+#define mftbu() ({unsigned long rval; \
+ asm volatile("mftbu %0" : "=r" (rval)); rval;})
+#else
#define mftbl() ({unsigned long rval; \
asm volatile("mfspr %0, %1" : "=r" (rval) : \
"i" (SPRN_TBRL)); rval;})
#define mftbu() ({unsigned long rval; \
asm volatile("mfspr %0, %1" : "=r" (rval) : \
"i" (SPRN_TBRU)); rval;})
+#endif
#endif /* !__powerpc64__ */
#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
ret = 0;
__asm__ __volatile__(
+#ifdef CONFIG_8xx
+ "97: mftb %0\n"
+#else
"97: mfspr %0, %2\n"
+#endif
"99:\n"
".section __ftr_fixup,\"a\"\n"
".align 2\n"
" .long 0\n"
" .long 0\n"
".previous"
+#ifdef CONFIG_8xx
+ : "=r" (ret) : "i" (CPU_FTR_601));
+#else
: "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
+#endif
return ret;
#endif
}
#include <linux/ftrace.h>
#include <asm/machdep.h>
+#include <asm/pgalloc.h>
#include <asm/prom.h>
#include <asm/sections.h>
#ifndef CONFIG_NEED_MULTIPLE_NODES
VMCOREINFO_SYMBOL(contig_page_data);
#endif
+#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
+ VMCOREINFO_SYMBOL(vmemmap_list);
+ VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
+ VMCOREINFO_SYMBOL(mmu_psize_defs);
+ VMCOREINFO_STRUCT_SIZE(vmemmap_backing);
+ VMCOREINFO_OFFSET(vmemmap_backing, list);
+ VMCOREINFO_OFFSET(vmemmap_backing, phys);
+ VMCOREINFO_OFFSET(vmemmap_backing, virt_addr);
+ VMCOREINFO_STRUCT_SIZE(mmu_psize_def);
+ VMCOREINFO_OFFSET(mmu_psize_def, shift);
+#endif
}
/*
printk(KERN_WARNING "--------%s---------\n", label);
printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
list_for_each_entry(tmp_part, &nvram_partitions, partition) {
- printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n",
+ printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12.12s\n",
tmp_part->index, tmp_part->header.signature,
tmp_part->header.checksum, tmp_part->header.length,
tmp_part->header.name);
#endif /* CONFIG_ALTIVEC */
if (copy_fpr_to_user(&frame->mc_fregs, current))
return 1;
+
+ /*
+ * Clear the MSR VSX bit to indicate there is no valid state attached
+ * to this context, except in the specific case below where we set it.
+ */
+ msr &= ~MSR_VSX;
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
msr |= MSR_VSX;
- } else if (!ctx_has_vsx_region)
- /*
- * With a small context structure we can't hold the VSX
- * registers, hence clear the MSR value to indicate the state
- * was not saved.
- */
- msr &= ~MSR_VSX;
-
-
+ }
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
/* save spe registers */
flush_fp_to_thread(current);
/* copy fpr regs and fpscr */
err |= copy_fpr_to_user(&sc->fp_regs, current);
+
+ /*
+ * Clear the MSR VSX bit to indicate there is no valid state attached
+ * to this context, except in the specific case below where we set it.
+ */
+ msr &= ~MSR_VSX;
#ifdef CONFIG_VSX
/*
* Copy VSX low doubleword to local buffer for formatting,
lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
/* Get a stable TB value */
+#ifdef CONFIG_8xx
+2: mftbu r3
+ mftbl r4
+ mftbu r0
+#else
2: mfspr r3, SPRN_TBRU
mfspr r4, SPRN_TBRL
mfspr r0, SPRN_TBRU
+#endif
cmplw cr0,r3,r0
bne- 2b
struct hstate *hstate = hstate_file(vma->vm_file);
unsigned long tsize = huge_page_shift(hstate) - 10;
- __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
-
+ __flush_tlb_page(vma->vm_mm, vmaddr, tsize, 0);
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
#ifdef CONFIG_HUGETLB_PAGE
- if (is_vm_hugetlb_page(vma))
+ if (vma && is_vm_hugetlb_page(vma))
flush_hugetlb_page(vma, vmaddr);
#endif
endmenu
-config CPU_LITTLE_ENDIAN
- bool "Build little endian kernel"
- default n
+choice
+ prompt "Endianness selection"
+ default CPU_BIG_ENDIAN
help
This option selects whether a big endian or little endian kernel will
be built.
+config CPU_BIG_ENDIAN
+ bool "Build big endian kernel"
+ help
+ Build a big endian kernel.
+
+ If unsure, select this option.
+
+config CPU_LITTLE_ENDIAN
+ bool "Build little endian kernel"
+ help
+ Build a little endian kernel.
+
Note that if cross compiling a little endian kernel,
CROSS_COMPILE must point to a toolchain capable of targeting
little endian powerpc.
+
+endchoice
select GENERIC_CPU_DEVICES if !SMP
select GENERIC_FIND_FIRST_BIT
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_TIME_VSYSCALL_OLD
+ select GENERIC_TIME_VSYSCALL
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
select HAVE_ARCH_SECCOMP_FILTER
static char keylen_flag;
struct s390_aes_ctx {
- u8 iv[AES_BLOCK_SIZE];
u8 key[AES_MAX_KEY_SIZE];
long enc;
long dec;
struct s390_xts_ctx {
u8 key[32];
- u8 xts_param[16];
- struct pcc_param pcc;
+ u8 pcc_key[32];
long enc;
long dec;
int key_len;
return aes_set_key(tfm, in_key, key_len);
}
-static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
+static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
struct blkcipher_walk *walk)
{
+ struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
int ret = blkcipher_walk_virt(desc, walk);
unsigned int nbytes = walk->nbytes;
+ struct {
+ u8 iv[AES_BLOCK_SIZE];
+ u8 key[AES_MAX_KEY_SIZE];
+ } param;
if (!nbytes)
goto out;
- memcpy(param, walk->iv, AES_BLOCK_SIZE);
+ memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
+ memcpy(param.key, sctx->key, sctx->key_len);
do {
/* only use complete blocks */
unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
u8 *out = walk->dst.virt.addr;
u8 *in = walk->src.virt.addr;
- ret = crypt_s390_kmc(func, param, out, in, n);
+ ret = crypt_s390_kmc(func, ¶m, out, in, n);
if (ret < 0 || ret != n)
return -EIO;
nbytes &= AES_BLOCK_SIZE - 1;
ret = blkcipher_walk_done(desc, walk, nbytes);
} while ((nbytes = walk->nbytes));
- memcpy(walk->iv, param, AES_BLOCK_SIZE);
+ memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
out:
return ret;
return fallback_blk_enc(desc, dst, src, nbytes);
blkcipher_walk_init(&walk, dst, src, nbytes);
- return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
+ return cbc_aes_crypt(desc, sctx->enc, &walk);
}
static int cbc_aes_decrypt(struct blkcipher_desc *desc,
return fallback_blk_dec(desc, dst, src, nbytes);
blkcipher_walk_init(&walk, dst, src, nbytes);
- return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
+ return cbc_aes_crypt(desc, sctx->dec, &walk);
}
static struct crypto_alg cbc_aes_alg = {
xts_ctx->enc = KM_XTS_128_ENCRYPT;
xts_ctx->dec = KM_XTS_128_DECRYPT;
memcpy(xts_ctx->key + 16, in_key, 16);
- memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16);
+ memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16);
break;
case 48:
xts_ctx->enc = 0;
xts_ctx->enc = KM_XTS_256_ENCRYPT;
xts_ctx->dec = KM_XTS_256_DECRYPT;
memcpy(xts_ctx->key, in_key, 32);
- memcpy(xts_ctx->pcc.key, in_key + 32, 32);
+ memcpy(xts_ctx->pcc_key, in_key + 32, 32);
break;
default:
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
unsigned int nbytes = walk->nbytes;
unsigned int n;
u8 *in, *out;
- void *param;
+ struct pcc_param pcc_param;
+ struct {
+ u8 key[32];
+ u8 init[16];
+ } xts_param;
if (!nbytes)
goto out;
- memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block));
- memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit));
- memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts));
- memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak));
- param = xts_ctx->pcc.key + offset;
- ret = crypt_s390_pcc(func, param);
+ memset(pcc_param.block, 0, sizeof(pcc_param.block));
+ memset(pcc_param.bit, 0, sizeof(pcc_param.bit));
+ memset(pcc_param.xts, 0, sizeof(pcc_param.xts));
+ memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
+ memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
+ ret = crypt_s390_pcc(func, &pcc_param.key[offset]);
if (ret < 0)
return -EIO;
- memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16);
- param = xts_ctx->key + offset;
+ memcpy(xts_param.key, xts_ctx->key, 32);
+ memcpy(xts_param.init, pcc_param.xts, 16);
do {
/* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1);
out = walk->dst.virt.addr;
in = walk->src.virt.addr;
- ret = crypt_s390_km(func, param, out, in, n);
+ ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n);
if (ret < 0 || ret != n)
return -EIO;
: "memory", "cc");
}
+/*
+ * copy_page uses the mvcl instruction with 0xb0 padding byte in order to
+ * bypass caches when copying a page. Especially when copying huge pages
+ * this keeps L1 and L2 data caches alive.
+ */
static inline void copy_page(void *to, void *from)
{
- if (MACHINE_HAS_MVPG) {
- register unsigned long reg0 asm ("0") = 0;
- asm volatile(
- " mvpg %0,%1"
- : : "a" (to), "a" (from), "d" (reg0)
- : "memory", "cc");
- } else
- asm volatile(
- " mvc 0(256,%0),0(%1)\n"
- " mvc 256(256,%0),256(%1)\n"
- " mvc 512(256,%0),512(%1)\n"
- " mvc 768(256,%0),768(%1)\n"
- " mvc 1024(256,%0),1024(%1)\n"
- " mvc 1280(256,%0),1280(%1)\n"
- " mvc 1536(256,%0),1536(%1)\n"
- " mvc 1792(256,%0),1792(%1)\n"
- " mvc 2048(256,%0),2048(%1)\n"
- " mvc 2304(256,%0),2304(%1)\n"
- " mvc 2560(256,%0),2560(%1)\n"
- " mvc 2816(256,%0),2816(%1)\n"
- " mvc 3072(256,%0),3072(%1)\n"
- " mvc 3328(256,%0),3328(%1)\n"
- " mvc 3584(256,%0),3584(%1)\n"
- " mvc 3840(256,%0),3840(%1)\n"
- : : "a" (to), "a" (from) : "memory");
+ register void *reg2 asm ("2") = to;
+ register unsigned long reg3 asm ("3") = 0x1000;
+ register void *reg4 asm ("4") = from;
+ register unsigned long reg5 asm ("5") = 0xb0001000;
+ asm volatile(
+ " mvcl 2,4"
+ : "+d" (reg2), "+d" (reg3), "+d" (reg4), "+d" (reg5)
+ : : "memory", "cc");
}
#define clear_user_page(page, vaddr, pg) clear_page(page)
__u64 wtom_clock_nsec; /* 0x28 */
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
__u32 tz_dsttime; /* Type of dst correction 0x34 */
- __u32 ectg_available;
- __u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
+ __u32 ectg_available; /* ECTG instruction present 0x38 */
+ __u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
+ __u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
};
struct vdso_per_cpu_data {
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
- DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
+ DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
+ DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
/* constants used by the vdso */
return -EINVAL;
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
- regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+ regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
PGM_CHECK_DEFAULT /* 35 */
PGM_CHECK_DEFAULT /* 36 */
PGM_CHECK_DEFAULT /* 37 */
-PGM_CHECK_DEFAULT /* 38 */
+PGM_CHECK_64BIT(do_dat_exception) /* 38 */
PGM_CHECK_64BIT(do_dat_exception) /* 39 */
PGM_CHECK_64BIT(do_dat_exception) /* 3a */
PGM_CHECK_64BIT(do_dat_exception) /* 3b */
return -EINVAL;
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
- regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+ regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
(user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
/* Check for invalid user address space control. */
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
set_clock_comparator(S390_lowcore.clock_comparator);
}
-static int s390_next_ktime(ktime_t expires,
+static int s390_next_event(unsigned long delta,
struct clock_event_device *evt)
{
- struct timespec ts;
- u64 nsecs;
-
- ts.tv_sec = ts.tv_nsec = 0;
- monotonic_to_bootbased(&ts);
- nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
- do_div(nsecs, 125);
- S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
- /* Program the maximum value if we have an overflow (== year 2042) */
- if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
- S390_lowcore.clock_comparator = -1ULL;
+ S390_lowcore.clock_comparator = get_tod_clock() + delta;
set_clock_comparator(S390_lowcore.clock_comparator);
return 0;
}
cpu = smp_processor_id();
cd = &per_cpu(comparators, cpu);
cd->name = "comparator";
- cd->features = CLOCK_EVT_FEAT_ONESHOT |
- CLOCK_EVT_FEAT_KTIME;
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
cd->mult = 16777;
cd->shift = 12;
cd->min_delta_ns = 1;
cd->max_delta_ns = LONG_MAX;
cd->rating = 400;
cd->cpumask = cpumask_of(cpu);
- cd->set_next_ktime = s390_next_ktime;
+ cd->set_next_event = s390_next_event;
cd->set_mode = s390_set_mode;
clockevents_register_device(cd);
return &clocksource_tod;
}
-void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
- struct clocksource *clock, u32 mult)
+void update_vsyscall(struct timekeeper *tk)
{
- if (clock != &clocksource_tod)
+ u64 nsecps;
+
+ if (tk->clock != &clocksource_tod)
return;
/* Make userspace gettimeofday spin until we're done. */
++vdso_data->tb_update_count;
smp_wmb();
- vdso_data->xtime_tod_stamp = clock->cycle_last;
- vdso_data->xtime_clock_sec = wall_time->tv_sec;
- vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
- vdso_data->wtom_clock_sec = wtm->tv_sec;
- vdso_data->wtom_clock_nsec = wtm->tv_nsec;
- vdso_data->ntp_mult = mult;
+ vdso_data->xtime_tod_stamp = tk->clock->cycle_last;
+ vdso_data->xtime_clock_sec = tk->xtime_sec;
+ vdso_data->xtime_clock_nsec = tk->xtime_nsec;
+ vdso_data->wtom_clock_sec =
+ tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+ vdso_data->wtom_clock_nsec = tk->xtime_nsec +
+ + (tk->wall_to_monotonic.tv_nsec << tk->shift);
+ nsecps = (u64) NSEC_PER_SEC << tk->shift;
+ while (vdso_data->wtom_clock_nsec >= nsecps) {
+ vdso_data->wtom_clock_nsec -= nsecps;
+ vdso_data->wtom_clock_sec++;
+ }
+ vdso_data->tk_mult = tk->mult;
+ vdso_data->tk_shift = tk->shift;
smp_wmb();
++vdso_data->tb_update_count;
}
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,2f
ahi %r0,-1
-2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
+2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
lr %r2,%r0
- l %r0,__VDSO_NTP_MULT(%r5)
+ l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 3f
- a %r0,__VDSO_NTP_MULT(%r5)
+ a %r0,__VDSO_TK_MULT(%r5)
3: alr %r0,%r2
- srdl %r0,12
- al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
+ al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,4f
ahi %r0,1
-4: l %r2,__VDSO_XTIME_SEC+4(%r5)
- al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
+4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
al %r1,__VDSO_WTOM_NSEC+4(%r5)
brc 12,5f
ahi %r0,1
-5: al %r2,__VDSO_WTOM_SEC+4(%r5)
+5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
+ srdl %r0,0(%r2) /* >> tk->shift */
+ l %r2,__VDSO_XTIME_SEC+4(%r5)
+ al %r2,__VDSO_WTOM_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 1b
basr %r5,0
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,12f
ahi %r0,-1
-12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
+12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
lr %r2,%r0
- l %r0,__VDSO_NTP_MULT(%r5)
+ l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 13f
- a %r0,__VDSO_NTP_MULT(%r5)
+ a %r0,__VDSO_TK_MULT(%r5)
13: alr %r0,%r2
- srdl %r0,12
- al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
+ al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,14f
ahi %r0,1
-14: l %r2,__VDSO_XTIME_SEC+4(%r5)
+14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
+ srdl %r0,0(%r2) /* >> tk->shift */
+ l %r2,__VDSO_XTIME_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 11b
basr %r5,0
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,3f
ahi %r0,-1
-3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
+3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
st %r0,24(%r15)
- l %r0,__VDSO_NTP_MULT(%r5)
+ l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 4f
- a %r0,__VDSO_NTP_MULT(%r5)
+ a %r0,__VDSO_TK_MULT(%r5)
4: al %r0,24(%r15)
- srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,5f
5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 1b
+ l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
+ srdl %r0,0(%r4) /* >> tk->shift */
l %r4,24(%r15) /* get tv_sec from stack */
basr %r5,0
6: ltr %r0,%r0
tmll %r4,0x0001 /* pending update ? loop */
jnz 0b
stck 48(%r15) /* Store TOD clock */
+ lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
+ lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
+ alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
- srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
- alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
- lg %r0,__VDSO_XTIME_SEC(%r5)
- alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
- alg %r0,__VDSO_WTOM_SEC(%r5)
+ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
+ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
+ alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
+ srlg %r1,%r1,0(%r2) /* >> tk->shift */
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 0b
larl %r5,13f
tmll %r4,0x0001 /* pending update ? loop */
jnz 5b
stck 48(%r15) /* Store TOD clock */
+ lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
- srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
- alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
- lg %r0,__VDSO_XTIME_SEC(%r5)
+ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
+ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
+ srlg %r1,%r1,0(%r2) /* >> tk->shift */
+ lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 5b
larl %r5,13f
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
- srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
- alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
- lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
+ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
+ alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
+ lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
jne 0b
+ lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
+ srlg %r1,%r1,0(%r5) /* >> tk->shift */
larl %r5,5f
2: clg %r1,0(%r5)
jl 3f
* contains the (negative) exception code.
*/
#ifdef CONFIG_64BIT
+
static unsigned long follow_table(struct mm_struct *mm,
unsigned long address, int write)
{
unsigned long *table = (unsigned long *)__pa(mm->pgd);
+ if (unlikely(address > mm->context.asce_limit - 1))
+ return -0x38UL;
switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
case _ASCE_TYPE_REGION1:
table = table + ((address >> 53) & 0x7ff);
HEADER_ARCH := $(SUBARCH)
-# Additional ARCH settings for x86
-ifeq ($(SUBARCH),i386)
- HEADER_ARCH := x86
+ifneq ($(filter $(SUBARCH),x86 x86_64 i386),)
+ HEADER_ARCH := x86
endif
-ifeq ($(SUBARCH),x86_64)
- HEADER_ARCH := x86
+
+ifdef CONFIG_64BIT
KBUILD_CFLAGS += -mcmodel=large
endif
unsigned long return_address;
};
-static void print_stack_trace(unsigned long *sp, unsigned long bp)
+static void do_stack_trace(unsigned long *sp, unsigned long bp)
{
int reliable;
unsigned long addr;
}
printk(KERN_CONT "\n");
- print_stack_trace(sp, bp);
+ do_stack_trace(sp, bp);
}
KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
+ # Don't autogenerate SSE instructions
+ KBUILD_CFLAGS += -mno-sse
+
# Never want PIC in a 32-bit kernel, prevent breakage with GCC built
# with nonstandard options
KBUILD_CFLAGS += -fno-pic
KBUILD_AFLAGS += -m64
KBUILD_CFLAGS += -m64
+ # Don't autogenerate SSE instructions
+ KBUILD_CFLAGS += -mno-sse
+
# Use -mpreferred-stack-boundary=3 if supported.
- KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3)
+ KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
# FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
#
avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
+avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
+ $(comma)4)$(comma)%ymm2,yes,no)
-obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o
obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
#include <asm/cpu_device_id.h>
#include <asm/i387.h>
#include <asm/crypto/aes.h>
-#include <asm/crypto/ablk_helper.h>
+#include <crypto/ablk_helper.h>
#include <crypto/scatterwalk.h>
#include <crypto/internal/aead.h>
#include <linux/workqueue.h>
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/ctr.h>
#include <crypto/lrw.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <asm/crypto/camellia.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#define CAMELLIA_AESNI_PARALLEL_BLOCKS 16
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/ctr.h>
#include <crypto/lrw.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <asm/crypto/camellia.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#define CAMELLIA_AESNI_PARALLEL_BLOCKS 16
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/cast5.h>
#include <crypto/cryptd.h>
#include <crypto/ctr.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#define CAST5_PARALLEL_BLOCKS 16
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/cast6.h>
#include <crypto/cryptd.h>
#include <crypto/xts.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#define CAST6_PARALLEL_BLOCKS 8
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/ctr.h>
#include <crypto/lrw.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <asm/crypto/serpent-avx.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#define SERPENT_AVX2_PARALLEL_BLOCKS 16
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/serpent.h>
#include <crypto/cryptd.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <asm/crypto/serpent-avx.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
/* 8-way parallel cipher functions */
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/serpent.h>
#include <crypto/cryptd.h>
#include <crypto/lrw.h>
#include <crypto/xts.h>
#include <asm/crypto/serpent-sse2.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src)
/* allow AVX to override SSSE3, it's a little faster */
if (avx_usable()) {
#ifdef CONFIG_AS_AVX2
- if (boot_cpu_has(X86_FEATURE_AVX2))
+ if (boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_BMI2))
sha256_transform_asm = sha256_transform_rorx;
else
#endif
MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated");
MODULE_ALIAS("sha256");
-MODULE_ALIAS("sha384");
+MODULE_ALIAS("sha224");
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <crypto/twofish.h>
#include <crypto/cryptd.h>
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <asm/crypto/twofish.h>
-#include <asm/crypto/ablk_helper.h>
#include <asm/crypto/glue_helper.h>
#include <crypto/scatterwalk.h>
#include <linux/workqueue.h>
*/
static inline int atomic_sub_and_test(int i, atomic_t *v)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, i, "%0", "e");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, "er", i, "%0", "e");
}
/**
*/
static inline int atomic_add_negative(int i, atomic_t *v)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, i, "%0", "s");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, "er", i, "%0", "s");
}
/**
*/
static inline int atomic64_sub_and_test(long i, atomic64_t *v)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, i, "%0", "e");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, "er", i, "%0", "e");
}
/**
*/
static inline int atomic64_add_negative(long i, atomic64_t *v)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, i, "%0", "s");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, "er", i, "%0", "s");
}
/**
*/
static inline int test_and_set_bit(long nr, volatile unsigned long *addr)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, nr, "%0", "c");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c");
}
/**
*/
static inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, nr, "%0", "c");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c");
}
/**
*/
static inline int test_and_change_bit(long nr, volatile unsigned long *addr)
{
- GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, nr, "%0", "c");
+ GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c");
}
static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr)
*/
static inline int local_sub_and_test(long i, local_t *l)
{
- GEN_BINARY_RMWcc(_ASM_SUB, l->a.counter, i, "%0", "e");
+ GEN_BINARY_RMWcc(_ASM_SUB, l->a.counter, "er", i, "%0", "e");
}
/**
*/
static inline int local_add_negative(long i, local_t *l)
{
- GEN_BINARY_RMWcc(_ASM_ADD, l->a.counter, i, "%0", "s");
+ GEN_BINARY_RMWcc(_ASM_ADD, l->a.counter, "er", i, "%0", "s");
}
/**
#define GEN_UNARY_RMWcc(op, var, arg0, cc) \
__GEN_RMWcc(op " " arg0, var, cc)
-#define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \
- __GEN_RMWcc(op " %1, " arg0, var, cc, "er" (val))
+#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \
+ __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val))
#else /* !CC_HAVE_ASM_GOTO */
#define GEN_UNARY_RMWcc(op, var, arg0, cc) \
__GEN_RMWcc(op " " arg0, var, cc)
-#define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \
- __GEN_RMWcc(op " %2, " arg0, var, cc, "er" (val))
+#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \
+ __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val))
#endif /* CC_HAVE_ASM_GOTO */
--- /dev/null
+
+#include <asm/i387.h>
+
+/*
+ * may_use_simd - whether it is allowable at this time to issue SIMD
+ * instructions or access the SIMD register file
+ */
+static __must_check inline bool may_use_simd(void)
+{
+ return irq_fpu_usable();
+}
*/
DEFINE_IRQ_VECTOR_EVENT(irq_work);
+/*
+ * We must dis-allow sampling irq_work_exit() because perf event sampling
+ * itself can cause irq_work, which would lead to an infinite loop;
+ *
+ * 1) irq_work_exit happens
+ * 2) generates perf sample
+ * 3) generates irq_work
+ * 4) goto 1
+ */
+TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0);
+
/*
* call_function - called when entering/exiting a call function interrupt
* vector handler
{
/* Stop the cpus and apics */
#ifdef CONFIG_X86_IO_APIC
+ /*
+ * Disabling IO APIC before local APIC is a workaround for
+ * erratum AVR31 in "Intel Atom Processor C2000 Product Family
+ * Specification Update". In this situation, interrupts that target
+ * a Logical Processor whose Local APIC is either in the process of
+ * being hardware disabled or software disabled are neither delivered
+ * nor discarded. When this erratum occurs, the processor may hang.
+ *
+ * Even without the erratum, it still makes sense to quiet IO APIC
+ * before disabling Local APIC.
+ */
disable_IO_APIC();
#endif
efi_y += font->height;
}
- if (efi_y + font->height >= si->lfb_height) {
+ if (efi_y + font->height > si->lfb_height) {
u32 i;
efi_y -= font->height;
uint64_t v;
do {
- start = u64_stats_fetch_begin(&stat->syncp);
+ start = u64_stats_fetch_begin_bh(&stat->syncp);
v = stat->cnt;
- } while (u64_stats_fetch_retry(&stat->syncp, start));
+ } while (u64_stats_fetch_retry_bh(&stat->syncp, start));
return v;
}
struct blkg_rwstat tmp;
do {
- start = u64_stats_fetch_begin(&rwstat->syncp);
+ start = u64_stats_fetch_begin_bh(&rwstat->syncp);
tmp = *rwstat;
- } while (u64_stats_fetch_retry(&rwstat->syncp, start));
+ } while (u64_stats_fetch_retry_bh(&rwstat->syncp, start));
return tmp;
}
}
}
-static void bio_end_flush(struct bio *bio, int err)
-{
- if (err)
- clear_bit(BIO_UPTODATE, &bio->bi_flags);
- if (bio->bi_private)
- complete(bio->bi_private);
- bio_put(bio);
-}
-
/**
* blkdev_issue_flush - queue a flush
* @bdev: blockdev to issue flush for
int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
sector_t *error_sector)
{
- DECLARE_COMPLETION_ONSTACK(wait);
struct request_queue *q;
struct bio *bio;
int ret = 0;
return -ENXIO;
bio = bio_alloc(gfp_mask, 0);
- bio->bi_end_io = bio_end_flush;
bio->bi_bdev = bdev;
- bio->bi_private = &wait;
- bio_get(bio);
- submit_bio(WRITE_FLUSH, bio);
- wait_for_completion_io(&wait);
+ ret = submit_bio_wait(WRITE_FLUSH, bio);
/*
* The driver must store the error location in ->bi_sector, if
if (error_sector)
*error_sector = bio->bi_sector;
- if (!bio_flagged(bio, BIO_UPTODATE))
- ret = -EIO;
-
bio_put(bio);
return ret;
}
if (rq) {
blk_mq_rq_ctx_init(q, ctx, rq, rw);
break;
- } else if (!(gfp & __GFP_WAIT))
- break;
+ }
blk_mq_put_ctx(ctx);
+ if (!(gfp & __GFP_WAIT))
+ break;
+
__blk_mq_run_hw_queue(hctx);
blk_mq_wait_for_tags(hctx->tags);
} while (1);
return NULL;
rq = blk_mq_alloc_request_pinned(q, rw, gfp, reserved);
- blk_mq_put_ctx(rq->mq_ctx);
+ if (rq)
+ blk_mq_put_ctx(rq->mq_ctx);
return rq;
}
return NULL;
rq = blk_mq_alloc_request_pinned(q, rw, gfp, true);
- blk_mq_put_ctx(rq->mq_ctx);
+ if (rq)
+ blk_mq_put_ctx(rq->mq_ctx);
return rq;
}
EXPORT_SYMBOL(blk_mq_alloc_reserved_request);
blk_account_io_completion(rq, bytes);
+ blk_account_io_done(rq);
+
if (rq->end_io)
rq->end_io(rq, error);
else
blk_mq_free_request(rq);
-
- blk_account_io_done(rq);
}
void __blk_mq_end_io(struct request *rq, int error)
help
Quick & dirty crypto test module.
-config CRYPTO_ABLK_HELPER_X86
+config CRYPTO_ABLK_HELPER
tristate
- depends on X86
select CRYPTO_CRYPTD
config CRYPTO_GLUE_HELPER_X86
select CRYPTO_AES_X86_64 if 64BIT
select CRYPTO_AES_586 if !64BIT
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_ALGAPI
select CRYPTO_GLUE_HELPER_X86 if 64BIT
select CRYPTO_LRW
depends on CRYPTO
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_CAMELLIA_X86_64
select CRYPTO_LRW
depends on CRYPTO
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_CAMELLIA_X86_64
select CRYPTO_CAMELLIA_AESNI_AVX_X86_64
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_CAST_COMMON
select CRYPTO_CAST5
help
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_CAST_COMMON
select CRYPTO_CAST6
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_SERPENT
select CRYPTO_LRW
depends on X86 && !64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_SERPENT
select CRYPTO_LRW
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_SERPENT
select CRYPTO_LRW
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_SERPENT
select CRYPTO_SERPENT_AVX_X86_64
depends on X86 && 64BIT
select CRYPTO_ALGAPI
select CRYPTO_CRYPTD
- select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_ABLK_HELPER
select CRYPTO_GLUE_HELPER_X86
select CRYPTO_TWOFISH_COMMON
select CRYPTO_TWOFISH_X86_64
# Cryptographic API
#
+# memneq MUST be built with -Os or -O0 to prevent early-return optimizations
+# that will defeat memneq's actual purpose to prevent timing attacks.
+CFLAGS_REMOVE_memneq.o := -O1 -O2 -O3
+CFLAGS_memneq.o := -Os
+
obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-y := api.o cipher.o compress.o
+crypto-y := api.o cipher.o compress.o memneq.o
obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
obj-$(CONFIG_ASYNC_CORE) += async_tx/
obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
+obj-$(CONFIG_CRYPTO_ABLK_HELPER) += ablk_helper.o
#include <linux/crypto.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/hardirq.h>
#include <crypto/algapi.h>
#include <crypto/cryptd.h>
-#include <asm/i387.h>
-#include <asm/crypto/ablk_helper.h>
+#include <crypto/ablk_helper.h>
+#include <asm/simd.h>
int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
unsigned int key_len)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm);
- if (!irq_fpu_usable()) {
+ if (!may_use_simd()) {
struct ablkcipher_request *cryptd_req =
ablkcipher_request_ctx(req);
- memcpy(cryptd_req, req, sizeof(*req));
+ *cryptd_req = *req;
ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_ablkcipher_encrypt(cryptd_req);
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm);
- if (!irq_fpu_usable()) {
+ if (!may_use_simd()) {
struct ablkcipher_request *cryptd_req =
ablkcipher_request_ctx(req);
- memcpy(cryptd_req, req, sizeof(*req));
+ *cryptd_req = *req;
ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_ablkcipher_decrypt(cryptd_req);
#include <crypto/internal/skcipher.h>
#include <linux/cpumask.h>
#include <linux/err.h>
-#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "internal.h"
-static const char *skcipher_default_geniv __read_mostly;
-
struct ablkcipher_buffer {
struct list_head entry;
struct scatter_walk dst;
alg->cra_blocksize)
return "chainiv";
- return alg->cra_flags & CRYPTO_ALG_ASYNC ?
- "eseqiv" : skcipher_default_geniv;
+ return "eseqiv";
}
static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask)
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher);
-
-static int __init skcipher_module_init(void)
-{
- skcipher_default_geniv = num_possible_cpus() > 1 ?
- "eseqiv" : "chainiv";
- return 0;
-}
-
-static void skcipher_module_exit(void)
-{
-}
-
-module_init(skcipher_module_init);
-module_exit(skcipher_module_exit);
struct hash_ctx *ctx = ask->private;
int err;
+ if (flags & MSG_SENDPAGE_NOTLAST)
+ flags |= MSG_MORE;
+
lock_sock(sk);
sg_init_table(ctx->sgl.sg, 1);
sg_set_page(ctx->sgl.sg, page, size, offset);
struct skcipher_sg_list *sgl;
int err = -EINVAL;
+ if (flags & MSG_SENDPAGE_NOTLAST)
+ flags |= MSG_MORE;
+
lock_sock(sk);
if (!ctx->more && ctx->used)
goto unlock;
*/
if (byte_count < DEFAULT_BLK_SZ) {
empty_rbuf:
- for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
- ctx->rand_data_valid++) {
+ while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
*ptr = ctx->rand_data[ctx->rand_data_valid];
ptr++;
byte_count--;
+ ctx->rand_data_valid++;
if (byte_count == 0)
goto done;
}
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <crypto/algapi.h>
#include "public_key.h"
MODULE_LICENSE("GPL");
}
}
- if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
+ if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) {
kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
return -EBADMSG;
}
- if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
+ if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) {
kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
return -EKEYREJECTED;
}
#include <linux/asn1_decoder.h>
#include <keys/asymmetric-subtype.h>
#include <keys/asymmetric-parser.h>
-#include <keys/system_keyring.h>
#include <crypto/hash.h>
#include "asymmetric_keys.h"
#include "public_key.h"
#include "x509_parser.h"
-/*
- * Find a key in the given keyring by issuer and authority.
- */
-static struct key *x509_request_asymmetric_key(
- struct key *keyring,
- const char *signer, size_t signer_len,
- const char *authority, size_t auth_len)
-{
- key_ref_t key;
- char *id;
-
- /* Construct an identifier. */
- id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);
- if (!id)
- return ERR_PTR(-ENOMEM);
-
- memcpy(id, signer, signer_len);
- id[signer_len + 0] = ':';
- id[signer_len + 1] = ' ';
- memcpy(id + signer_len + 2, authority, auth_len);
- id[signer_len + 2 + auth_len] = 0;
-
- pr_debug("Look up: \"%s\"\n", id);
-
- key = keyring_search(make_key_ref(keyring, 1),
- &key_type_asymmetric, id);
- if (IS_ERR(key))
- pr_debug("Request for module key '%s' err %ld\n",
- id, PTR_ERR(key));
- kfree(id);
-
- if (IS_ERR(key)) {
- switch (PTR_ERR(key)) {
- /* Hide some search errors */
- case -EACCES:
- case -ENOTDIR:
- case -EAGAIN:
- return ERR_PTR(-ENOKEY);
- default:
- return ERR_CAST(key);
- }
- }
-
- pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
- return key_ref_to_ptr(key);
-}
-
/*
* Set up the signature parameters in an X.509 certificate. This involves
* digesting the signed data and extracting the signature.
}
EXPORT_SYMBOL_GPL(x509_check_signature);
-/*
- * Check the new certificate against the ones in the trust keyring. If one of
- * those is the signing key and validates the new certificate, then mark the
- * new certificate as being trusted.
- *
- * Return 0 if the new certificate was successfully validated, 1 if we couldn't
- * find a matching parent certificate in the trusted list and an error if there
- * is a matching certificate but the signature check fails.
- */
-static int x509_validate_trust(struct x509_certificate *cert,
- struct key *trust_keyring)
-{
- const struct public_key *pk;
- struct key *key;
- int ret = 1;
-
- key = x509_request_asymmetric_key(trust_keyring,
- cert->issuer, strlen(cert->issuer),
- cert->authority,
- strlen(cert->authority));
- if (!IS_ERR(key)) {
- pk = key->payload.data;
- ret = x509_check_signature(pk, cert);
- }
- return ret;
-}
-
/*
* Attempt to parse a data blob for a key as an X509 certificate.
*/
/* Check the signature on the key if it appears to be self-signed */
if (!cert->authority ||
strcmp(cert->fingerprint, cert->authority) == 0) {
- ret = x509_check_signature(cert->pub, cert); /* self-signed */
+ ret = x509_check_signature(cert->pub, cert);
if (ret < 0)
goto error_free_cert;
- } else {
- ret = x509_validate_trust(cert, system_trusted_keyring);
- if (!ret)
- prep->trusted = 1;
}
/* Propose a description */
aead_request_complete(req, err);
}
-static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
- unsigned int keylen)
+int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
+ unsigned int keylen)
{
- unsigned int authkeylen;
- unsigned int enckeylen;
- struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
- struct crypto_ahash *auth = ctx->auth;
- struct crypto_ablkcipher *enc = ctx->enc;
- struct rtattr *rta = (void *)key;
+ struct rtattr *rta = (struct rtattr *)key;
struct crypto_authenc_key_param *param;
- int err = -EINVAL;
if (!RTA_OK(rta, keylen))
- goto badkey;
+ return -EINVAL;
if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
- goto badkey;
+ return -EINVAL;
if (RTA_PAYLOAD(rta) < sizeof(*param))
- goto badkey;
+ return -EINVAL;
param = RTA_DATA(rta);
- enckeylen = be32_to_cpu(param->enckeylen);
+ keys->enckeylen = be32_to_cpu(param->enckeylen);
key += RTA_ALIGN(rta->rta_len);
keylen -= RTA_ALIGN(rta->rta_len);
- if (keylen < enckeylen)
- goto badkey;
+ if (keylen < keys->enckeylen)
+ return -EINVAL;
- authkeylen = keylen - enckeylen;
+ keys->authkeylen = keylen - keys->enckeylen;
+ keys->authkey = key;
+ keys->enckey = key + keys->authkeylen;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_authenc_extractkeys);
+
+static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+ struct crypto_ahash *auth = ctx->auth;
+ struct crypto_ablkcipher *enc = ctx->enc;
+ struct crypto_authenc_keys keys;
+ int err = -EINVAL;
+
+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
+ goto badkey;
crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) &
CRYPTO_TFM_REQ_MASK);
- err = crypto_ahash_setkey(auth, key, authkeylen);
+ err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) &
CRYPTO_TFM_RES_MASK);
crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) &
CRYPTO_TFM_REQ_MASK);
- err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
+ err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) &
CRYPTO_TFM_RES_MASK);
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;
if (!err) {
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
- struct ablkcipher_request *abreq = aead_request_ctx(areq);
- u8 *iv = (u8 *)(abreq + 1) +
- crypto_ablkcipher_reqsize(ctx->enc);
+ struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq);
+ struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
+ + ctx->reqoff);
+ u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc);
err = crypto_authenc_genicv(areq, iv, 0);
}
ihash = ohash + authsize;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
}
static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *key,
unsigned int keylen)
{
- unsigned int authkeylen;
- unsigned int enckeylen;
struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
struct crypto_ahash *auth = ctx->auth;
struct crypto_ablkcipher *enc = ctx->enc;
- struct rtattr *rta = (void *)key;
- struct crypto_authenc_key_param *param;
+ struct crypto_authenc_keys keys;
int err = -EINVAL;
- if (!RTA_OK(rta, keylen))
+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
goto badkey;
- if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
- goto badkey;
- if (RTA_PAYLOAD(rta) < sizeof(*param))
- goto badkey;
-
- param = RTA_DATA(rta);
- enckeylen = be32_to_cpu(param->enckeylen);
-
- key += RTA_ALIGN(rta->rta_len);
- keylen -= RTA_ALIGN(rta->rta_len);
-
- if (keylen < enckeylen)
- goto badkey;
-
- authkeylen = keylen - enckeylen;
crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) &
CRYPTO_TFM_REQ_MASK);
- err = crypto_ahash_setkey(auth, key, authkeylen);
+ err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
crypto_aead_set_flags(authenc_esn, crypto_ahash_get_flags(auth) &
CRYPTO_TFM_RES_MASK);
crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc_esn) &
CRYPTO_TFM_REQ_MASK);
- err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
+ err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
crypto_aead_set_flags(authenc_esn, crypto_ablkcipher_get_flags(enc) &
CRYPTO_TFM_RES_MASK);
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;
ihash = ohash + authsize;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
}
static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
}
/* compute plaintext into mac */
- get_data_to_compute(cipher, pctx, plain, cryptlen);
+ if (cryptlen)
+ get_data_to_compute(cipher, pctx, plain, cryptlen);
out:
return err;
if (!err) {
err = crypto_ccm_auth(req, req->dst, cryptlen);
- if (!err && memcmp(pctx->auth_tag, pctx->odata, authsize))
+ if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize))
err = -EBADMSG;
}
aead_request_complete(req, err);
return err;
/* verify */
- if (memcmp(authtag, odata, authsize))
+ if (crypto_memneq(authtag, odata, authsize))
return -EBADMSG;
return err;
crypto_xor(auth_tag, iauth_tag, 16);
scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
- return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
}
static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
--- /dev/null
+/*
+ * Constant-time equality testing of memory regions.
+ *
+ * Authors:
+ *
+ * James Yonan <james@openvpn.net>
+ * Daniel Borkmann <dborkman@redhat.com>
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of OpenVPN Technologies nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <crypto/algapi.h>
+
+#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
+
+/* Generic path for arbitrary size */
+static inline unsigned long
+__crypto_memneq_generic(const void *a, const void *b, size_t size)
+{
+ unsigned long neq = 0;
+
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ while (size >= sizeof(unsigned long)) {
+ neq |= *(unsigned long *)a ^ *(unsigned long *)b;
+ a += sizeof(unsigned long);
+ b += sizeof(unsigned long);
+ size -= sizeof(unsigned long);
+ }
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+ while (size > 0) {
+ neq |= *(unsigned char *)a ^ *(unsigned char *)b;
+ a += 1;
+ b += 1;
+ size -= 1;
+ }
+ return neq;
+}
+
+/* Loop-free fast-path for frequently used 16-byte size */
+static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
+{
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ if (sizeof(unsigned long) == 8)
+ return ((*(unsigned long *)(a) ^ *(unsigned long *)(b))
+ | (*(unsigned long *)(a+8) ^ *(unsigned long *)(b+8)));
+ else if (sizeof(unsigned int) == 4)
+ return ((*(unsigned int *)(a) ^ *(unsigned int *)(b))
+ | (*(unsigned int *)(a+4) ^ *(unsigned int *)(b+4))
+ | (*(unsigned int *)(a+8) ^ *(unsigned int *)(b+8))
+ | (*(unsigned int *)(a+12) ^ *(unsigned int *)(b+12)));
+ else
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+ return ((*(unsigned char *)(a) ^ *(unsigned char *)(b))
+ | (*(unsigned char *)(a+1) ^ *(unsigned char *)(b+1))
+ | (*(unsigned char *)(a+2) ^ *(unsigned char *)(b+2))
+ | (*(unsigned char *)(a+3) ^ *(unsigned char *)(b+3))
+ | (*(unsigned char *)(a+4) ^ *(unsigned char *)(b+4))
+ | (*(unsigned char *)(a+5) ^ *(unsigned char *)(b+5))
+ | (*(unsigned char *)(a+6) ^ *(unsigned char *)(b+6))
+ | (*(unsigned char *)(a+7) ^ *(unsigned char *)(b+7))
+ | (*(unsigned char *)(a+8) ^ *(unsigned char *)(b+8))
+ | (*(unsigned char *)(a+9) ^ *(unsigned char *)(b+9))
+ | (*(unsigned char *)(a+10) ^ *(unsigned char *)(b+10))
+ | (*(unsigned char *)(a+11) ^ *(unsigned char *)(b+11))
+ | (*(unsigned char *)(a+12) ^ *(unsigned char *)(b+12))
+ | (*(unsigned char *)(a+13) ^ *(unsigned char *)(b+13))
+ | (*(unsigned char *)(a+14) ^ *(unsigned char *)(b+14))
+ | (*(unsigned char *)(a+15) ^ *(unsigned char *)(b+15)));
+}
+
+/* Compare two areas of memory without leaking timing information,
+ * and with special optimizations for common sizes. Users should
+ * not call this function directly, but should instead use
+ * crypto_memneq defined in crypto/algapi.h.
+ */
+noinline unsigned long __crypto_memneq(const void *a, const void *b,
+ size_t size)
+{
+ switch (size) {
+ case 16:
+ return __crypto_memneq_16(a, b);
+ default:
+ return __crypto_memneq_generic(a, b, size);
+ }
+}
+EXPORT_SYMBOL(__crypto_memneq);
+
+#endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */
ret += tcrypt_test("cmac(des3_ede)");
break;
+ case 155:
+ ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))");
+ break;
+
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32);
goto out;
}
- sg_init_one(&sg[0], input,
- template[i].ilen + (enc ? authsize : 0));
-
if (diff_dst) {
output = xoutbuf[0];
output += align_offset;
+ sg_init_one(&sg[0], input, template[i].ilen);
sg_init_one(&sgout[0], output,
+ template[i].rlen);
+ } else {
+ sg_init_one(&sg[0], input,
template[i].ilen +
(enc ? authsize : 0));
- } else {
output = input;
}
memcpy(q, template[i].input + temp,
template[i].tap[k]);
- n = template[i].tap[k];
- if (k == template[i].np - 1 && enc)
- n += authsize;
- if (offset_in_page(q) + n < PAGE_SIZE)
- q[n] = 0;
-
sg_set_buf(&sg[k], q, template[i].tap[k]);
if (diff_dst) {
offset_in_page(IDX[k]);
memset(q, 0, template[i].tap[k]);
- if (offset_in_page(q) + n < PAGE_SIZE)
- q[n] = 0;
sg_set_buf(&sgout[k], q,
template[i].tap[k]);
}
+ n = template[i].tap[k];
+ if (k == template[i].np - 1 && enc)
+ n += authsize;
+ if (offset_in_page(q) + n < PAGE_SIZE)
+ q[n] = 0;
+
temp += template[i].tap[k];
}
goto out;
}
- sg[k - 1].length += authsize;
-
if (diff_dst)
sgout[k - 1].length += authsize;
+ else
+ sg[k - 1].length += authsize;
}
sg_init_table(asg, template[i].anp);
obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
-obj-$(CONFIG_ARCH_SHMOBILE) += sh/
+obj-$(CONFIG_ARCH_SHMOBILE_LEGACY) += sh/
ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
obj-y += clocksource/
endif
struct acpi_buffer *output_buffer);
acpi_status
-acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
struct acpi_buffer *output_buffer);
acpi_status
u32 aml_buffer_length, acpi_size * size_needed);
acpi_status
-acpi_rs_get_aml_length(struct acpi_resource *linked_list_buffer,
- acpi_size * size_needed);
+acpi_rs_get_aml_length(struct acpi_resource *resource_list,
+ acpi_size resource_list_size, acpi_size * size_needed);
acpi_status
acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
void acpi_ns_delete_node(struct acpi_namespace_node *node)
{
union acpi_operand_object *obj_desc;
+ union acpi_operand_object *next_desc;
ACPI_FUNCTION_NAME(ns_delete_node);
acpi_ns_detach_object(node);
/*
- * Delete an attached data object if present (an object that was created
- * and attached via acpi_attach_data). Note: After any normal object is
- * detached above, the only possible remaining object is a data object.
+ * Delete an attached data object list if present (objects that were
+ * attached via acpi_attach_data). Note: After any normal object is
+ * detached above, the only possible remaining object(s) are data
+ * objects, in a linked list.
*/
obj_desc = node->object;
- if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
+ while (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
/* Invoke the attached data deletion handler if present */
obj_desc->data.handler(node, obj_desc->data.pointer);
}
+ next_desc = obj_desc->common.next_object;
acpi_ut_remove_reference(obj_desc);
+ obj_desc = next_desc;
+ }
+
+ /* Special case for the statically allocated root node */
+
+ if (node == acpi_gbl_root_node) {
+ return;
}
/* Now we can delete the node */
void acpi_ns_terminate(void)
{
- union acpi_operand_object *obj_desc;
+ acpi_status status;
ACPI_FUNCTION_TRACE(ns_terminate);
/*
- * 1) Free the entire namespace -- all nodes and objects
- *
- * Delete all object descriptors attached to namepsace nodes
+ * Free the entire namespace -- all nodes and all objects
+ * attached to the nodes
*/
acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
- /* Detach any objects attached to the root */
+ /* Delete any objects attached to the root node */
- obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
- if (obj_desc) {
- acpi_ns_detach_object(acpi_gbl_root_node);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_VOID;
}
+ acpi_ns_delete_node(acpi_gbl_root_node);
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
return_VOID;
}
* FUNCTION: acpi_rs_get_aml_length
*
* PARAMETERS: resource - Pointer to the resource linked list
+ * resource_list_size - Size of the resource linked list
* size_needed - Where the required size is returned
*
* RETURN: Status
******************************************************************************/
acpi_status
-acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
+acpi_rs_get_aml_length(struct acpi_resource *resource,
+ acpi_size resource_list_size, acpi_size * size_needed)
{
acpi_size aml_size_needed = 0;
+ struct acpi_resource *resource_end;
acpi_rs_length total_size;
ACPI_FUNCTION_TRACE(rs_get_aml_length);
/* Traverse entire list of internal resource descriptors */
- while (resource) {
+ resource_end =
+ ACPI_ADD_PTR(struct acpi_resource, resource, resource_list_size);
+ while (resource < resource_end) {
/* Validate the descriptor type */
*
* FUNCTION: acpi_rs_create_aml_resources
*
- * PARAMETERS: linked_list_buffer - Pointer to the resource linked list
- * output_buffer - Pointer to the user's buffer
+ * PARAMETERS: resource_list - Pointer to the resource list buffer
+ * output_buffer - Where the AML buffer is returned
*
* RETURN: Status AE_OK if okay, else a valid acpi_status code.
* If the output_buffer is too small, the error will be
* AE_BUFFER_OVERFLOW and output_buffer->Length will point
* to the size buffer needed.
*
- * DESCRIPTION: Takes the linked list of device resources and
- * creates a bytestream to be used as input for the
- * _SRS control method.
+ * DESCRIPTION: Converts a list of device resources to an AML bytestream
+ * to be used as input for the _SRS control method.
*
******************************************************************************/
acpi_status
-acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
struct acpi_buffer *output_buffer)
{
acpi_status status;
ACPI_FUNCTION_TRACE(rs_create_aml_resources);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n",
- linked_list_buffer));
+ /* Params already validated, no need to re-validate here */
- /*
- * Params already validated, so we don't re-validate here
- *
- * Pass the linked_list_buffer into a module that calculates
- * the buffer size needed for the byte stream.
- */
- status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
+ resource_list->pointer));
+
+ /* Get the buffer size needed for the AML byte stream */
+
+ status = acpi_rs_get_aml_length(resource_list->pointer,
+ resource_list->length,
+ &aml_size_needed);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
(u32)aml_size_needed, acpi_format_exception(status)));
/* Do the conversion */
- status =
- acpi_rs_convert_resources_to_aml(linked_list_buffer,
- aml_size_needed,
- output_buffer->pointer);
+ status = acpi_rs_convert_resources_to_aml(resource_list->pointer,
+ aml_size_needed,
+ output_buffer->pointer);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
* Convert the linked list into a byte stream
*/
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
+ status = acpi_rs_create_aml_resources(in_buffer, &buffer);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
}
acpi_gbl_prev_thread_id = thread_id;
+ acpi_gbl_nesting_level = 0;
}
/*
*/
acpi_os_printf("%9s-%04ld ", module_name, line_number);
+#ifdef ACPI_EXEC_APP
+ /*
+ * For acpi_exec only, emit the thread ID and nesting level.
+ * Note: nesting level is really only useful during a single-thread
+ * execution. Otherwise, multiple threads will keep resetting the
+ * level.
+ */
if (ACPI_LV_THREADS & acpi_dbg_level) {
acpi_os_printf("[%u] ", (u32)thread_id);
}
- acpi_os_printf("[%02ld] %-22.22s: ",
- acpi_gbl_nesting_level,
- acpi_ut_trim_function_name(function_name));
+ acpi_os_printf("[%02ld] ", acpi_gbl_nesting_level);
+#endif
+
+ acpi_os_printf("%-22.22s: ", acpi_ut_trim_function_name(function_name));
va_start(args, format);
acpi_os_vprintf(format, args);
component_id, "%s\n", acpi_gbl_fn_exit_str);
}
- acpi_gbl_nesting_level--;
+ if (acpi_gbl_nesting_level) {
+ acpi_gbl_nesting_level--;
+ }
}
ACPI_EXPORT_SYMBOL(acpi_ut_exit)
}
}
- acpi_gbl_nesting_level--;
+ if (acpi_gbl_nesting_level) {
+ acpi_gbl_nesting_level--;
+ }
}
ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
ACPI_FORMAT_UINT64(value));
}
- acpi_gbl_nesting_level--;
+ if (acpi_gbl_nesting_level) {
+ acpi_gbl_nesting_level--;
+ }
}
ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
ptr);
}
- acpi_gbl_nesting_level--;
+ if (acpi_gbl_nesting_level) {
+ acpi_gbl_nesting_level--;
+ }
}
#endif
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/acpi_io.h>
-#include <acpi/acpiosxf.h>
/* ACPI NVS regions, APEI may use it */
.ids = root_device_ids,
.attach = acpi_pci_root_add,
.detach = acpi_pci_root_remove,
+ .hotplug = {
+ .ignore = true,
+ },
};
static DEFINE_MUTEX(osc_lock);
*/
list_for_each_entry(hwid, &pnp.ids, list) {
handler = acpi_scan_match_handler(hwid->id, NULL);
- if (handler) {
+ if (handler && !handler->hotplug.ignore) {
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
acpi_hotplug_notify_cb, handler);
break;
* generate wakeup events.
*/
if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
- acpi_event_status pwr_btn_status;
+ acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED;
acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);
sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
table_attr->instance);
- table_attr->attr.size = 0;
+ table_attr->attr.size = table_header->length;
table_attr->attr.read = acpi_table_show;
table_attr->attr.attr.name = table_attr->name;
table_attr->attr.attr.mode = 0400;
{
struct acpi_table_attr *table_attr;
struct acpi_table_header *table_header = NULL;
- int table_index = 0;
- int result;
+ int table_index;
+ acpi_status status;
+ int ret;
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
if (!tables_kobj)
if (!dynamic_tables_kobj)
goto err_dynamic_tables;
- do {
- result = acpi_get_table_by_index(table_index, &table_header);
- if (!result) {
- table_index++;
- table_attr = NULL;
- table_attr =
- kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
- if (!table_attr)
- return -ENOMEM;
-
- acpi_table_attr_init(table_attr, table_header);
- result =
- sysfs_create_bin_file(tables_kobj,
- &table_attr->attr);
- if (result) {
- kfree(table_attr);
- return result;
- } else
- list_add_tail(&table_attr->node,
- &acpi_table_attr_list);
+ for (table_index = 0;; table_index++) {
+ status = acpi_get_table_by_index(table_index, &table_header);
+
+ if (status == AE_BAD_PARAMETER)
+ break;
+
+ if (ACPI_FAILURE(status))
+ continue;
+
+ table_attr = NULL;
+ table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
+ if (!table_attr)
+ return -ENOMEM;
+
+ acpi_table_attr_init(table_attr, table_header);
+ ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr);
+ if (ret) {
+ kfree(table_attr);
+ return ret;
}
- } while (!result);
+ list_add_tail(&table_attr->node, &acpi_table_attr_list);
+ }
+
kobject_uevent(tables_kobj, KOBJ_ADD);
kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
- result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
+ status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
- return result == AE_OK ? 0 : -EINVAL;
+ return ACPI_FAILURE(status) ? -EINVAL : 0;
err_dynamic_tables:
kobject_put(tables_kobj);
err:
.driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
.driver_data = board_ahci_yes_fbs },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
+ .driver_data = board_ahci_yes_fbs },
/* Promise */
{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,spear-ahci", },
{ .compatible = "snps,exynos5440-ahci", },
+ { .compatible = "ibm,476gtr-ahci", },
{},
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
ata_tlink_delete(&ap->pmp_link[i]);
}
- ata_tport_delete(ap);
-
/* remove the associated SCSI host */
scsi_remove_host(ap->scsi_host);
+ ata_tport_delete(ap);
}
/**
shost->max_lun = 1;
shost->max_channel = 1;
shost->max_cmd_len = 16;
+ shost->no_write_same = 1;
/* Schedule policy is determined by ->qc_defer()
* callback and it needs to see every deferred qc.
static bool odd_can_poweroff(struct ata_device *ata_dev)
{
acpi_handle handle;
- acpi_status status;
struct acpi_device *acpi_dev;
handle = ata_dev_acpi_handle(ata_dev);
if (!handle)
return false;
- status = acpi_bus_get_device(handle, &acpi_dev);
- if (ACPI_FAILURE(status))
+ if (acpi_bus_get_device(handle, &acpi_dev))
return false;
return acpi_device_can_poweroff(acpi_dev);
ret = clk_set_rate(acdev->clk, 166000000);
if (ret) {
dev_warn(acdev->host->dev, "clock set rate failed");
+ clk_disable_unprepare(acdev->clk);
return ret;
}
#include <linux/async.h>
#include <linux/suspend.h>
#include <trace/events/power.h>
+#include <linux/cpufreq.h>
#include <linux/cpuidle.h>
#include <linux/timer.h>
dpm_show_time(starttime, state, "noirq");
resume_device_irqs();
cpuidle_resume();
+ cpufreq_resume();
}
/**
ktime_t starttime = ktime_get();
int error = 0;
+ cpufreq_suspend();
cpuidle_pause();
suspend_device_irqs();
mutex_lock(&dpm_list_mtx);
if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
(i % SEGS_PER_INDIRECT_FRAME == 0)) {
- unsigned long pfn;
+ unsigned long uninitialized_var(pfn);
if (segments)
kunmap_atomic(segments);
bdev = bdget_disk(disk, 0);
+ if (!bdev) {
+ WARN(1, "Block device %s yanked out from us!\n", disk->disk_name);
+ goto out_mutex;
+ }
if (bdev->bd_openers)
goto out;
out:
bdput(bdev);
+out_mutex:
mutex_unlock(&blkfront_mutex);
}
If unsure, say Y.
+config HW_RANDOM_OMAP3_ROM
+ tristate "OMAP3 ROM Random Number Generator support"
+ depends on HW_RANDOM && ARCH_OMAP3
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on OMAP34xx processors.
+
+ To compile this driver as a module, choose M here: the
+ module will be called omap3-rom-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_OCTEON
tristate "Octeon Random Number Generator support"
depends on HW_RANDOM && CAVIUM_OCTEON_SOC
module will be called tpm-rng.
If unsure, say Y.
+
+config HW_RANDOM_MSM
+ tristate "Qualcomm MSM Random Number Generator support"
+ depends on HW_RANDOM && ARCH_MSM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on Qualcomm MSM SoCs.
+
+ To compile this driver as a module, choose M here. the
+ module will be called msm-rng.
+
+ If unsure, say Y.
obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
+obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
--- /dev/null
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+/* Device specific register offsets */
+#define PRNG_DATA_OUT 0x0000
+#define PRNG_STATUS 0x0004
+#define PRNG_LFSR_CFG 0x0100
+#define PRNG_CONFIG 0x0104
+
+/* Device specific register masks and config values */
+#define PRNG_LFSR_CFG_MASK 0x0000ffff
+#define PRNG_LFSR_CFG_CLOCKS 0x0000dddd
+#define PRNG_CONFIG_HW_ENABLE BIT(1)
+#define PRNG_STATUS_DATA_AVAIL BIT(0)
+
+#define MAX_HW_FIFO_DEPTH 16
+#define MAX_HW_FIFO_SIZE (MAX_HW_FIFO_DEPTH * 4)
+#define WORD_SZ 4
+
+struct msm_rng {
+ void __iomem *base;
+ struct clk *clk;
+ struct hwrng hwrng;
+};
+
+#define to_msm_rng(p) container_of(p, struct msm_rng, hwrng)
+
+static int msm_rng_enable(struct hwrng *hwrng, int enable)
+{
+ struct msm_rng *rng = to_msm_rng(hwrng);
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(rng->clk);
+ if (ret)
+ return ret;
+
+ if (enable) {
+ /* Enable PRNG only if it is not already enabled */
+ val = readl_relaxed(rng->base + PRNG_CONFIG);
+ if (val & PRNG_CONFIG_HW_ENABLE)
+ goto already_enabled;
+
+ val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
+ val &= ~PRNG_LFSR_CFG_MASK;
+ val |= PRNG_LFSR_CFG_CLOCKS;
+ writel(val, rng->base + PRNG_LFSR_CFG);
+
+ val = readl_relaxed(rng->base + PRNG_CONFIG);
+ val |= PRNG_CONFIG_HW_ENABLE;
+ writel(val, rng->base + PRNG_CONFIG);
+ } else {
+ val = readl_relaxed(rng->base + PRNG_CONFIG);
+ val &= ~PRNG_CONFIG_HW_ENABLE;
+ writel(val, rng->base + PRNG_CONFIG);
+ }
+
+already_enabled:
+ clk_disable_unprepare(rng->clk);
+ return 0;
+}
+
+static int msm_rng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
+{
+ struct msm_rng *rng = to_msm_rng(hwrng);
+ size_t currsize = 0;
+ u32 *retdata = data;
+ size_t maxsize;
+ int ret;
+ u32 val;
+
+ /* calculate max size bytes to transfer back to caller */
+ maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, max);
+
+ /* no room for word data */
+ if (maxsize < WORD_SZ)
+ return 0;
+
+ ret = clk_prepare_enable(rng->clk);
+ if (ret)
+ return ret;
+
+ /* read random data from hardware */
+ do {
+ val = readl_relaxed(rng->base + PRNG_STATUS);
+ if (!(val & PRNG_STATUS_DATA_AVAIL))
+ break;
+
+ val = readl_relaxed(rng->base + PRNG_DATA_OUT);
+ if (!val)
+ break;
+
+ *retdata++ = val;
+ currsize += WORD_SZ;
+
+ /* make sure we stay on 32bit boundary */
+ if ((maxsize - currsize) < WORD_SZ)
+ break;
+ } while (currsize < maxsize);
+
+ clk_disable_unprepare(rng->clk);
+
+ return currsize;
+}
+
+static int msm_rng_init(struct hwrng *hwrng)
+{
+ return msm_rng_enable(hwrng, 1);
+}
+
+static void msm_rng_cleanup(struct hwrng *hwrng)
+{
+ msm_rng_enable(hwrng, 0);
+}
+
+static int msm_rng_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct msm_rng *rng;
+ int ret;
+
+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+ if (!rng)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, rng);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rng->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rng->base))
+ return PTR_ERR(rng->base);
+
+ rng->clk = devm_clk_get(&pdev->dev, "core");
+ if (IS_ERR(rng->clk))
+ return PTR_ERR(rng->clk);
+
+ rng->hwrng.name = KBUILD_MODNAME,
+ rng->hwrng.init = msm_rng_init,
+ rng->hwrng.cleanup = msm_rng_cleanup,
+ rng->hwrng.read = msm_rng_read,
+
+ ret = hwrng_register(&rng->hwrng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register hwrng\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int msm_rng_remove(struct platform_device *pdev)
+{
+ struct msm_rng *rng = platform_get_drvdata(pdev);
+
+ hwrng_unregister(&rng->hwrng);
+ return 0;
+}
+
+static const struct of_device_id msm_rng_of_match[] = {
+ { .compatible = "qcom,prng", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, msm_rng_of_match);
+
+static struct platform_driver msm_rng_driver = {
+ .probe = msm_rng_probe,
+ .remove = msm_rng_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(msm_rng_of_match),
+ }
+};
+module_platform_driver(msm_rng_driver);
+
+MODULE_ALIAS("platform:" KBUILD_MODNAME);
+MODULE_AUTHOR("The Linux Foundation");
+MODULE_DESCRIPTION("Qualcomm MSM random number generator driver");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+/*
+ * omap3-rom-rng.c - RNG driver for TI OMAP3 CPU family
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@solidboot.com>
+ *
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/hw_random.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#define RNG_RESET 0x01
+#define RNG_GEN_PRNG_HW_INIT 0x02
+#define RNG_GEN_HW 0x08
+
+/* param1: ptr, param2: count, param3: flag */
+static u32 (*omap3_rom_rng_call)(u32, u32, u32);
+
+static struct timer_list idle_timer;
+static int rng_idle;
+static struct clk *rng_clk;
+
+static void omap3_rom_rng_idle(unsigned long data)
+{
+ int r;
+
+ r = omap3_rom_rng_call(0, 0, RNG_RESET);
+ if (r != 0) {
+ pr_err("reset failed: %d\n", r);
+ return;
+ }
+ clk_disable_unprepare(rng_clk);
+ rng_idle = 1;
+}
+
+static int omap3_rom_rng_get_random(void *buf, unsigned int count)
+{
+ u32 r;
+ u32 ptr;
+
+ del_timer_sync(&idle_timer);
+ if (rng_idle) {
+ clk_prepare_enable(rng_clk);
+ r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT);
+ if (r != 0) {
+ clk_disable_unprepare(rng_clk);
+ pr_err("HW init failed: %d\n", r);
+ return -EIO;
+ }
+ rng_idle = 0;
+ }
+
+ ptr = virt_to_phys(buf);
+ r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW);
+ mod_timer(&idle_timer, jiffies + msecs_to_jiffies(500));
+ if (r != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int omap3_rom_rng_data_present(struct hwrng *rng, int wait)
+{
+ return 1;
+}
+
+static int omap3_rom_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ int r;
+
+ r = omap3_rom_rng_get_random(data, 4);
+ if (r < 0)
+ return r;
+ return 4;
+}
+
+static struct hwrng omap3_rom_rng_ops = {
+ .name = "omap3-rom",
+ .data_present = omap3_rom_rng_data_present,
+ .data_read = omap3_rom_rng_data_read,
+};
+
+static int omap3_rom_rng_probe(struct platform_device *pdev)
+{
+ pr_info("initializing\n");
+
+ omap3_rom_rng_call = pdev->dev.platform_data;
+ if (!omap3_rom_rng_call) {
+ pr_err("omap3_rom_rng_call is NULL\n");
+ return -EINVAL;
+ }
+
+ setup_timer(&idle_timer, omap3_rom_rng_idle, 0);
+ rng_clk = clk_get(&pdev->dev, "ick");
+ if (IS_ERR(rng_clk)) {
+ pr_err("unable to get RNG clock\n");
+ return PTR_ERR(rng_clk);
+ }
+
+ /* Leave the RNG in reset state. */
+ clk_prepare_enable(rng_clk);
+ omap3_rom_rng_idle(0);
+
+ return hwrng_register(&omap3_rom_rng_ops);
+}
+
+static int omap3_rom_rng_remove(struct platform_device *pdev)
+{
+ hwrng_unregister(&omap3_rom_rng_ops);
+ clk_disable_unprepare(rng_clk);
+ clk_put(rng_clk);
+ return 0;
+}
+
+static struct platform_driver omap3_rom_rng_driver = {
+ .driver = {
+ .name = "omap3-rom-rng",
+ .owner = THIS_MODULE,
+ },
+ .probe = omap3_rom_rng_probe,
+ .remove = omap3_rom_rng_remove,
+};
+
+module_platform_driver(omap3_rom_rng_driver);
+
+MODULE_ALIAS("platform:omap3-rom-rng");
+MODULE_AUTHOR("Juha Yrjola");
+MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
+MODULE_LICENSE("GPL");
#include <linux/hw_random.h>
#include <asm/vio.h>
-#define MODULE_NAME "pseries-rng"
static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
{
};
static struct hwrng pseries_rng = {
- .name = MODULE_NAME,
+ .name = KBUILD_MODNAME,
.data_read = pseries_rng_data_read,
};
MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids);
static struct vio_driver pseries_rng_driver = {
- .name = MODULE_NAME,
+ .name = KBUILD_MODNAME,
.probe = pseries_rng_probe,
.remove = pseries_rng_remove,
.get_desired_dma = pseries_rng_get_desired_dma,
module_init(mod_init);
module_exit(mod_exit);
-static struct x86_cpu_id via_rng_cpu_id[] = {
+static struct x86_cpu_id __maybe_unused via_rng_cpu_id[] = {
X86_FEATURE_MATCH(X86_FEATURE_XSTORE),
{}
};
obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
+obj-$(CONFIG_COMMON_CLK_AT91) += at91/
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/
obj-$(CONFIG_X86) += x86/
--- /dev/null
+#
+# Makefile for at91 specific clk
+#
+
+obj-y += pmc.o
+obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
+obj-y += clk-system.o clk-peripheral.o
+
+obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
+obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
+obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
+obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include "pmc.h"
+
+#define SLOW_CLOCK_FREQ 32768
+#define MAINF_DIV 16
+#define MAINFRDY_TIMEOUT (((MAINF_DIV + 1) * USEC_PER_SEC) / \
+ SLOW_CLOCK_FREQ)
+#define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ)
+#define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT
+
+struct clk_main {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned long rate;
+ unsigned int irq;
+ wait_queue_head_t wait;
+};
+
+#define to_clk_main(hw) container_of(hw, struct clk_main, hw)
+
+static irqreturn_t clk_main_irq_handler(int irq, void *dev_id)
+{
+ struct clk_main *clkmain = (struct clk_main *)dev_id;
+
+ wake_up(&clkmain->wait);
+ disable_irq_nosync(clkmain->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_main_prepare(struct clk_hw *hw)
+{
+ struct clk_main *clkmain = to_clk_main(hw);
+ struct at91_pmc *pmc = clkmain->pmc;
+ unsigned long halt_time, timeout;
+ u32 tmp;
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
+ enable_irq(clkmain->irq);
+ wait_event(clkmain->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
+ }
+
+ if (clkmain->rate)
+ return 0;
+
+ timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
+ do {
+ halt_time = jiffies;
+ tmp = pmc_read(pmc, AT91_CKGR_MCFR);
+ if (tmp & AT91_PMC_MAINRDY)
+ return 0;
+ usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
+ } while (time_before(halt_time, timeout));
+
+ return 0;
+}
+
+static int clk_main_is_prepared(struct clk_hw *hw)
+{
+ struct clk_main *clkmain = to_clk_main(hw);
+
+ return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
+}
+
+static unsigned long clk_main_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ struct clk_main *clkmain = to_clk_main(hw);
+ struct at91_pmc *pmc = clkmain->pmc;
+
+ if (clkmain->rate)
+ return clkmain->rate;
+
+ tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF;
+ clkmain->rate = (tmp * parent_rate) / MAINF_DIV;
+
+ return clkmain->rate;
+}
+
+static const struct clk_ops main_ops = {
+ .prepare = clk_main_prepare,
+ .is_prepared = clk_main_is_prepared,
+ .recalc_rate = clk_main_recalc_rate,
+};
+
+static struct clk * __init
+at91_clk_register_main(struct at91_pmc *pmc,
+ unsigned int irq,
+ const char *name,
+ const char *parent_name,
+ unsigned long rate)
+{
+ int ret;
+ struct clk_main *clkmain;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !irq || !name)
+ return ERR_PTR(-EINVAL);
+
+ if (!rate && !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
+ if (!clkmain)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &main_ops;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.flags = parent_name ? 0 : CLK_IS_ROOT;
+
+ clkmain->hw.init = &init;
+ clkmain->rate = rate;
+ clkmain->pmc = pmc;
+ clkmain->irq = irq;
+ init_waitqueue_head(&clkmain->wait);
+ irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
+ ret = request_irq(clkmain->irq, clk_main_irq_handler,
+ IRQF_TRIGGER_HIGH, "clk-main", clkmain);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &clkmain->hw);
+ if (IS_ERR(clk)) {
+ free_irq(clkmain->irq, clkmain);
+ kfree(clkmain);
+ }
+
+ return clk;
+}
+
+
+
+static void __init
+of_at91_clk_main_setup(struct device_node *np, struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ unsigned int irq;
+ const char *parent_name;
+ const char *name = np->name;
+ u32 rate = 0;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "clock-frequency", &rate);
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_main(pmc, irq, name, parent_name, rate);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+void __init of_at91rm9200_clk_main_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_main_setup(np, pmc);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include "pmc.h"
+
+#define MASTER_SOURCE_MAX 4
+
+#define MASTER_PRES_MASK 0x7
+#define MASTER_PRES_MAX MASTER_PRES_MASK
+#define MASTER_DIV_SHIFT 8
+#define MASTER_DIV_MASK 0x3
+
+struct clk_master_characteristics {
+ struct clk_range output;
+ u32 divisors[4];
+ u8 have_div3_pres;
+};
+
+struct clk_master_layout {
+ u32 mask;
+ u8 pres_shift;
+};
+
+#define to_clk_master(hw) container_of(hw, struct clk_master, hw)
+
+struct clk_master {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ const struct clk_master_layout *layout;
+ const struct clk_master_characteristics *characteristics;
+};
+
+static irqreturn_t clk_master_irq_handler(int irq, void *dev_id)
+{
+ struct clk_master *master = (struct clk_master *)dev_id;
+
+ wake_up(&master->wait);
+ disable_irq_nosync(master->irq);
+
+ return IRQ_HANDLED;
+}
+static int clk_master_prepare(struct clk_hw *hw)
+{
+ struct clk_master *master = to_clk_master(hw);
+ struct at91_pmc *pmc = master->pmc;
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) {
+ enable_irq(master->irq);
+ wait_event(master->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
+ }
+
+ return 0;
+}
+
+static int clk_master_is_prepared(struct clk_hw *hw)
+{
+ struct clk_master *master = to_clk_master(hw);
+
+ return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
+}
+
+static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u8 pres;
+ u8 div;
+ unsigned long rate = parent_rate;
+ struct clk_master *master = to_clk_master(hw);
+ struct at91_pmc *pmc = master->pmc;
+ const struct clk_master_layout *layout = master->layout;
+ const struct clk_master_characteristics *characteristics =
+ master->characteristics;
+ u32 tmp;
+
+ pmc_lock(pmc);
+ tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask;
+ pmc_unlock(pmc);
+
+ pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK;
+ div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
+
+ if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
+ rate /= 3;
+ else
+ rate >>= pres;
+
+ rate /= characteristics->divisors[div];
+
+ if (rate < characteristics->output.min)
+ pr_warn("master clk is underclocked");
+ else if (rate > characteristics->output.max)
+ pr_warn("master clk is overclocked");
+
+ return rate;
+}
+
+static u8 clk_master_get_parent(struct clk_hw *hw)
+{
+ struct clk_master *master = to_clk_master(hw);
+ struct at91_pmc *pmc = master->pmc;
+
+ return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS;
+}
+
+static const struct clk_ops master_ops = {
+ .prepare = clk_master_prepare,
+ .is_prepared = clk_master_is_prepared,
+ .recalc_rate = clk_master_recalc_rate,
+ .get_parent = clk_master_get_parent,
+};
+
+static struct clk * __init
+at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq,
+ const char *name, int num_parents,
+ const char **parent_names,
+ const struct clk_master_layout *layout,
+ const struct clk_master_characteristics *characteristics)
+{
+ int ret;
+ struct clk_master *master;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !irq || !name || !num_parents || !parent_names)
+ return ERR_PTR(-EINVAL);
+
+ master = kzalloc(sizeof(*master), GFP_KERNEL);
+ if (!master)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &master_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = 0;
+
+ master->hw.init = &init;
+ master->layout = layout;
+ master->characteristics = characteristics;
+ master->pmc = pmc;
+ master->irq = irq;
+ init_waitqueue_head(&master->wait);
+ irq_set_status_flags(master->irq, IRQ_NOAUTOEN);
+ ret = request_irq(master->irq, clk_master_irq_handler,
+ IRQF_TRIGGER_HIGH, "clk-master", master);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &master->hw);
+ if (IS_ERR(clk))
+ kfree(master);
+
+ return clk;
+}
+
+
+static const struct clk_master_layout at91rm9200_master_layout = {
+ .mask = 0x31F,
+ .pres_shift = 2,
+};
+
+static const struct clk_master_layout at91sam9x5_master_layout = {
+ .mask = 0x373,
+ .pres_shift = 4,
+};
+
+
+static struct clk_master_characteristics * __init
+of_at91_clk_master_get_characteristics(struct device_node *np)
+{
+ struct clk_master_characteristics *characteristics;
+
+ characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+ if (!characteristics)
+ return NULL;
+
+ if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
+ goto out_free_characteristics;
+
+ of_property_read_u32_array(np, "atmel,clk-divisors",
+ characteristics->divisors, 4);
+
+ characteristics->have_div3_pres =
+ of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
+
+ return characteristics;
+
+out_free_characteristics:
+ kfree(characteristics);
+ return NULL;
+}
+
+static void __init
+of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
+ const struct clk_master_layout *layout)
+{
+ struct clk *clk;
+ int num_parents;
+ int i;
+ unsigned int irq;
+ const char *parent_names[MASTER_SOURCE_MAX];
+ const char *name = np->name;
+ struct clk_master_characteristics *characteristics;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
+ return;
+
+ for (i = 0; i < num_parents; ++i) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ characteristics = of_at91_clk_master_get_characteristics(np);
+ if (!characteristics)
+ return;
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_master(pmc, irq, name, num_parents,
+ parent_names, layout,
+ characteristics);
+ if (IS_ERR(clk))
+ goto out_free_characteristics;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+
+out_free_characteristics:
+ kfree(characteristics);
+}
+
+void __init of_at91rm9200_clk_master_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout);
+}
+
+void __init of_at91sam9x5_clk_master_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define PERIPHERAL_MAX 64
+
+#define PERIPHERAL_AT91RM9200 0
+#define PERIPHERAL_AT91SAM9X5 1
+
+#define PERIPHERAL_ID_MIN 2
+#define PERIPHERAL_ID_MAX 31
+#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
+
+#define PERIPHERAL_RSHIFT_MASK 0x3
+#define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK)
+
+#define PERIPHERAL_MAX_SHIFT 4
+
+struct clk_peripheral {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ u32 id;
+};
+
+#define to_clk_peripheral(hw) container_of(hw, struct clk_peripheral, hw)
+
+struct clk_sam9x5_peripheral {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ struct clk_range range;
+ u32 id;
+ u32 div;
+ bool auto_div;
+};
+
+#define to_clk_sam9x5_peripheral(hw) \
+ container_of(hw, struct clk_sam9x5_peripheral, hw)
+
+static int clk_peripheral_enable(struct clk_hw *hw)
+{
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCER;
+ u32 id = periph->id;
+
+ if (id < PERIPHERAL_ID_MIN)
+ return 0;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCER1;
+ pmc_write(pmc, offset, PERIPHERAL_MASK(id));
+ return 0;
+}
+
+static void clk_peripheral_disable(struct clk_hw *hw)
+{
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCDR;
+ u32 id = periph->id;
+
+ if (id < PERIPHERAL_ID_MIN)
+ return;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCDR1;
+ pmc_write(pmc, offset, PERIPHERAL_MASK(id));
+}
+
+static int clk_peripheral_is_enabled(struct clk_hw *hw)
+{
+ struct clk_peripheral *periph = to_clk_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+ int offset = AT91_PMC_PCSR;
+ u32 id = periph->id;
+
+ if (id < PERIPHERAL_ID_MIN)
+ return 1;
+ if (id > PERIPHERAL_ID_MAX)
+ offset = AT91_PMC_PCSR1;
+ return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id));
+}
+
+static const struct clk_ops peripheral_ops = {
+ .enable = clk_peripheral_enable,
+ .disable = clk_peripheral_disable,
+ .is_enabled = clk_peripheral_is_enabled,
+};
+
+static struct clk * __init
+at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name,
+ const char *parent_name, u32 id)
+{
+ struct clk_peripheral *periph;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX)
+ return ERR_PTR(-EINVAL);
+
+ periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+ if (!periph)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &peripheral_ops;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+ init.flags = 0;
+
+ periph->id = id;
+ periph->hw.init = &init;
+ periph->pmc = pmc;
+
+ clk = clk_register(NULL, &periph->hw);
+ if (IS_ERR(clk))
+ kfree(periph);
+
+ return clk;
+}
+
+static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
+{
+ struct clk *parent;
+ unsigned long parent_rate;
+ int shift = 0;
+
+ if (!periph->auto_div)
+ return;
+
+ if (periph->range.max) {
+ parent = clk_get_parent_by_index(periph->hw.clk, 0);
+ parent_rate = __clk_get_rate(parent);
+ if (!parent_rate)
+ return;
+
+ for (; shift < PERIPHERAL_MAX_SHIFT; shift++) {
+ if (parent_rate >> shift <= periph->range.max)
+ break;
+ }
+ }
+
+ periph->auto_div = false;
+ periph->div = shift;
+}
+
+static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
+{
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return 0;
+
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
+ AT91_PMC_PCR_CMD |
+ AT91_PMC_PCR_DIV(periph->div) |
+ AT91_PMC_PCR_EN);
+ return 0;
+}
+
+static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
+{
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return;
+
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
+ AT91_PMC_PCR_CMD);
+}
+
+static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
+{
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+ int ret;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return 1;
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+ ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN);
+ pmc_unlock(pmc);
+
+ return ret;
+}
+
+static unsigned long
+clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+ struct at91_pmc *pmc = periph->pmc;
+ u32 tmp;
+
+ if (periph->id < PERIPHERAL_ID_MIN)
+ return parent_rate;
+
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+ tmp = pmc_read(pmc, AT91_PMC_PCR);
+ pmc_unlock(pmc);
+
+ if (tmp & AT91_PMC_PCR_EN) {
+ periph->div = PERIPHERAL_RSHIFT(tmp);
+ periph->auto_div = false;
+ } else {
+ clk_sam9x5_peripheral_autodiv(periph);
+ }
+
+ return parent_rate >> periph->div;
+}
+
+static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *parent_rate)
+{
+ int shift = 0;
+ unsigned long best_rate;
+ unsigned long best_diff;
+ unsigned long cur_rate = *parent_rate;
+ unsigned long cur_diff;
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+
+ if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max)
+ return *parent_rate;
+
+ if (periph->range.max) {
+ for (; shift < PERIPHERAL_MAX_SHIFT; shift++) {
+ cur_rate = *parent_rate >> shift;
+ if (cur_rate <= periph->range.max)
+ break;
+ }
+ }
+
+ if (rate >= cur_rate)
+ return cur_rate;
+
+ best_diff = cur_rate - rate;
+ best_rate = cur_rate;
+ for (; shift < PERIPHERAL_MAX_SHIFT; shift++) {
+ cur_rate = *parent_rate >> shift;
+ if (cur_rate < rate)
+ cur_diff = rate - cur_rate;
+ else
+ cur_diff = cur_rate - rate;
+
+ if (cur_diff < best_diff) {
+ best_diff = cur_diff;
+ best_rate = cur_rate;
+ }
+
+ if (!best_diff || cur_rate < rate)
+ break;
+ }
+
+ return best_rate;
+}
+
+static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ int shift;
+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
+ if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) {
+ if (parent_rate == rate)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ if (periph->range.max && rate > periph->range.max)
+ return -EINVAL;
+
+ for (shift = 0; shift < PERIPHERAL_MAX_SHIFT; shift++) {
+ if (parent_rate >> shift == rate) {
+ periph->auto_div = false;
+ periph->div = shift;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static const struct clk_ops sam9x5_peripheral_ops = {
+ .enable = clk_sam9x5_peripheral_enable,
+ .disable = clk_sam9x5_peripheral_disable,
+ .is_enabled = clk_sam9x5_peripheral_is_enabled,
+ .recalc_rate = clk_sam9x5_peripheral_recalc_rate,
+ .round_rate = clk_sam9x5_peripheral_round_rate,
+ .set_rate = clk_sam9x5_peripheral_set_rate,
+};
+
+static struct clk * __init
+at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name,
+ const char *parent_name, u32 id,
+ const struct clk_range *range)
+{
+ struct clk_sam9x5_peripheral *periph;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+ if (!periph)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &sam9x5_peripheral_ops;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+ init.flags = 0;
+
+ periph->id = id;
+ periph->hw.init = &init;
+ periph->div = 0;
+ periph->pmc = pmc;
+ periph->auto_div = true;
+ periph->range = *range;
+
+ clk = clk_register(NULL, &periph->hw);
+ if (IS_ERR(clk))
+ kfree(periph);
+ else
+ clk_sam9x5_peripheral_autodiv(periph);
+
+ return clk;
+}
+
+static void __init
+of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type)
+{
+ int num;
+ u32 id;
+ struct clk *clk;
+ const char *parent_name;
+ const char *name;
+ struct device_node *periphclknp;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ num = of_get_child_count(np);
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
+ for_each_child_of_node(np, periphclknp) {
+ if (of_property_read_u32(periphclknp, "reg", &id))
+ continue;
+
+ if (id >= PERIPHERAL_MAX)
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = periphclknp->name;
+
+ if (type == PERIPHERAL_AT91RM9200) {
+ clk = at91_clk_register_peripheral(pmc, name,
+ parent_name, id);
+ } else {
+ struct clk_range range = CLK_RANGE(0, 0);
+
+ of_at91_get_clk_range(periphclknp,
+ "atmel,clk-output-range",
+ &range);
+
+ clk = at91_clk_register_sam9x5_peripheral(pmc, name,
+ parent_name,
+ id, &range);
+ }
+
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk);
+ }
+}
+
+void __init of_at91rm9200_clk_periph_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91RM9200);
+}
+
+void __init of_at91sam9x5_clk_periph_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91SAM9X5);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include "pmc.h"
+
+#define PLL_STATUS_MASK(id) (1 << (1 + (id)))
+#define PLL_REG(id) (AT91_CKGR_PLLAR + ((id) * 4))
+#define PLL_DIV_MASK 0xff
+#define PLL_DIV_MAX PLL_DIV_MASK
+#define PLL_DIV(reg) ((reg) & PLL_DIV_MASK)
+#define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \
+ (layout)->mul_mask)
+#define PLL_ICPR_SHIFT(id) ((id) * 16)
+#define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id))
+#define PLL_MAX_COUNT 0x3ff
+#define PLL_COUNT_SHIFT 8
+#define PLL_OUT_SHIFT 14
+#define PLL_MAX_ID 1
+
+struct clk_pll_characteristics {
+ struct clk_range input;
+ int num_output;
+ struct clk_range *output;
+ u16 *icpll;
+ u8 *out;
+};
+
+struct clk_pll_layout {
+ u32 pllr_mask;
+ u16 mul_mask;
+ u8 mul_shift;
+};
+
+#define to_clk_pll(hw) container_of(hw, struct clk_pll, hw)
+
+struct clk_pll {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 id;
+ u8 div;
+ u8 range;
+ u16 mul;
+ const struct clk_pll_layout *layout;
+ const struct clk_pll_characteristics *characteristics;
+};
+
+static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id)
+{
+ struct clk_pll *pll = (struct clk_pll *)dev_id;
+
+ wake_up(&pll->wait);
+ disable_irq_nosync(pll->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_pll_prepare(struct clk_hw *hw)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct at91_pmc *pmc = pll->pmc;
+ const struct clk_pll_layout *layout = pll->layout;
+ const struct clk_pll_characteristics *characteristics =
+ pll->characteristics;
+ u8 id = pll->id;
+ u32 mask = PLL_STATUS_MASK(id);
+ int offset = PLL_REG(id);
+ u8 out = 0;
+ u32 pllr, icpr;
+ u8 div;
+ u16 mul;
+
+ pllr = pmc_read(pmc, offset);
+ div = PLL_DIV(pllr);
+ mul = PLL_MUL(pllr, layout);
+
+ if ((pmc_read(pmc, AT91_PMC_SR) & mask) &&
+ (div == pll->div && mul == pll->mul))
+ return 0;
+
+ if (characteristics->out)
+ out = characteristics->out[pll->range];
+ if (characteristics->icpll) {
+ icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id);
+ icpr |= (characteristics->icpll[pll->range] <<
+ PLL_ICPR_SHIFT(id));
+ pmc_write(pmc, AT91_PMC_PLLICPR, icpr);
+ }
+
+ pllr &= ~layout->pllr_mask;
+ pllr |= layout->pllr_mask &
+ (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) |
+ (out << PLL_OUT_SHIFT) |
+ ((pll->mul & layout->mul_mask) << layout->mul_shift));
+ pmc_write(pmc, offset, pllr);
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
+ enable_irq(pll->irq);
+ wait_event(pll->wait,
+ pmc_read(pmc, AT91_PMC_SR) & mask);
+ }
+
+ return 0;
+}
+
+static int clk_pll_is_prepared(struct clk_hw *hw)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct at91_pmc *pmc = pll->pmc;
+
+ return !!(pmc_read(pmc, AT91_PMC_SR) &
+ PLL_STATUS_MASK(pll->id));
+}
+
+static void clk_pll_unprepare(struct clk_hw *hw)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct at91_pmc *pmc = pll->pmc;
+ const struct clk_pll_layout *layout = pll->layout;
+ int offset = PLL_REG(pll->id);
+ u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask);
+
+ pmc_write(pmc, offset, tmp);
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ const struct clk_pll_layout *layout = pll->layout;
+ struct at91_pmc *pmc = pll->pmc;
+ int offset = PLL_REG(pll->id);
+ u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask;
+ u8 div = PLL_DIV(tmp);
+ u16 mul = PLL_MUL(tmp, layout);
+ if (!div || !mul)
+ return 0;
+
+ return (parent_rate * (mul + 1)) / div;
+}
+
+static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
+ unsigned long parent_rate,
+ u32 *div, u32 *mul,
+ u32 *index) {
+ unsigned long maxrate;
+ unsigned long minrate;
+ unsigned long divrate;
+ unsigned long bestdiv = 1;
+ unsigned long bestmul;
+ unsigned long tmpdiv;
+ unsigned long roundup;
+ unsigned long rounddown;
+ unsigned long remainder;
+ unsigned long bestremainder;
+ unsigned long maxmul;
+ unsigned long maxdiv;
+ unsigned long mindiv;
+ int i = 0;
+ const struct clk_pll_layout *layout = pll->layout;
+ const struct clk_pll_characteristics *characteristics =
+ pll->characteristics;
+
+ /* Minimum divider = 1 */
+ /* Maximum multiplier = max_mul */
+ maxmul = layout->mul_mask + 1;
+ maxrate = (parent_rate * maxmul) / 1;
+
+ /* Maximum divider = max_div */
+ /* Minimum multiplier = 2 */
+ maxdiv = PLL_DIV_MAX;
+ minrate = (parent_rate * 2) / maxdiv;
+
+ if (parent_rate < characteristics->input.min ||
+ parent_rate < characteristics->input.max)
+ return -ERANGE;
+
+ if (parent_rate < minrate || parent_rate > maxrate)
+ return -ERANGE;
+
+ for (i = 0; i < characteristics->num_output; i++) {
+ if (parent_rate >= characteristics->output[i].min &&
+ parent_rate <= characteristics->output[i].max)
+ break;
+ }
+
+ if (i >= characteristics->num_output)
+ return -ERANGE;
+
+ bestmul = rate / parent_rate;
+ rounddown = parent_rate % rate;
+ roundup = rate - rounddown;
+ bestremainder = roundup < rounddown ? roundup : rounddown;
+
+ if (!bestremainder) {
+ if (div)
+ *div = bestdiv;
+ if (mul)
+ *mul = bestmul;
+ if (index)
+ *index = i;
+ return rate;
+ }
+
+ maxdiv = 255 / (bestmul + 1);
+ if (parent_rate / maxdiv < characteristics->input.min)
+ maxdiv = parent_rate / characteristics->input.min;
+ mindiv = parent_rate / characteristics->input.max;
+ if (parent_rate % characteristics->input.max)
+ mindiv++;
+
+ for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) {
+ divrate = parent_rate / tmpdiv;
+
+ rounddown = rate % divrate;
+ roundup = divrate - rounddown;
+ remainder = roundup < rounddown ? roundup : rounddown;
+
+ if (remainder < bestremainder) {
+ bestremainder = remainder;
+ bestmul = rate / divrate;
+ bestdiv = tmpdiv;
+ }
+
+ if (!remainder)
+ break;
+ }
+
+ rate = (parent_rate / bestdiv) * bestmul;
+
+ if (div)
+ *div = bestdiv;
+ if (mul)
+ *mul = bestmul;
+ if (index)
+ *index = i;
+
+ return rate;
+}
+
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+
+ return clk_pll_get_best_div_mul(pll, rate, *parent_rate,
+ NULL, NULL, NULL);
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ long ret;
+ u32 div;
+ u32 mul;
+ u32 index;
+
+ ret = clk_pll_get_best_div_mul(pll, rate, parent_rate,
+ &div, &mul, &index);
+ if (ret < 0)
+ return ret;
+
+ pll->range = index;
+ pll->div = div;
+ pll->mul = mul;
+
+ return 0;
+}
+
+static const struct clk_ops pll_ops = {
+ .prepare = clk_pll_prepare,
+ .unprepare = clk_pll_unprepare,
+ .is_prepared = clk_pll_is_prepared,
+ .recalc_rate = clk_pll_recalc_rate,
+ .round_rate = clk_pll_round_rate,
+ .set_rate = clk_pll_set_rate,
+};
+
+static struct clk * __init
+at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name,
+ const char *parent_name, u8 id,
+ const struct clk_pll_layout *layout,
+ const struct clk_pll_characteristics *characteristics)
+{
+ struct clk_pll *pll;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+ int ret;
+ int offset = PLL_REG(id);
+ u32 tmp;
+
+ if (id > PLL_MAX_ID)
+ return ERR_PTR(-EINVAL);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &pll_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_GATE;
+
+ pll->id = id;
+ pll->hw.init = &init;
+ pll->layout = layout;
+ pll->characteristics = characteristics;
+ pll->pmc = pmc;
+ pll->irq = irq;
+ tmp = pmc_read(pmc, offset) & layout->pllr_mask;
+ pll->div = PLL_DIV(tmp);
+ pll->mul = PLL_MUL(tmp, layout);
+ init_waitqueue_head(&pll->wait);
+ irq_set_status_flags(pll->irq, IRQ_NOAUTOEN);
+ ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH,
+ id ? "clk-pllb" : "clk-plla", pll);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+
+static const struct clk_pll_layout at91rm9200_pll_layout = {
+ .pllr_mask = 0x7FFFFFF,
+ .mul_shift = 16,
+ .mul_mask = 0x7FF,
+};
+
+static const struct clk_pll_layout at91sam9g45_pll_layout = {
+ .pllr_mask = 0xFFFFFF,
+ .mul_shift = 16,
+ .mul_mask = 0xFF,
+};
+
+static const struct clk_pll_layout at91sam9g20_pllb_layout = {
+ .pllr_mask = 0x3FFFFF,
+ .mul_shift = 16,
+ .mul_mask = 0x3F,
+};
+
+static const struct clk_pll_layout sama5d3_pll_layout = {
+ .pllr_mask = 0x1FFFFFF,
+ .mul_shift = 18,
+ .mul_mask = 0x7F,
+};
+
+
+static struct clk_pll_characteristics * __init
+of_at91_clk_pll_get_characteristics(struct device_node *np)
+{
+ int i;
+ int offset;
+ u32 tmp;
+ int num_output;
+ u32 num_cells;
+ struct clk_range input;
+ struct clk_range *output;
+ u8 *out = NULL;
+ u16 *icpll = NULL;
+ struct clk_pll_characteristics *characteristics;
+
+ if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
+ return NULL;
+
+ if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
+ &num_cells))
+ return NULL;
+
+ if (num_cells < 2 || num_cells > 4)
+ return NULL;
+
+ if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
+ return NULL;
+ num_output = tmp / (sizeof(u32) * num_cells);
+
+ characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+ if (!characteristics)
+ return NULL;
+
+ output = kzalloc(sizeof(*output) * num_output, GFP_KERNEL);
+ if (!output)
+ goto out_free_characteristics;
+
+ if (num_cells > 2) {
+ out = kzalloc(sizeof(*out) * num_output, GFP_KERNEL);
+ if (!out)
+ goto out_free_output;
+ }
+
+ if (num_cells > 3) {
+ icpll = kzalloc(sizeof(*icpll) * num_output, GFP_KERNEL);
+ if (!icpll)
+ goto out_free_output;
+ }
+
+ for (i = 0; i < num_output; i++) {
+ offset = i * num_cells;
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset, &tmp))
+ goto out_free_output;
+ output[i].min = tmp;
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 1, &tmp))
+ goto out_free_output;
+ output[i].max = tmp;
+
+ if (num_cells == 2)
+ continue;
+
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 2, &tmp))
+ goto out_free_output;
+ out[i] = tmp;
+
+ if (num_cells == 3)
+ continue;
+
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 3, &tmp))
+ goto out_free_output;
+ icpll[i] = tmp;
+ }
+
+ characteristics->input = input;
+ characteristics->num_output = num_output;
+ characteristics->output = output;
+ characteristics->out = out;
+ characteristics->icpll = icpll;
+ return characteristics;
+
+out_free_output:
+ kfree(icpll);
+ kfree(out);
+ kfree(output);
+out_free_characteristics:
+ kfree(characteristics);
+ return NULL;
+}
+
+static void __init
+of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc,
+ const struct clk_pll_layout *layout)
+{
+ u32 id;
+ unsigned int irq;
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+ struct clk_pll_characteristics *characteristics;
+
+ if (of_property_read_u32(np, "reg", &id))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ characteristics = of_at91_clk_pll_get_characteristics(np);
+ if (!characteristics)
+ return;
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout,
+ characteristics);
+ if (IS_ERR(clk))
+ goto out_free_characteristics;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+
+out_free_characteristics:
+ kfree(characteristics);
+}
+
+void __init of_at91rm9200_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout);
+}
+
+void __init of_at91sam9g45_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout);
+}
+
+void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout);
+}
+
+void __init of_sama5d3_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define to_clk_plldiv(hw) container_of(hw, struct clk_plldiv, hw)
+
+struct clk_plldiv {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+};
+
+static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_plldiv *plldiv = to_clk_plldiv(hw);
+ struct at91_pmc *pmc = plldiv->pmc;
+
+ if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2)
+ return parent_rate / 2;
+
+ return parent_rate;
+}
+
+static long clk_plldiv_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long div;
+
+ if (rate > *parent_rate)
+ return *parent_rate;
+ div = *parent_rate / 2;
+ if (rate < div)
+ return div;
+
+ if (rate - div < *parent_rate - rate)
+ return div;
+
+ return *parent_rate;
+}
+
+static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_plldiv *plldiv = to_clk_plldiv(hw);
+ struct at91_pmc *pmc = plldiv->pmc;
+ u32 tmp;
+
+ if (parent_rate != rate && (parent_rate / 2) != rate)
+ return -EINVAL;
+
+ pmc_lock(pmc);
+ tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2;
+ if ((parent_rate / 2) == rate)
+ tmp |= AT91_PMC_PLLADIV2;
+ pmc_write(pmc, AT91_PMC_MCKR, tmp);
+ pmc_unlock(pmc);
+
+ return 0;
+}
+
+static const struct clk_ops plldiv_ops = {
+ .recalc_rate = clk_plldiv_recalc_rate,
+ .round_rate = clk_plldiv_round_rate,
+ .set_rate = clk_plldiv_set_rate,
+};
+
+static struct clk * __init
+at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name,
+ const char *parent_name)
+{
+ struct clk_plldiv *plldiv;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL);
+ if (!plldiv)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &plldiv_ops;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.flags = CLK_SET_RATE_GATE;
+
+ plldiv->hw.init = &init;
+ plldiv->pmc = pmc;
+
+ clk = clk_register(NULL, &plldiv->hw);
+
+ if (IS_ERR(clk))
+ kfree(plldiv);
+
+ return clk;
+}
+
+static void __init
+of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91_clk_register_plldiv(pmc, name, parent_name);
+
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+}
+
+void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_plldiv_setup(np, pmc);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include "pmc.h"
+
+#define PROG_SOURCE_MAX 5
+#define PROG_ID_MAX 7
+
+#define PROG_STATUS_MASK(id) (1 << ((id) + 8))
+#define PROG_PRES_MASK 0x7
+#define PROG_MAX_RM9200_CSS 3
+
+struct clk_programmable_layout {
+ u8 pres_shift;
+ u8 css_mask;
+ u8 have_slck_mck;
+};
+
+struct clk_programmable {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 id;
+ u8 css;
+ u8 pres;
+ u8 slckmck;
+ const struct clk_programmable_layout *layout;
+};
+
+#define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
+
+
+static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id)
+{
+ struct clk_programmable *prog = (struct clk_programmable *)dev_id;
+
+ wake_up(&prog->wait);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_programmable_prepare(struct clk_hw *hw)
+{
+ u32 tmp;
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
+ u8 id = prog->id;
+ u32 mask = PROG_STATUS_MASK(id);
+
+ tmp = prog->css | (prog->pres << layout->pres_shift);
+ if (layout->have_slck_mck && prog->slckmck)
+ tmp |= AT91_PMC_CSSMCK_MCK;
+
+ pmc_write(pmc, AT91_PMC_PCKR(id), tmp);
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
+ wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);
+
+ return 0;
+}
+
+static int clk_programmable_is_ready(struct clk_hw *hw)
+{
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ struct at91_pmc *pmc = prog->pmc;
+
+ return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
+}
+
+static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
+
+ tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
+ prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;
+
+ return parent_rate >> prog->pres;
+}
+
+static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long best_rate = *parent_rate;
+ unsigned long best_diff;
+ unsigned long new_diff;
+ unsigned long cur_rate;
+ int shift = shift;
+
+ if (rate > *parent_rate)
+ return *parent_rate;
+ else
+ best_diff = *parent_rate - rate;
+
+ if (!best_diff)
+ return best_rate;
+
+ for (shift = 1; shift < PROG_PRES_MASK; shift++) {
+ cur_rate = *parent_rate >> shift;
+
+ if (cur_rate > rate)
+ new_diff = cur_rate - rate;
+ else
+ new_diff = rate - cur_rate;
+
+ if (!new_diff)
+ return cur_rate;
+
+ if (new_diff < best_diff) {
+ best_diff = new_diff;
+ best_rate = cur_rate;
+ }
+
+ if (rate > cur_rate)
+ break;
+ }
+
+ return best_rate;
+}
+
+static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ const struct clk_programmable_layout *layout = prog->layout;
+ if (index > layout->css_mask) {
+ if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) {
+ prog->css = 0;
+ prog->slckmck = 1;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+ }
+
+ prog->css = index;
+ return 0;
+}
+
+static u8 clk_programmable_get_parent(struct clk_hw *hw)
+{
+ u32 tmp;
+ u8 ret;
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
+
+ tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
+ prog->css = tmp & layout->css_mask;
+ ret = prog->css;
+ if (layout->have_slck_mck) {
+ prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK);
+ if (prog->slckmck && !ret)
+ ret = PROG_MAX_RM9200_CSS + 1;
+ }
+
+ return ret;
+}
+
+static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_programmable *prog = to_clk_programmable(hw);
+ unsigned long best_rate = parent_rate;
+ unsigned long best_diff;
+ unsigned long new_diff;
+ unsigned long cur_rate;
+ int shift = 0;
+
+ if (rate > parent_rate)
+ return parent_rate;
+ else
+ best_diff = parent_rate - rate;
+
+ if (!best_diff) {
+ prog->pres = shift;
+ return 0;
+ }
+
+ for (shift = 1; shift < PROG_PRES_MASK; shift++) {
+ cur_rate = parent_rate >> shift;
+
+ if (cur_rate > rate)
+ new_diff = cur_rate - rate;
+ else
+ new_diff = rate - cur_rate;
+
+ if (!new_diff)
+ break;
+
+ if (new_diff < best_diff) {
+ best_diff = new_diff;
+ best_rate = cur_rate;
+ }
+
+ if (rate > cur_rate)
+ break;
+ }
+
+ prog->pres = shift;
+ return 0;
+}
+
+static const struct clk_ops programmable_ops = {
+ .prepare = clk_programmable_prepare,
+ .is_prepared = clk_programmable_is_ready,
+ .recalc_rate = clk_programmable_recalc_rate,
+ .round_rate = clk_programmable_round_rate,
+ .get_parent = clk_programmable_get_parent,
+ .set_parent = clk_programmable_set_parent,
+ .set_rate = clk_programmable_set_rate,
+};
+
+static struct clk * __init
+at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
+ const char *name, const char **parent_names,
+ u8 num_parents, u8 id,
+ const struct clk_programmable_layout *layout)
+{
+ int ret;
+ struct clk_programmable *prog;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+ char irq_name[11];
+
+ if (id > PROG_ID_MAX)
+ return ERR_PTR(-EINVAL);
+
+ prog = kzalloc(sizeof(*prog), GFP_KERNEL);
+ if (!prog)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &programmable_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ prog->id = id;
+ prog->layout = layout;
+ prog->hw.init = &init;
+ prog->pmc = pmc;
+ prog->irq = irq;
+ init_waitqueue_head(&prog->wait);
+ irq_set_status_flags(prog->irq, IRQ_NOAUTOEN);
+ snprintf(irq_name, sizeof(irq_name), "clk-prog%d", id);
+ ret = request_irq(prog->irq, clk_programmable_irq_handler,
+ IRQF_TRIGGER_HIGH, irq_name, prog);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &prog->hw);
+ if (IS_ERR(clk))
+ kfree(prog);
+
+ return clk;
+}
+
+static const struct clk_programmable_layout at91rm9200_programmable_layout = {
+ .pres_shift = 2,
+ .css_mask = 0x3,
+ .have_slck_mck = 0,
+};
+
+static const struct clk_programmable_layout at91sam9g45_programmable_layout = {
+ .pres_shift = 2,
+ .css_mask = 0x3,
+ .have_slck_mck = 1,
+};
+
+static const struct clk_programmable_layout at91sam9x5_programmable_layout = {
+ .pres_shift = 4,
+ .css_mask = 0x7,
+ .have_slck_mck = 0,
+};
+
+static void __init
+of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
+ const struct clk_programmable_layout *layout)
+{
+ int num;
+ u32 id;
+ int i;
+ unsigned int irq;
+ struct clk *clk;
+ int num_parents;
+ const char *parent_names[PROG_SOURCE_MAX];
+ const char *name;
+ struct device_node *progclknp;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
+ return;
+
+ for (i = 0; i < num_parents; ++i) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ num = of_get_child_count(np);
+ if (!num || num > (PROG_ID_MAX + 1))
+ return;
+
+ for_each_child_of_node(np, progclknp) {
+ if (of_property_read_u32(progclknp, "reg", &id))
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = progclknp->name;
+
+ irq = irq_of_parse_and_map(progclknp, 0);
+ if (!irq)
+ continue;
+
+ clk = at91_clk_register_programmable(pmc, irq, name,
+ parent_names, num_parents,
+ id, layout);
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
+ }
+}
+
+
+void __init of_at91rm9200_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_prog_setup(np, pmc, &at91rm9200_programmable_layout);
+}
+
+void __init of_at91sam9g45_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_prog_setup(np, pmc, &at91sam9g45_programmable_layout);
+}
+
+void __init of_at91sam9x5_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_prog_setup(np, pmc, &at91sam9x5_programmable_layout);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define SMD_SOURCE_MAX 2
+
+#define SMD_DIV_SHIFT 8
+#define SMD_MAX_DIV 0xf
+
+struct at91sam9x5_clk_smd {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+};
+
+#define to_at91sam9x5_clk_smd(hw) \
+ container_of(hw, struct at91sam9x5_clk_smd, hw)
+
+static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ u8 smddiv;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+ struct at91_pmc *pmc = smd->pmc;
+
+ tmp = pmc_read(pmc, AT91_PMC_SMD);
+ smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT;
+ return parent_rate / (smddiv + 1);
+}
+
+static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long div;
+ unsigned long bestrate;
+ unsigned long tmp;
+
+ if (rate >= *parent_rate)
+ return *parent_rate;
+
+ div = *parent_rate / rate;
+ if (div > SMD_MAX_DIV)
+ return *parent_rate / (SMD_MAX_DIV + 1);
+
+ bestrate = *parent_rate / div;
+ tmp = *parent_rate / (div + 1);
+ if (bestrate - rate > rate - tmp)
+ bestrate = tmp;
+
+ return bestrate;
+}
+
+static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
+{
+ u32 tmp;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+ struct at91_pmc *pmc = smd->pmc;
+
+ if (index > 1)
+ return -EINVAL;
+ tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS;
+ if (index)
+ tmp |= AT91_PMC_SMDS;
+ pmc_write(pmc, AT91_PMC_SMD, tmp);
+ return 0;
+}
+
+static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw)
+{
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+ struct at91_pmc *pmc = smd->pmc;
+
+ return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS;
+}
+
+static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+ struct at91_pmc *pmc = smd->pmc;
+ unsigned long div = parent_rate / rate;
+
+ if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1))
+ return -EINVAL;
+ tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMD_DIV;
+ tmp |= (div - 1) << SMD_DIV_SHIFT;
+ pmc_write(pmc, AT91_PMC_SMD, tmp);
+
+ return 0;
+}
+
+static const struct clk_ops at91sam9x5_smd_ops = {
+ .recalc_rate = at91sam9x5_clk_smd_recalc_rate,
+ .round_rate = at91sam9x5_clk_smd_round_rate,
+ .get_parent = at91sam9x5_clk_smd_get_parent,
+ .set_parent = at91sam9x5_clk_smd_set_parent,
+ .set_rate = at91sam9x5_clk_smd_set_rate,
+};
+
+static struct clk * __init
+at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name,
+ const char **parent_names, u8 num_parents)
+{
+ struct at91sam9x5_clk_smd *smd;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ smd = kzalloc(sizeof(*smd), GFP_KERNEL);
+ if (!smd)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &at91sam9x5_smd_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ smd->hw.init = &init;
+ smd->pmc = pmc;
+
+ clk = clk_register(NULL, &smd->hw);
+ if (IS_ERR(clk))
+ kfree(smd);
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_smd_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ int i;
+ int num_parents;
+ const char *parent_names[SMD_SOURCE_MAX];
+ const char *name = np->name;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX)
+ return;
+
+ for (i = 0; i < num_parents; i++) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91sam9x5_clk_register_smd(pmc, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define SYSTEM_MAX_ID 31
+
+#define SYSTEM_MAX_NAME_SZ 32
+
+#define to_clk_system(hw) container_of(hw, struct clk_system, hw)
+struct clk_system {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ u8 id;
+};
+
+static int clk_system_enable(struct clk_hw *hw)
+{
+ struct clk_system *sys = to_clk_system(hw);
+ struct at91_pmc *pmc = sys->pmc;
+
+ pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id);
+ return 0;
+}
+
+static void clk_system_disable(struct clk_hw *hw)
+{
+ struct clk_system *sys = to_clk_system(hw);
+ struct at91_pmc *pmc = sys->pmc;
+
+ pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
+}
+
+static int clk_system_is_enabled(struct clk_hw *hw)
+{
+ struct clk_system *sys = to_clk_system(hw);
+ struct at91_pmc *pmc = sys->pmc;
+
+ return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id));
+}
+
+static const struct clk_ops system_ops = {
+ .enable = clk_system_enable,
+ .disable = clk_system_disable,
+ .is_enabled = clk_system_is_enabled,
+};
+
+static struct clk * __init
+at91_clk_register_system(struct at91_pmc *pmc, const char *name,
+ const char *parent_name, u8 id)
+{
+ struct clk_system *sys;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!parent_name || id > SYSTEM_MAX_ID)
+ return ERR_PTR(-EINVAL);
+
+ sys = kzalloc(sizeof(*sys), GFP_KERNEL);
+ if (!sys)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &system_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ /*
+ * CLK_IGNORE_UNUSED is used to avoid ddrck switch off.
+ * TODO : we should implement a driver supporting at91 ddr controller
+ * (see drivers/memory) which would request and enable the ddrck clock.
+ * When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
+ */
+ init.flags = CLK_IGNORE_UNUSED;
+
+ sys->id = id;
+ sys->hw.init = &init;
+ sys->pmc = pmc;
+
+ clk = clk_register(NULL, &sys->hw);
+ if (IS_ERR(clk))
+ kfree(sys);
+
+ return clk;
+}
+
+static void __init
+of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
+{
+ int num;
+ u32 id;
+ struct clk *clk;
+ const char *name;
+ struct device_node *sysclknp;
+ const char *parent_name;
+
+ num = of_get_child_count(np);
+ if (num > (SYSTEM_MAX_ID + 1))
+ return;
+
+ for_each_child_of_node(np, sysclknp) {
+ if (of_property_read_u32(sysclknp, "reg", &id))
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = sysclknp->name;
+
+ parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+ clk = at91_clk_register_system(pmc, name, parent_name, id);
+ if (IS_ERR(clk))
+ continue;
+
+ of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
+ }
+}
+
+void __init of_at91rm9200_clk_sys_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_sys_setup(np, pmc);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define USB_SOURCE_MAX 2
+
+#define SAM9X5_USB_DIV_SHIFT 8
+#define SAM9X5_USB_MAX_DIV 0xf
+
+#define RM9200_USB_DIV_SHIFT 28
+#define RM9200_USB_DIV_TAB_SIZE 4
+
+struct at91sam9x5_clk_usb {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+};
+
+#define to_at91sam9x5_clk_usb(hw) \
+ container_of(hw, struct at91sam9x5_clk_usb, hw)
+
+struct at91rm9200_clk_usb {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ u32 divisors[4];
+};
+
+#define to_at91rm9200_clk_usb(hw) \
+ container_of(hw, struct at91rm9200_clk_usb, hw)
+
+static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ u8 usbdiv;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ tmp = pmc_read(pmc, AT91_PMC_USB);
+ usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
+ return parent_rate / (usbdiv + 1);
+}
+
+static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long div;
+ unsigned long bestrate;
+ unsigned long tmp;
+
+ if (rate >= *parent_rate)
+ return *parent_rate;
+
+ div = *parent_rate / rate;
+ if (div >= SAM9X5_USB_MAX_DIV)
+ return *parent_rate / (SAM9X5_USB_MAX_DIV + 1);
+
+ bestrate = *parent_rate / div;
+ tmp = *parent_rate / (div + 1);
+ if (bestrate - rate > rate - tmp)
+ bestrate = tmp;
+
+ return bestrate;
+}
+
+static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
+{
+ u32 tmp;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ if (index > 1)
+ return -EINVAL;
+ tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS;
+ if (index)
+ tmp |= AT91_PMC_USBS;
+ pmc_write(pmc, AT91_PMC_USB, tmp);
+ return 0;
+}
+
+static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
+{
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS;
+}
+
+static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+ unsigned long div = parent_rate / rate;
+
+ if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV)
+ return -EINVAL;
+
+ tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
+ tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT;
+ pmc_write(pmc, AT91_PMC_USB, tmp);
+
+ return 0;
+}
+
+static const struct clk_ops at91sam9x5_usb_ops = {
+ .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
+ .round_rate = at91sam9x5_clk_usb_round_rate,
+ .get_parent = at91sam9x5_clk_usb_get_parent,
+ .set_parent = at91sam9x5_clk_usb_set_parent,
+ .set_rate = at91sam9x5_clk_usb_set_rate,
+};
+
+static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
+{
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ pmc_write(pmc, AT91_PMC_USB,
+ pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS);
+ return 0;
+}
+
+static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
+{
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ pmc_write(pmc, AT91_PMC_USB,
+ pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS);
+}
+
+static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
+{
+ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+
+ return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS);
+}
+
+static const struct clk_ops at91sam9n12_usb_ops = {
+ .enable = at91sam9n12_clk_usb_enable,
+ .disable = at91sam9n12_clk_usb_disable,
+ .is_enabled = at91sam9n12_clk_usb_is_enabled,
+ .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
+ .round_rate = at91sam9x5_clk_usb_round_rate,
+ .set_rate = at91sam9x5_clk_usb_set_rate,
+};
+
+static struct clk * __init
+at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
+ const char **parent_names, u8 num_parents)
+{
+ struct at91sam9x5_clk_usb *usb;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ usb = kzalloc(sizeof(*usb), GFP_KERNEL);
+ if (!usb)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &at91sam9x5_usb_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ usb->hw.init = &init;
+ usb->pmc = pmc;
+
+ clk = clk_register(NULL, &usb->hw);
+ if (IS_ERR(clk))
+ kfree(usb);
+
+ return clk;
+}
+
+static struct clk * __init
+at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
+ const char *parent_name)
+{
+ struct at91sam9x5_clk_usb *usb;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ usb = kzalloc(sizeof(*usb), GFP_KERNEL);
+ if (!usb)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &at91sam9n12_usb_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_GATE;
+
+ usb->hw.init = &init;
+ usb->pmc = pmc;
+
+ clk = clk_register(NULL, &usb->hw);
+ if (IS_ERR(clk))
+ kfree(usb);
+
+ return clk;
+}
+
+static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+ u32 tmp;
+ u8 usbdiv;
+
+ tmp = pmc_read(pmc, AT91_CKGR_PLLBR);
+ usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
+ if (usb->divisors[usbdiv])
+ return parent_rate / usb->divisors[usbdiv];
+
+ return 0;
+}
+
+static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+ unsigned long bestrate = 0;
+ int bestdiff = -1;
+ unsigned long tmprate;
+ int tmpdiff;
+ int i = 0;
+
+ for (i = 0; i < 4; i++) {
+ if (!usb->divisors[i])
+ continue;
+ tmprate = *parent_rate / usb->divisors[i];
+ if (tmprate < rate)
+ tmpdiff = rate - tmprate;
+ else
+ tmpdiff = tmprate - rate;
+
+ if (bestdiff < 0 || bestdiff > tmpdiff) {
+ bestrate = tmprate;
+ bestdiff = tmpdiff;
+ }
+
+ if (!bestdiff)
+ break;
+ }
+
+ return bestrate;
+}
+
+static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u32 tmp;
+ int i;
+ struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+ struct at91_pmc *pmc = usb->pmc;
+ unsigned long div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ return -EINVAL;
+ for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
+ if (usb->divisors[i] == div) {
+ tmp = pmc_read(pmc, AT91_CKGR_PLLBR) &
+ ~AT91_PMC_USBDIV;
+ tmp |= i << RM9200_USB_DIV_SHIFT;
+ pmc_write(pmc, AT91_CKGR_PLLBR, tmp);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static const struct clk_ops at91rm9200_usb_ops = {
+ .recalc_rate = at91rm9200_clk_usb_recalc_rate,
+ .round_rate = at91rm9200_clk_usb_round_rate,
+ .set_rate = at91rm9200_clk_usb_set_rate,
+};
+
+static struct clk * __init
+at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name,
+ const char *parent_name, const u32 *divisors)
+{
+ struct at91rm9200_clk_usb *usb;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ usb = kzalloc(sizeof(*usb), GFP_KERNEL);
+ if (!usb)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &at91rm9200_usb_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ usb->hw.init = &init;
+ usb->pmc = pmc;
+ memcpy(usb->divisors, divisors, sizeof(usb->divisors));
+
+ clk = clk_register(NULL, &usb->hw);
+ if (IS_ERR(clk))
+ kfree(usb);
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ int i;
+ int num_parents;
+ const char *parent_names[USB_SOURCE_MAX];
+ const char *name = np->name;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
+ return;
+
+ for (i = 0; i < num_parents; i++) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91sam9n12_clk_register_usb(pmc, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+ u32 divisors[4] = {0, 0, 0, 0};
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
+ if (!divisors[0])
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include "pmc.h"
+
+#define UTMI_FIXED_MUL 40
+
+struct clk_utmi {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+};
+
+#define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
+
+static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id)
+{
+ struct clk_utmi *utmi = (struct clk_utmi *)dev_id;
+
+ wake_up(&utmi->wait);
+ disable_irq_nosync(utmi->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_utmi_prepare(struct clk_hw *hw)
+{
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+ struct at91_pmc *pmc = utmi->pmc;
+ u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
+ AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
+
+ pmc_write(pmc, AT91_CKGR_UCKR, tmp);
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) {
+ enable_irq(utmi->irq);
+ wait_event(utmi->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
+ }
+
+ return 0;
+}
+
+static int clk_utmi_is_prepared(struct clk_hw *hw)
+{
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+ struct at91_pmc *pmc = utmi->pmc;
+
+ return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
+}
+
+static void clk_utmi_unprepare(struct clk_hw *hw)
+{
+ struct clk_utmi *utmi = to_clk_utmi(hw);
+ struct at91_pmc *pmc = utmi->pmc;
+ u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
+
+ pmc_write(pmc, AT91_CKGR_UCKR, tmp);
+}
+
+static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ /* UTMI clk is a fixed clk multiplier */
+ return parent_rate * UTMI_FIXED_MUL;
+}
+
+static const struct clk_ops utmi_ops = {
+ .prepare = clk_utmi_prepare,
+ .unprepare = clk_utmi_unprepare,
+ .is_prepared = clk_utmi_is_prepared,
+ .recalc_rate = clk_utmi_recalc_rate,
+};
+
+static struct clk * __init
+at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq,
+ const char *name, const char *parent_name)
+{
+ int ret;
+ struct clk_utmi *utmi;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
+ if (!utmi)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &utmi_ops;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.flags = CLK_SET_RATE_GATE;
+
+ utmi->hw.init = &init;
+ utmi->pmc = pmc;
+ utmi->irq = irq;
+ init_waitqueue_head(&utmi->wait);
+ irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN);
+ ret = request_irq(utmi->irq, clk_utmi_irq_handler,
+ IRQF_TRIGGER_HIGH, "clk-utmi", utmi);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &utmi->hw);
+ if (IS_ERR(clk))
+ kfree(utmi);
+
+ return clk;
+}
+
+static void __init
+of_at91_clk_utmi_setup(struct device_node *np, struct at91_pmc *pmc)
+{
+ unsigned int irq;
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_utmi(pmc, irq, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ return;
+}
+
+void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ of_at91_clk_utmi_setup(np, pmc);
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+
+#include <asm/proc-fns.h>
+
+#include "pmc.h"
+
+void __iomem *at91_pmc_base;
+EXPORT_SYMBOL_GPL(at91_pmc_base);
+
+void at91sam9_idle(void)
+{
+ at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
+int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range)
+{
+ u32 min, max;
+ int ret;
+
+ ret = of_property_read_u32_index(np, propname, 0, &min);
+ if (ret)
+ return ret;
+
+ ret = of_property_read_u32_index(np, propname, 1, &max);
+ if (ret)
+ return ret;
+
+ if (range) {
+ range->min = min;
+ range->max = max;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+
+static void pmc_irq_mask(struct irq_data *d)
+{
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+ pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq);
+}
+
+static void pmc_irq_unmask(struct irq_data *d)
+{
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+ pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq);
+}
+
+static int pmc_irq_set_type(struct irq_data *d, unsigned type)
+{
+ if (type != IRQ_TYPE_LEVEL_HIGH) {
+ pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct irq_chip pmc_irq = {
+ .name = "PMC",
+ .irq_disable = pmc_irq_mask,
+ .irq_mask = pmc_irq_mask,
+ .irq_unmask = pmc_irq_unmask,
+ .irq_set_type = pmc_irq_set_type,
+};
+
+static struct lock_class_key pmc_lock_class;
+
+static int pmc_irq_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct at91_pmc *pmc = h->host_data;
+
+ irq_set_lockdep_class(virq, &pmc_lock_class);
+
+ irq_set_chip_and_handler(virq, &pmc_irq,
+ handle_level_irq);
+ set_irq_flags(virq, IRQF_VALID);
+ irq_set_chip_data(virq, pmc);
+
+ return 0;
+}
+
+static int pmc_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type)
+{
+ struct at91_pmc *pmc = d->host_data;
+ const struct at91_pmc_caps *caps = pmc->caps;
+
+ if (WARN_ON(intsize < 1))
+ return -EINVAL;
+
+ *out_hwirq = intspec[0];
+
+ if (!(caps->available_irqs & (1 << *out_hwirq)))
+ return -EINVAL;
+
+ *out_type = IRQ_TYPE_LEVEL_HIGH;
+
+ return 0;
+}
+
+static struct irq_domain_ops pmc_irq_ops = {
+ .map = pmc_irq_map,
+ .xlate = pmc_irq_domain_xlate,
+};
+
+static irqreturn_t pmc_irq_handler(int irq, void *data)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)data;
+ unsigned long sr;
+ int n;
+
+ sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR);
+ if (!sr)
+ return IRQ_NONE;
+
+ for_each_set_bit(n, &sr, BITS_PER_LONG)
+ generic_handle_irq(irq_find_mapping(pmc->irqdomain, n));
+
+ return IRQ_HANDLED;
+}
+
+static const struct at91_pmc_caps at91rm9200_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+ AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+ AT91_PMC_PCK3RDY,
+};
+
+static const struct at91_pmc_caps at91sam9260_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+ AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY,
+};
+
+static const struct at91_pmc_caps at91sam9g45_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+ AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY,
+};
+
+static const struct at91_pmc_caps at91sam9n12_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB |
+ AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS |
+ AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
+};
+
+static const struct at91_pmc_caps at91sam9x5_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+ AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS |
+ AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
+};
+
+static const struct at91_pmc_caps sama5d3_caps = {
+ .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+ AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+ AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+ AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
+ AT91_PMC_CFDEV,
+};
+
+static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
+ void __iomem *regbase, int virq,
+ const struct at91_pmc_caps *caps)
+{
+ struct at91_pmc *pmc;
+
+ if (!regbase || !virq || !caps)
+ return NULL;
+
+ at91_pmc_base = regbase;
+
+ pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+ if (!pmc)
+ return NULL;
+
+ spin_lock_init(&pmc->lock);
+ pmc->regbase = regbase;
+ pmc->virq = virq;
+ pmc->caps = caps;
+
+ pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc);
+
+ if (!pmc->irqdomain)
+ goto out_free_pmc;
+
+ pmc_write(pmc, AT91_PMC_IDR, 0xffffffff);
+ if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc))
+ goto out_remove_irqdomain;
+
+ return pmc;
+
+out_remove_irqdomain:
+ irq_domain_remove(pmc->irqdomain);
+out_free_pmc:
+ kfree(pmc);
+
+ return NULL;
+}
+
+static const struct of_device_id pmc_clk_ids[] __initdata = {
+ /* Main clock */
+ {
+ .compatible = "atmel,at91rm9200-clk-main",
+ .data = of_at91rm9200_clk_main_setup,
+ },
+ /* PLL clocks */
+ {
+ .compatible = "atmel,at91rm9200-clk-pll",
+ .data = of_at91rm9200_clk_pll_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9g45-clk-pll",
+ .data = of_at91sam9g45_clk_pll_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9g20-clk-pllb",
+ .data = of_at91sam9g20_clk_pllb_setup,
+ },
+ {
+ .compatible = "atmel,sama5d3-clk-pll",
+ .data = of_sama5d3_clk_pll_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-plldiv",
+ .data = of_at91sam9x5_clk_plldiv_setup,
+ },
+ /* Master clock */
+ {
+ .compatible = "atmel,at91rm9200-clk-master",
+ .data = of_at91rm9200_clk_master_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-master",
+ .data = of_at91sam9x5_clk_master_setup,
+ },
+ /* System clocks */
+ {
+ .compatible = "atmel,at91rm9200-clk-system",
+ .data = of_at91rm9200_clk_sys_setup,
+ },
+ /* Peripheral clocks */
+ {
+ .compatible = "atmel,at91rm9200-clk-peripheral",
+ .data = of_at91rm9200_clk_periph_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-peripheral",
+ .data = of_at91sam9x5_clk_periph_setup,
+ },
+ /* Programmable clocks */
+#if defined(CONFIG_AT91_PROGRAMMABLE_CLOCKS)
+ {
+ .compatible = "atmel,at91rm9200-clk-programmable",
+ .data = of_at91rm9200_clk_prog_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9g45-clk-programmable",
+ .data = of_at91sam9g45_clk_prog_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-programmable",
+ .data = of_at91sam9x5_clk_prog_setup,
+ },
+#endif
+ /* UTMI clock */
+#if defined(CONFIG_HAVE_AT91_UTMI)
+ {
+ .compatible = "atmel,at91sam9x5-clk-utmi",
+ .data = of_at91sam9x5_clk_utmi_setup,
+ },
+#endif
+ /* USB clock */
+#if defined(CONFIG_HAVE_AT91_USB_CLK)
+ {
+ .compatible = "atmel,at91rm9200-clk-usb",
+ .data = of_at91rm9200_clk_usb_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-usb",
+ .data = of_at91sam9x5_clk_usb_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9n12-clk-usb",
+ .data = of_at91sam9n12_clk_usb_setup,
+ },
+#endif
+ /* SMD clock */
+#if defined(CONFIG_HAVE_AT91_SMD)
+ {
+ .compatible = "atmel,at91sam9x5-clk-smd",
+ .data = of_at91sam9x5_clk_smd_setup,
+ },
+#endif
+ { /*sentinel*/ }
+};
+
+static void __init of_at91_pmc_setup(struct device_node *np,
+ const struct at91_pmc_caps *caps)
+{
+ struct at91_pmc *pmc;
+ struct device_node *childnp;
+ void (*clk_setup)(struct device_node *, struct at91_pmc *);
+ const struct of_device_id *clk_id;
+ void __iomem *regbase = of_iomap(np, 0);
+ int virq;
+
+ if (!regbase)
+ return;
+
+ virq = irq_of_parse_and_map(np, 0);
+ if (!virq)
+ return;
+
+ pmc = at91_pmc_init(np, regbase, virq, caps);
+ if (!pmc)
+ return;
+ for_each_child_of_node(np, childnp) {
+ clk_id = of_match_node(pmc_clk_ids, childnp);
+ if (!clk_id)
+ continue;
+ clk_setup = clk_id->data;
+ clk_setup(childnp, pmc);
+ }
+}
+
+static void __init of_at91rm9200_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &at91rm9200_caps);
+}
+CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc",
+ of_at91rm9200_pmc_setup);
+
+static void __init of_at91sam9260_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &at91sam9260_caps);
+}
+CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc",
+ of_at91sam9260_pmc_setup);
+
+static void __init of_at91sam9g45_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &at91sam9g45_caps);
+}
+CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc",
+ of_at91sam9g45_pmc_setup);
+
+static void __init of_at91sam9n12_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &at91sam9n12_caps);
+}
+CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc",
+ of_at91sam9n12_pmc_setup);
+
+static void __init of_at91sam9x5_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &at91sam9x5_caps);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc",
+ of_at91sam9x5_pmc_setup);
+
+static void __init of_sama5d3_pmc_setup(struct device_node *np)
+{
+ of_at91_pmc_setup(np, &sama5d3_caps);
+}
+CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc",
+ of_sama5d3_pmc_setup);
--- /dev/null
+/*
+ * drivers/clk/at91/pmc.h
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PMC_H_
+#define __PMC_H_
+
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/spinlock.h>
+
+struct clk_range {
+ unsigned long min;
+ unsigned long max;
+};
+
+#define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
+
+struct at91_pmc_caps {
+ u32 available_irqs;
+};
+
+struct at91_pmc {
+ void __iomem *regbase;
+ int virq;
+ spinlock_t lock;
+ const struct at91_pmc_caps *caps;
+ struct irq_domain *irqdomain;
+};
+
+static inline void pmc_lock(struct at91_pmc *pmc)
+{
+ spin_lock(&pmc->lock);
+}
+
+static inline void pmc_unlock(struct at91_pmc *pmc)
+{
+ spin_unlock(&pmc->lock);
+}
+
+static inline u32 pmc_read(struct at91_pmc *pmc, int offset)
+{
+ return readl(pmc->regbase + offset);
+}
+
+static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
+{
+ writel(value, pmc->regbase + offset);
+}
+
+int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range);
+
+extern void __init of_at91rm9200_clk_main_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
+extern void __init of_at91rm9200_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9g45_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_sama5d3_clk_pll_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
+extern void __init of_at91rm9200_clk_master_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_master_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
+extern void __init of_at91rm9200_clk_sys_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
+extern void __init of_at91rm9200_clk_periph_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_periph_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
+#if defined(CONFIG_AT91_PROGRAMMABLE_CLOCKS)
+extern void __init of_at91rm9200_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9g45_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_prog_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+#endif
+
+#if defined(CONFIG_HAVE_AT91_UTMI)
+extern void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+#endif
+
+#if defined(CONFIG_HAVE_AT91_USB_CLK)
+extern void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+#endif
+
+#if defined(CONFIG_HAVE_AT91_SMD)
+extern void __init of_at91sam9x5_clk_smd_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+#endif
+
+#endif /* __PMC_H_ */
DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6),
DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6),
DIV(none, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4),
- DIV(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8),
+ DIV_F(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8,
+ CLK_SET_RATE_PARENT, 0),
DIV(none, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
DIV(none, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
DIV(none, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
--- /dev/null
+obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o
+
+# for emply built-in.o
+obj-n := dummy
--- /dev/null
+/*
+ * r8a7790 Common Clock Framework support
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define CPG_DIV6_CKSTP BIT(8)
+#define CPG_DIV6_DIV(d) ((d) & 0x3f)
+#define CPG_DIV6_DIV_MASK 0x3f
+
+/**
+ * struct div6_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @reg: IO-remapped register
+ * @div: divisor value (1-64)
+ */
+struct div6_clock {
+ struct clk_hw hw;
+ void __iomem *reg;
+ unsigned int div;
+};
+
+#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
+
+static int cpg_div6_clock_enable(struct clk_hw *hw)
+{
+ struct div6_clock *clock = to_div6_clock(hw);
+
+ clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+ return 0;
+}
+
+static void cpg_div6_clock_disable(struct clk_hw *hw)
+{
+ struct div6_clock *clock = to_div6_clock(hw);
+
+ /* DIV6 clocks require the divisor field to be non-zero when stopping
+ * the clock.
+ */
+ clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK),
+ clock->reg);
+}
+
+static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
+{
+ struct div6_clock *clock = to_div6_clock(hw);
+
+ return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP);
+}
+
+static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct div6_clock *clock = to_div6_clock(hw);
+ unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+ return parent_rate / div;
+}
+
+static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
+ unsigned long parent_rate)
+{
+ unsigned int div;
+
+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
+ return clamp_t(unsigned int, div, 1, 64);
+}
+
+static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate);
+
+ return *parent_rate / div;
+}
+
+static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct div6_clock *clock = to_div6_clock(hw);
+ unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate);
+
+ clock->div = div;
+
+ /* Only program the new divisor if the clock isn't stopped. */
+ if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP))
+ clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+ return 0;
+}
+
+static const struct clk_ops cpg_div6_clock_ops = {
+ .enable = cpg_div6_clock_enable,
+ .disable = cpg_div6_clock_disable,
+ .is_enabled = cpg_div6_clock_is_enabled,
+ .recalc_rate = cpg_div6_clock_recalc_rate,
+ .round_rate = cpg_div6_clock_round_rate,
+ .set_rate = cpg_div6_clock_set_rate,
+};
+
+static void __init cpg_div6_clock_init(struct device_node *np)
+{
+ struct clk_init_data init;
+ struct div6_clock *clock;
+ const char *parent_name;
+ const char *name;
+ struct clk *clk;
+ int ret;
+
+ clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+ if (!clock) {
+ pr_err("%s: failed to allocate %s DIV6 clock\n",
+ __func__, np->name);
+ return;
+ }
+
+ /* Remap the clock register and read the divisor. Disabling the
+ * clock overwrites the divisor, so we need to cache its value for the
+ * enable operation.
+ */
+ clock->reg = of_iomap(np, 0);
+ if (clock->reg == NULL) {
+ pr_err("%s: failed to map %s DIV6 clock register\n",
+ __func__, np->name);
+ goto error;
+ }
+
+ clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+ /* Parse the DT properties. */
+ ret = of_property_read_string(np, "clock-output-names", &name);
+ if (ret < 0) {
+ pr_err("%s: failed to get %s DIV6 clock output name\n",
+ __func__, np->name);
+ goto error;
+ }
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (parent_name == NULL) {
+ pr_err("%s: failed to get %s DIV6 clock parent name\n",
+ __func__, np->name);
+ goto error;
+ }
+
+ /* Register the clock. */
+ init.name = name;
+ init.ops = &cpg_div6_clock_ops;
+ init.flags = CLK_IS_BASIC;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clock->hw.init = &init;
+
+ clk = clk_register(NULL, &clock->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
+ __func__, np->name, PTR_ERR(clk));
+ goto error;
+ }
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+ return;
+
+error:
+ if (clock->reg)
+ iounmap(clock->reg);
+ kfree(clock);
+}
+CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
--- /dev/null
+/*
+ * R-Car MSTP clocks
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+/*
+ * MSTP clocks. We can't use standard gate clocks as we need to poll on the
+ * status register when enabling the clock.
+ */
+
+#define MSTP_MAX_CLOCKS 32
+
+/**
+ * struct mstp_clock_group - MSTP gating clocks group
+ *
+ * @data: clocks in this group
+ * @smstpcr: module stop control register
+ * @mstpsr: module stop status register (optional)
+ * @lock: protects writes to SMSTPCR
+ */
+struct mstp_clock_group {
+ struct clk_onecell_data data;
+ void __iomem *smstpcr;
+ void __iomem *mstpsr;
+ spinlock_t lock;
+};
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @bit_index: control bit index
+ * @group: MSTP clocks group
+ */
+struct mstp_clock {
+ struct clk_hw hw;
+ u32 bit_index;
+ struct mstp_clock_group *group;
+};
+
+#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
+{
+ struct mstp_clock *clock = to_mstp_clock(hw);
+ struct mstp_clock_group *group = clock->group;
+ u32 bitmask = BIT(clock->bit_index);
+ unsigned long flags;
+ unsigned int i;
+ u32 value;
+
+ spin_lock_irqsave(&group->lock, flags);
+
+ value = clk_readl(group->smstpcr);
+ if (enable)
+ value &= ~bitmask;
+ else
+ value |= bitmask;
+ clk_writel(value, group->smstpcr);
+
+ spin_unlock_irqrestore(&group->lock, flags);
+
+ if (!enable || !group->mstpsr)
+ return 0;
+
+ for (i = 1000; i > 0; --i) {
+ if (!(clk_readl(group->mstpsr) & bitmask))
+ break;
+ cpu_relax();
+ }
+
+ if (!i) {
+ pr_err("%s: failed to enable %p[%d]\n", __func__,
+ group->smstpcr, clock->bit_index);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int cpg_mstp_clock_enable(struct clk_hw *hw)
+{
+ return cpg_mstp_clock_endisable(hw, true);
+}
+
+static void cpg_mstp_clock_disable(struct clk_hw *hw)
+{
+ cpg_mstp_clock_endisable(hw, false);
+}
+
+static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
+{
+ struct mstp_clock *clock = to_mstp_clock(hw);
+ struct mstp_clock_group *group = clock->group;
+ u32 value;
+
+ if (group->mstpsr)
+ value = clk_readl(group->mstpsr);
+ else
+ value = clk_readl(group->smstpcr);
+
+ return !!(value & BIT(clock->bit_index));
+}
+
+static const struct clk_ops cpg_mstp_clock_ops = {
+ .enable = cpg_mstp_clock_enable,
+ .disable = cpg_mstp_clock_disable,
+ .is_enabled = cpg_mstp_clock_is_enabled,
+};
+
+static struct clk * __init
+cpg_mstp_clock_register(const char *name, const char *parent_name,
+ unsigned int index, struct mstp_clock_group *group)
+{
+ struct clk_init_data init;
+ struct mstp_clock *clock;
+ struct clk *clk;
+
+ clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+ if (!clock) {
+ pr_err("%s: failed to allocate MSTP clock.\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.ops = &cpg_mstp_clock_ops;
+ init.flags = CLK_IS_BASIC;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clock->bit_index = index;
+ clock->group = group;
+ clock->hw.init = &init;
+
+ clk = clk_register(NULL, &clock->hw);
+
+ if (IS_ERR(clk))
+ kfree(clock);
+
+ return clk;
+}
+
+static void __init cpg_mstp_clocks_init(struct device_node *np)
+{
+ struct mstp_clock_group *group;
+ struct clk **clks;
+ unsigned int i;
+
+ group = kzalloc(sizeof(*group), GFP_KERNEL);
+ clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
+ if (group == NULL || clks == NULL) {
+ kfree(group);
+ kfree(clks);
+ pr_err("%s: failed to allocate group\n", __func__);
+ return;
+ }
+
+ spin_lock_init(&group->lock);
+ group->data.clks = clks;
+
+ group->smstpcr = of_iomap(np, 0);
+ group->mstpsr = of_iomap(np, 1);
+
+ if (group->smstpcr == NULL) {
+ pr_err("%s: failed to remap SMSTPCR\n", __func__);
+ kfree(group);
+ kfree(clks);
+ return;
+ }
+
+ for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
+ const char *parent_name;
+ const char *name;
+ u32 clkidx;
+ int ret;
+
+ /* Skip clocks with no name. */
+ ret = of_property_read_string_index(np, "clock-output-names",
+ i, &name);
+ if (ret < 0 || strlen(name) == 0)
+ continue;
+
+ parent_name = of_clk_get_parent_name(np, i);
+ ret = of_property_read_u32_index(np, "renesas,clock-indices", i,
+ &clkidx);
+ if (parent_name == NULL || ret < 0)
+ break;
+
+ if (clkidx >= MSTP_MAX_CLOCKS) {
+ pr_err("%s: invalid clock %s %s index %u)\n",
+ __func__, np->name, name, clkidx);
+ continue;
+ }
+
+ clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i,
+ group);
+ if (!IS_ERR(clks[clkidx])) {
+ group->data.clk_num = max(group->data.clk_num, clkidx);
+ /*
+ * Register a clkdev to let board code retrieve the
+ * clock by name and register aliases for non-DT
+ * devices.
+ *
+ * FIXME: Remove this when all devices that require a
+ * clock will be instantiated from DT.
+ */
+ clk_register_clkdev(clks[clkidx], name, NULL);
+ } else {
+ pr_err("%s: failed to register %s %s clock (%ld)\n",
+ __func__, np->name, name, PTR_ERR(clks[clkidx]));
+ }
+ }
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
+}
+CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
--- /dev/null
+/*
+ * rcar_gen2 Core CPG Clocks
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct rcar_gen2_cpg {
+ struct clk_onecell_data data;
+ spinlock_t lock;
+ void __iomem *reg;
+};
+
+#define CPG_SDCKCR 0x00000074
+#define CPG_PLL0CR 0x000000d8
+#define CPG_FRQCRC 0x000000e0
+#define CPG_FRQCRC_ZFC_MASK (0x1f << 8)
+#define CPG_FRQCRC_ZFC_SHIFT 8
+
+/* -----------------------------------------------------------------------------
+ * Z Clock
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable. clk->rate = parent->rate * mult / 32
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+struct cpg_z_clk {
+ struct clk_hw hw;
+ void __iomem *reg;
+};
+
+#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct cpg_z_clk *zclk = to_z_clk(hw);
+ unsigned int mult;
+ unsigned int val;
+
+ val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK)
+ >> CPG_FRQCRC_ZFC_SHIFT;
+ mult = 32 - val;
+
+ return div_u64((u64)parent_rate * mult, 32);
+}
+
+static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long prate = *parent_rate;
+ unsigned int mult;
+
+ if (!prate)
+ prate = 1;
+
+ mult = div_u64((u64)rate * 32, prate);
+ mult = clamp(mult, 1U, 32U);
+
+ return *parent_rate / 32 * mult;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct cpg_z_clk *zclk = to_z_clk(hw);
+ unsigned int mult;
+ u32 val;
+
+ mult = div_u64((u64)rate * 32, parent_rate);
+ mult = clamp(mult, 1U, 32U);
+
+ val = clk_readl(zclk->reg);
+ val &= ~CPG_FRQCRC_ZFC_MASK;
+ val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT;
+ clk_writel(val, zclk->reg);
+
+ return 0;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+ .recalc_rate = cpg_z_clk_recalc_rate,
+ .round_rate = cpg_z_clk_round_rate,
+ .set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
+{
+ static const char *parent_name = "pll0";
+ struct clk_init_data init;
+ struct cpg_z_clk *zclk;
+ struct clk *clk;
+
+ zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+ if (!zclk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = "z";
+ init.ops = &cpg_z_clk_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ zclk->reg = cpg->reg + CPG_FRQCRC;
+ zclk->hw.init = &init;
+
+ clk = clk_register(NULL, &zclk->hw);
+ if (IS_ERR(clk))
+ kfree(zclk);
+
+ return clk;
+}
+
+/* -----------------------------------------------------------------------------
+ * CPG Clock Data
+ */
+
+/*
+ * MD EXTAL PLL0 PLL1 PLL3
+ * 14 13 19 (MHz) *1 *1
+ *---------------------------------------------------
+ * 0 0 0 15 x 1 x172/2 x208/2 x106
+ * 0 0 1 15 x 1 x172/2 x208/2 x88
+ * 0 1 0 20 x 1 x130/2 x156/2 x80
+ * 0 1 1 20 x 1 x130/2 x156/2 x66
+ * 1 0 0 26 / 2 x200/2 x240/2 x122
+ * 1 0 1 26 / 2 x200/2 x240/2 x102
+ * 1 1 0 30 / 2 x172/2 x208/2 x106
+ * 1 1 1 30 / 2 x172/2 x208/2 x88
+ *
+ * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
+ (((md) & BIT(13)) >> 12) | \
+ (((md) & BIT(19)) >> 19))
+struct cpg_pll_config {
+ unsigned int extal_div;
+ unsigned int pll1_mult;
+ unsigned int pll3_mult;
+};
+
+static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
+ { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 },
+ { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 },
+};
+
+/* SDHI divisors */
+static const struct clk_div_table cpg_sdh_div_table[] = {
+ { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
+ { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
+ { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 },
+};
+
+static const struct clk_div_table cpg_sd01_div_table[] = {
+ { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 },
+ { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 },
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+static u32 cpg_mode __initdata;
+
+static struct clk * __init
+rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
+ const struct cpg_pll_config *config,
+ const char *name)
+{
+ const struct clk_div_table *table = NULL;
+ const char *parent_name = "main";
+ unsigned int shift;
+ unsigned int mult = 1;
+ unsigned int div = 1;
+
+ if (!strcmp(name, "main")) {
+ parent_name = of_clk_get_parent_name(np, 0);
+ div = config->extal_div;
+ } else if (!strcmp(name, "pll0")) {
+ /* PLL0 is a configurable multiplier clock. Register it as a
+ * fixed factor clock for now as there's no generic multiplier
+ * clock implementation and we currently have no need to change
+ * the multiplier value.
+ */
+ u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+ mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+ } else if (!strcmp(name, "pll1")) {
+ mult = config->pll1_mult / 2;
+ } else if (!strcmp(name, "pll3")) {
+ mult = config->pll3_mult;
+ } else if (!strcmp(name, "lb")) {
+ div = cpg_mode & BIT(18) ? 36 : 24;
+ } else if (!strcmp(name, "qspi")) {
+ div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2)
+ ? 16 : 20;
+ } else if (!strcmp(name, "sdh")) {
+ table = cpg_sdh_div_table;
+ shift = 8;
+ } else if (!strcmp(name, "sd0")) {
+ table = cpg_sd01_div_table;
+ shift = 4;
+ } else if (!strcmp(name, "sd1")) {
+ table = cpg_sd01_div_table;
+ shift = 0;
+ } else if (!strcmp(name, "z")) {
+ return cpg_z_clk_register(cpg);
+ } else {
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!table)
+ return clk_register_fixed_factor(NULL, name, parent_name, 0,
+ mult, div);
+ else
+ return clk_register_divider_table(NULL, name, parent_name, 0,
+ cpg->reg + CPG_SDCKCR, shift,
+ 4, 0, table, &cpg->lock);
+}
+
+static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
+{
+ const struct cpg_pll_config *config;
+ struct rcar_gen2_cpg *cpg;
+ struct clk **clks;
+ unsigned int i;
+ int num_clks;
+
+ num_clks = of_property_count_strings(np, "clock-output-names");
+ if (num_clks < 0) {
+ pr_err("%s: failed to count clocks\n", __func__);
+ return;
+ }
+
+ cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+ clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL);
+ if (cpg == NULL || clks == NULL) {
+ /* We're leaking memory on purpose, there's no point in cleaning
+ * up as the system won't boot anyway.
+ */
+ pr_err("%s: failed to allocate cpg\n", __func__);
+ return;
+ }
+
+ spin_lock_init(&cpg->lock);
+
+ cpg->data.clks = clks;
+ cpg->data.clk_num = num_clks;
+
+ cpg->reg = of_iomap(np, 0);
+ if (WARN_ON(cpg->reg == NULL))
+ return;
+
+ config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+ for (i = 0; i < num_clks; ++i) {
+ const char *name;
+ struct clk *clk;
+
+ of_property_read_string_index(np, "clock-output-names", i,
+ &name);
+
+ clk = rcar_gen2_cpg_register_clock(np, cpg, config, name);
+ if (IS_ERR(clk))
+ pr_err("%s: failed to register %s %s clock (%ld)\n",
+ __func__, np->name, name, PTR_ERR(clk));
+ else
+ cpg->data.clks[i] = clk;
+ }
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
+ rcar_gen2_cpg_clocks_init);
+
+void __init rcar_gen2_clocks_init(u32 mode)
+{
+ cpg_mode = mode;
+
+ of_clk_init(NULL);
+}
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
--- /dev/null
+/*
+ * 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 */
#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))
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,
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) {
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,
.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))
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,
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);
}
#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)
#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)
#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))
{
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);
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;
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;
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);
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);
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;
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)
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);
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);
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;
_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) {
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;
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;
}
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;
}
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);
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);
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));
.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)
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);
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)
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:
#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;
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)
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);
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);
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,
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);
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);
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);
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;
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.
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);
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);
}
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
--- /dev/null
+/*
+ * 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;
+ }
+}
+
--- /dev/null
+/*
+ * 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;
+ }
+}
+
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
+}
+
#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
#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
#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
#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)
#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 */
} 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,
.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 = {
.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 = {
.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 = {
.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 = {
.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[] = {
.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[] = {
.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 = {
.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[] = {
.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[] = {
.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},
};
.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 = {
.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 */
#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;
/* 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",
};
{ .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;
/* 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;
/* 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;
}
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)
{
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",
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);
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 */
* 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);
}
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) {
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;
--- /dev/null
+/*
+ * 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);
#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)
#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
#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
#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
} 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 },
.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 = {
.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 = {
.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 = {
.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 = {
.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[] = {
.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 = {
.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 = {
.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)
/* 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",
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",
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",
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",
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",
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;
}
"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)
/* 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,
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)
/* 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 */
};
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);
}
/*
* 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 = {
static void __init tegra20_clock_init(struct device_node *np)
{
- int i;
struct device_node *node;
clk_base = of_iomap(np, 0);
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;
#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)
#define SYSTEM_CLK_RATE 0x030
+#define TEGRA30_CLK_PERIPH_BANKS 5
+
#define PLLC_BASE 0x80
#define PLLC_MISC 0x8c
#define PLLM_BASE 0x90
#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)
} 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.
.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 = {
.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 = {
.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 = {
.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 = {
.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 = {
.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 = {
.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 = {
.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 = {
.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;
/* 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",
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",
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,
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",
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
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,
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)
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,
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 */
};
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);
}
/*
* 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 = {
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) {
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;
#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)
{
}
}
+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)
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);
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;
};
/**
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;
};
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
*
#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
#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, \
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;
#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, \
#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
}, \
}
+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);
config ARM_ARCH_TIMER_EVTSTREAM
bool "Support for ARM architected timer event stream generation"
default y if ARM_ARCH_TIMER
+ depends on ARM_ARCH_TIMER
help
This option enables support for event stream generation based on
the ARM architected timer. It is used for waking up CPUs executing
MCT_L1_IRQ,
MCT_L2_IRQ,
MCT_L3_IRQ,
+ MCT_L4_IRQ,
+ MCT_L5_IRQ,
+ MCT_L6_IRQ,
+ MCT_L7_IRQ,
MCT_NR_IRQS,
};
static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
{
- pm_genpd_syscore_poweroff(&ced_to_sh_cmt(ced)->pdev->dev);
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ pm_genpd_syscore_poweroff(&p->pdev->dev);
+ clk_unprepare(p->clk);
}
static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
{
- pm_genpd_syscore_poweron(&ced_to_sh_cmt(ced)->pdev->dev);
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ clk_prepare(p->clk);
+ pm_genpd_syscore_poweron(&p->pdev->dev);
}
static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
goto err2;
}
+ ret = clk_prepare(p->clk);
+ if (ret < 0)
+ goto err3;
+
if (res2 && (resource_size(res2) == 4)) {
/* assume both CMSTR and CMCSR to be 32-bit */
p->read_control = sh_cmt_read32;
cfg->clocksource_rating);
if (ret) {
dev_err(&p->pdev->dev, "registration failed\n");
- goto err3;
+ goto err4;
}
p->cs_enabled = false;
ret = setup_irq(irq, &p->irqaction);
if (ret) {
dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
- goto err3;
+ goto err4;
}
platform_set_drvdata(pdev, p);
return 0;
+err4:
+ clk_unprepare(p->clk);
err3:
clk_put(p->clk);
err2:
goto err1;
}
- return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
- cfg->clockevent_rating);
+ ret = clk_prepare(p->clk);
+ if (ret < 0)
+ goto err2;
+
+ ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
+ cfg->clockevent_rating);
+ if (ret < 0)
+ goto err3;
+
+ return 0;
+ err3:
+ clk_unprepare(p->clk);
+ err2:
+ clk_put(p->clk);
err1:
iounmap(p->mapbase);
err0:
ret = PTR_ERR(p->clk);
goto err1;
}
+
+ ret = clk_prepare(p->clk);
+ if (ret < 0)
+ goto err2;
+
p->cs_enabled = false;
p->enable_count = 0;
- return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
- cfg->clockevent_rating,
- cfg->clocksource_rating);
+ ret = sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ if (ret < 0)
+ goto err3;
+
+ return 0;
+
+ err3:
+ clk_unprepare(p->clk);
+ err2:
+ clk_put(p->clk);
err1:
iounmap(p->mapbase);
err0:
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/tick.h>
#include <trace/events/power.h>
static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
#endif
+/* Flag to suspend/resume CPUFreq governors */
+static bool cpufreq_suspended;
+
static inline bool has_target(void)
{
return cpufreq_driver->target_index || cpufreq_driver->target;
.remove_dev = cpufreq_remove_dev,
};
+void cpufreq_suspend(void)
+{
+ struct cpufreq_policy *policy;
+
+ if (!has_target())
+ return;
+
+ pr_debug("%s: Suspending Governors\n", __func__);
+
+ list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+ if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
+ pr_err("%s: Failed to stop governor for policy: %p\n",
+ __func__, policy);
+
+ cpufreq_suspended = true;
+}
+
+void cpufreq_resume(void)
+{
+ struct cpufreq_policy *policy;
+
+ if (!has_target())
+ return;
+
+ pr_debug("%s: Resuming Governors\n", __func__);
+
+ cpufreq_suspended = false;
+
+ list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+ if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
+ || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
+ pr_err("%s: Failed to start governor for policy: %p\n",
+ __func__, policy);
+}
+
/**
* cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
*
struct cpufreq_governor *gov = NULL;
#endif
+ /* Don't start any governor operations if we are entering suspend */
+ if (cpufreq_suspended)
+ return 0;
+
if (policy->governor->max_transition_latency &&
policy->cpuinfo.transition_latency >
policy->governor->max_transition_latency) {
dev = get_cpu_device(cpu);
if (dev) {
- if (action & CPU_TASKS_FROZEN)
- frozen = true;
-
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE:
__cpufreq_add_dev(dev, NULL, frozen);
pr_debug("%s: failed initialization\n", __func__);
return -EINVAL;
}
-EXPORT_SYMBOL(exynos4210_cpufreq_init);
pr_debug("%s: failed initialization\n", __func__);
return -EINVAL;
}
-EXPORT_SYMBOL(exynos4x12_cpufreq_init);
pr_err("%s: failed initialization\n", __func__);
return -EINVAL;
}
-EXPORT_SYMBOL(exynos5250_cpufreq_init);
mutex_lock(&tegra_cpu_lock);
- if (is_suspended) {
- ret = -EBUSY;
+ if (is_suspended)
goto out;
- }
freq = freq_table[index].frequency;
*/
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
- if (dev->registered == 0)
+ if (!dev || dev->registered == 0)
return;
cpuidle_pause_and_lock();
help
Enables the driver module for Freescale's Cryptographic Accelerator
and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
- This module adds a job ring operation interface, and configures h/w
+ This module creates job ring devices, and configures h/w
to operate as a DPAA component automatically, depending
on h/w feature availability.
To compile this driver as a module, choose M here: the module
will be called caam.
+config CRYPTO_DEV_FSL_CAAM_JR
+ tristate "Freescale CAAM Job Ring driver backend"
+ depends on CRYPTO_DEV_FSL_CAAM
+ default y
+ help
+ Enables the driver module for Job Rings which are part of
+ Freescale's Cryptographic Accelerator
+ and Assurance Module (CAAM). This module adds a job ring operation
+ interface.
+
+ To compile this driver as a module, choose M here: the module
+ will be called caam_jr.
+
config CRYPTO_DEV_FSL_CAAM_RINGSIZE
int "Job Ring size"
- depends on CRYPTO_DEV_FSL_CAAM
+ depends on CRYPTO_DEV_FSL_CAAM_JR
range 2 9
default "9"
help
config CRYPTO_DEV_FSL_CAAM_INTC
bool "Job Ring interrupt coalescing"
- depends on CRYPTO_DEV_FSL_CAAM
+ depends on CRYPTO_DEV_FSL_CAAM_JR
default n
help
Enable the Job Ring's interrupt coalescing feature.
config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
tristate "Register algorithm implementations with the Crypto API"
- depends on CRYPTO_DEV_FSL_CAAM
+ depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
default y
select CRYPTO_ALGAPI
select CRYPTO_AUTHENC
config CRYPTO_DEV_FSL_CAAM_AHASH_API
tristate "Register hash algorithm implementations with Crypto API"
- depends on CRYPTO_DEV_FSL_CAAM
+ depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
default y
select CRYPTO_HASH
help
config CRYPTO_DEV_FSL_CAAM_RNG_API
tristate "Register caam device for hwrng API"
- depends on CRYPTO_DEV_FSL_CAAM
+ depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
default y
select CRYPTO_RNG
select HW_RANDOM
endif
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
-caam-objs := ctrl.o jr.o error.o key_gen.o
+caam-objs := ctrl.o
+caam_jr-objs := jr.o key_gen.o error.o
#else
#define debug(format, arg...)
#endif
+static struct list_head alg_list;
/* Set DK bit in class 1 operation if shared */
static inline void append_dec_op1(u32 *desc, u32 type)
ivsize, 1);
print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst),
- req->cryptlen, 1);
+ req->cryptlen - ctx->authsize, 1);
#endif
if (err) {
(edesc->src_nents ? : 1);
in_options = LDST_SGF;
}
- if (encrypt)
- append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
- req->cryptlen - authsize, in_options);
- else
- append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
- req->cryptlen, in_options);
+
+ append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
+ in_options);
if (likely(req->src == req->dst)) {
if (all_contig) {
}
}
if (encrypt)
- append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options);
+ append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize,
+ out_options);
else
append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize,
out_options);
sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents;
in_options = LDST_SGF;
}
- append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
- req->cryptlen - authsize, in_options);
+ append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
+ in_options);
if (contig & GIV_DST_CONTIG) {
dst_dma = edesc->iv_dma;
}
}
- append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen, out_options);
+ append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize,
+ out_options);
}
/*
* allocate and map the aead extended descriptor
*/
static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
- int desc_bytes, bool *all_contig_ptr)
+ int desc_bytes, bool *all_contig_ptr,
+ bool encrypt)
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct caam_ctx *ctx = crypto_aead_ctx(aead);
bool assoc_chained = false, src_chained = false, dst_chained = false;
int ivsize = crypto_aead_ivsize(aead);
int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
+ unsigned int authsize = ctx->authsize;
assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
- src_nents = sg_count(req->src, req->cryptlen, &src_chained);
- if (unlikely(req->dst != req->src))
- dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
+ if (unlikely(req->dst != req->src)) {
+ src_nents = sg_count(req->src, req->cryptlen, &src_chained);
+ dst_nents = sg_count(req->dst,
+ req->cryptlen +
+ (encrypt ? authsize : (-authsize)),
+ &dst_chained);
+ } else {
+ src_nents = sg_count(req->src,
+ req->cryptlen +
+ (encrypt ? authsize : 0),
+ &src_chained);
+ }
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
DMA_TO_DEVICE, assoc_chained);
u32 *desc;
int ret = 0;
- req->cryptlen += ctx->authsize;
-
/* allocate extended descriptor */
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
- CAAM_CMD_SZ, &all_contig);
+ CAAM_CMD_SZ, &all_contig, true);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
/* allocate extended descriptor */
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
- CAAM_CMD_SZ, &all_contig);
+ CAAM_CMD_SZ, &all_contig, false);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
src_nents = sg_count(req->src, req->cryptlen, &src_chained);
if (unlikely(req->dst != req->src))
- dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
+ dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize,
+ &dst_chained);
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
DMA_TO_DEVICE, assoc_chained);
u32 *desc;
int ret = 0;
- req->cryptlen += ctx->authsize;
-
/* allocate extended descriptor */
edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN *
CAAM_CMD_SZ, &contig);
struct caam_crypto_alg {
struct list_head entry;
- struct device *ctrldev;
int class1_alg_type;
int class2_alg_type;
int alg_op;
struct caam_crypto_alg *caam_alg =
container_of(alg, struct caam_crypto_alg, crypto_alg);
struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
- struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev);
- int tgt_jr = atomic_inc_return(&priv->tfm_count);
- /*
- * distribute tfms across job rings to ensure in-order
- * crypto request processing per tfm
- */
- ctx->jrdev = priv->jrdev[(tgt_jr / 2) % priv->total_jobrs];
+ ctx->jrdev = caam_jr_alloc();
+ if (IS_ERR(ctx->jrdev)) {
+ pr_err("Job Ring Device allocation for transform failed\n");
+ return PTR_ERR(ctx->jrdev);
+ }
/* copy descriptor header template value */
ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
desc_bytes(ctx->sh_desc_givenc),
DMA_TO_DEVICE);
+
+ caam_jr_free(ctx->jrdev);
}
static void __exit caam_algapi_exit(void)
{
- struct device_node *dev_node;
- struct platform_device *pdev;
- struct device *ctrldev;
- struct caam_drv_private *priv;
struct caam_crypto_alg *t_alg, *n;
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node) {
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
- if (!dev_node)
- return;
- }
-
- pdev = of_find_device_by_node(dev_node);
- if (!pdev)
- return;
-
- ctrldev = &pdev->dev;
- of_node_put(dev_node);
- priv = dev_get_drvdata(ctrldev);
-
- if (!priv->alg_list.next)
+ if (!alg_list.next)
return;
- list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
+ list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
crypto_unregister_alg(&t_alg->crypto_alg);
list_del(&t_alg->entry);
kfree(t_alg);
}
}
-static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
- struct caam_alg_template
+static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
*template)
{
struct caam_crypto_alg *t_alg;
t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL);
if (!t_alg) {
- dev_err(ctrldev, "failed to allocate t_alg\n");
+ pr_err("failed to allocate t_alg\n");
return ERR_PTR(-ENOMEM);
}
t_alg->class1_alg_type = template->class1_alg_type;
t_alg->class2_alg_type = template->class2_alg_type;
t_alg->alg_op = template->alg_op;
- t_alg->ctrldev = ctrldev;
return t_alg;
}
static int __init caam_algapi_init(void)
{
- struct device_node *dev_node;
- struct platform_device *pdev;
- struct device *ctrldev;
- struct caam_drv_private *priv;
int i = 0, err = 0;
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node) {
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
- if (!dev_node)
- return -ENODEV;
- }
-
- pdev = of_find_device_by_node(dev_node);
- if (!pdev)
- return -ENODEV;
-
- ctrldev = &pdev->dev;
- priv = dev_get_drvdata(ctrldev);
- of_node_put(dev_node);
-
- INIT_LIST_HEAD(&priv->alg_list);
-
- atomic_set(&priv->tfm_count, -1);
+ INIT_LIST_HEAD(&alg_list);
/* register crypto algorithms the device supports */
for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
/* TODO: check if h/w supports alg */
struct caam_crypto_alg *t_alg;
- t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
+ t_alg = caam_alg_alloc(&driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
- dev_warn(ctrldev, "%s alg allocation failed\n",
- driver_algs[i].driver_name);
+ pr_warn("%s alg allocation failed\n",
+ driver_algs[i].driver_name);
continue;
}
err = crypto_register_alg(&t_alg->crypto_alg);
if (err) {
- dev_warn(ctrldev, "%s alg registration failed\n",
+ pr_warn("%s alg registration failed\n",
t_alg->crypto_alg.cra_driver_name);
kfree(t_alg);
} else
- list_add_tail(&t_alg->entry, &priv->alg_list);
+ list_add_tail(&t_alg->entry, &alg_list);
}
- if (!list_empty(&priv->alg_list))
- dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
- (char *)of_get_property(dev_node, "compatible", NULL));
+ if (!list_empty(&alg_list))
+ pr_info("caam algorithms registered in /proc/crypto\n");
return err;
}
#define debug(format, arg...)
#endif
+
+static struct list_head hash_list;
+
/* ahash per-session context */
struct caam_hash_ctx {
struct device *jrdev;
struct caam_hash_alg {
struct list_head entry;
- struct device *ctrldev;
int alg_type;
int alg_op;
struct ahash_alg ahash_alg;
struct caam_hash_alg *caam_hash =
container_of(alg, struct caam_hash_alg, ahash_alg);
struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
- struct caam_drv_private *priv = dev_get_drvdata(caam_hash->ctrldev);
/* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */
static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE,
HASH_MSG_LEN + SHA1_DIGEST_SIZE,
HASH_MSG_LEN + SHA256_DIGEST_SIZE,
HASH_MSG_LEN + 64,
HASH_MSG_LEN + SHA512_DIGEST_SIZE };
- int tgt_jr = atomic_inc_return(&priv->tfm_count);
int ret = 0;
/*
- * distribute tfms across job rings to ensure in-order
+ * Get a Job ring from Job Ring driver to ensure in-order
* crypto request processing per tfm
*/
- ctx->jrdev = priv->jrdev[tgt_jr % priv->total_jobrs];
-
+ ctx->jrdev = caam_jr_alloc();
+ if (IS_ERR(ctx->jrdev)) {
+ pr_err("Job Ring Device allocation for transform failed\n");
+ return PTR_ERR(ctx->jrdev);
+ }
/* copy descriptor header template value */
ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_hash->alg_op;
!dma_mapping_error(ctx->jrdev, ctx->sh_desc_finup_dma))
dma_unmap_single(ctx->jrdev, ctx->sh_desc_finup_dma,
desc_bytes(ctx->sh_desc_finup), DMA_TO_DEVICE);
+
+ caam_jr_free(ctx->jrdev);
}
static void __exit caam_algapi_hash_exit(void)
{
- struct device_node *dev_node;
- struct platform_device *pdev;
- struct device *ctrldev;
- struct caam_drv_private *priv;
struct caam_hash_alg *t_alg, *n;
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node) {
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
- if (!dev_node)
- return;
- }
-
- pdev = of_find_device_by_node(dev_node);
- if (!pdev)
+ if (!hash_list.next)
return;
- ctrldev = &pdev->dev;
- of_node_put(dev_node);
- priv = dev_get_drvdata(ctrldev);
-
- if (!priv->hash_list.next)
- return;
-
- list_for_each_entry_safe(t_alg, n, &priv->hash_list, entry) {
+ list_for_each_entry_safe(t_alg, n, &hash_list, entry) {
crypto_unregister_ahash(&t_alg->ahash_alg);
list_del(&t_alg->entry);
kfree(t_alg);
}
static struct caam_hash_alg *
-caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template,
+caam_hash_alloc(struct caam_hash_template *template,
bool keyed)
{
struct caam_hash_alg *t_alg;
t_alg = kzalloc(sizeof(struct caam_hash_alg), GFP_KERNEL);
if (!t_alg) {
- dev_err(ctrldev, "failed to allocate t_alg\n");
+ pr_err("failed to allocate t_alg\n");
return ERR_PTR(-ENOMEM);
}
t_alg->alg_type = template->alg_type;
t_alg->alg_op = template->alg_op;
- t_alg->ctrldev = ctrldev;
return t_alg;
}
static int __init caam_algapi_hash_init(void)
{
- struct device_node *dev_node;
- struct platform_device *pdev;
- struct device *ctrldev;
- struct caam_drv_private *priv;
int i = 0, err = 0;
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node) {
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
- if (!dev_node)
- return -ENODEV;
- }
-
- pdev = of_find_device_by_node(dev_node);
- if (!pdev)
- return -ENODEV;
-
- ctrldev = &pdev->dev;
- priv = dev_get_drvdata(ctrldev);
- of_node_put(dev_node);
-
- INIT_LIST_HEAD(&priv->hash_list);
-
- atomic_set(&priv->tfm_count, -1);
+ INIT_LIST_HEAD(&hash_list);
/* register crypto algorithms the device supports */
for (i = 0; i < ARRAY_SIZE(driver_hash); i++) {
struct caam_hash_alg *t_alg;
/* register hmac version */
- t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], true);
+ t_alg = caam_hash_alloc(&driver_hash[i], true);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
- dev_warn(ctrldev, "%s alg allocation failed\n",
- driver_hash[i].driver_name);
+ pr_warn("%s alg allocation failed\n",
+ driver_hash[i].driver_name);
continue;
}
err = crypto_register_ahash(&t_alg->ahash_alg);
if (err) {
- dev_warn(ctrldev, "%s alg registration failed\n",
+ pr_warn("%s alg registration failed\n",
t_alg->ahash_alg.halg.base.cra_driver_name);
kfree(t_alg);
} else
- list_add_tail(&t_alg->entry, &priv->hash_list);
+ list_add_tail(&t_alg->entry, &hash_list);
/* register unkeyed version */
- t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], false);
+ t_alg = caam_hash_alloc(&driver_hash[i], false);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
- dev_warn(ctrldev, "%s alg allocation failed\n",
- driver_hash[i].driver_name);
+ pr_warn("%s alg allocation failed\n",
+ driver_hash[i].driver_name);
continue;
}
err = crypto_register_ahash(&t_alg->ahash_alg);
if (err) {
- dev_warn(ctrldev, "%s alg registration failed\n",
+ pr_warn("%s alg registration failed\n",
t_alg->ahash_alg.halg.base.cra_driver_name);
kfree(t_alg);
} else
- list_add_tail(&t_alg->entry, &priv->hash_list);
+ list_add_tail(&t_alg->entry, &hash_list);
}
return err;
static void __exit caam_rng_exit(void)
{
+ caam_jr_free(rng_ctx.jrdev);
hwrng_unregister(&caam_rng);
}
static int __init caam_rng_init(void)
{
- struct device_node *dev_node;
- struct platform_device *pdev;
- struct device *ctrldev;
- struct caam_drv_private *priv;
-
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node) {
- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
- if (!dev_node)
- return -ENODEV;
- }
-
- pdev = of_find_device_by_node(dev_node);
- if (!pdev)
- return -ENODEV;
+ struct device *dev;
- ctrldev = &pdev->dev;
- priv = dev_get_drvdata(ctrldev);
- of_node_put(dev_node);
+ dev = caam_jr_alloc();
+ if (IS_ERR(dev)) {
+ pr_err("Job Ring Device allocation for transform failed\n");
+ return PTR_ERR(dev);
+ }
- caam_init_rng(&rng_ctx, priv->jrdev[0]);
+ caam_init_rng(&rng_ctx, dev);
- dev_info(priv->jrdev[0], "registering rng-caam\n");
+ dev_info(dev, "registering rng-caam\n");
return hwrng_register(&caam_rng);
}
#include "error.h"
#include "ctrl.h"
-static int caam_remove(struct platform_device *pdev)
-{
- struct device *ctrldev;
- struct caam_drv_private *ctrlpriv;
- struct caam_drv_private_jr *jrpriv;
- struct caam_full __iomem *topregs;
- int ring, ret = 0;
-
- ctrldev = &pdev->dev;
- ctrlpriv = dev_get_drvdata(ctrldev);
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
-
- /* shut down JobRs */
- for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
- ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
- jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
- irq_dispose_mapping(jrpriv->irq);
- }
-
- /* Shut down debug views */
-#ifdef CONFIG_DEBUG_FS
- debugfs_remove_recursive(ctrlpriv->dfs_root);
-#endif
-
- /* Unmap controller region */
- iounmap(&topregs->ctrl);
-
- kfree(ctrlpriv->jrdev);
- kfree(ctrlpriv);
-
- return ret;
-}
-
/*
* Descriptor to instantiate RNG State Handle 0 in normal mode and
* load the JDKEK, TDKEK and TDSK registers
*/
-static void build_instantiation_desc(u32 *desc)
+static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
{
- u32 *jump_cmd;
+ u32 *jump_cmd, op_flags;
init_job_desc(desc, 0);
+ op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
+
/* INIT RNG in non-test mode */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AS_INIT);
+ append_operation(desc, op_flags);
+
+ if (!handle && do_sk) {
+ /*
+ * For SH0, Secure Keys must be generated as well
+ */
+
+ /* wait for done */
+ jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+ set_jump_tgt_here(desc, jump_cmd);
+
+ /*
+ * load 1 to clear written reg:
+ * resets the done interrrupt and returns the RNG to idle.
+ */
+ append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+ /* Initialize State Handle */
+ append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ OP_ALG_AAI_RNG4_SK);
+ }
- /* wait for done */
- jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
- set_jump_tgt_here(desc, jump_cmd);
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+}
- /*
- * load 1 to clear written reg:
- * resets the done interrupt and returns the RNG to idle.
- */
- append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
+static void build_deinstantiation_desc(u32 *desc, int handle)
+{
+ init_job_desc(desc, 0);
- /* generate secure keys (non-test) */
+ /* Uninstantiate State Handle 0 */
append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_RNG4_SK);
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
+
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}
-static int instantiate_rng(struct device *ctrldev)
+/*
+ * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
+ * the software (no JR/QI used).
+ * @ctrldev - pointer to device
+ * @status - descriptor status, after being run
+ *
+ * Return: - 0 if no error occurred
+ * - -ENODEV if the DECO couldn't be acquired
+ * - -EAGAIN if an error occurred while executing the descriptor
+ */
+static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
+ u32 *status)
{
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
struct caam_full __iomem *topregs;
unsigned int timeout = 100000;
- u32 *desc;
- int i, ret = 0;
-
- desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA);
- if (!desc) {
- dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
- return -ENOMEM;
- }
- build_instantiation_desc(desc);
+ u32 deco_dbg_reg, flags;
+ int i;
/* Set the bit to request direct access to DECO0 */
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
if (!timeout) {
dev_err(ctrldev, "failed to acquire DECO 0\n");
- ret = -EIO;
- goto out;
+ clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
+ return -ENODEV;
}
for (i = 0; i < desc_len(desc); i++)
- topregs->deco.descbuf[i] = *(desc + i);
+ wr_reg32(&topregs->deco.descbuf[i], *(desc + i));
+
+ flags = DECO_JQCR_WHL;
+ /*
+ * If the descriptor length is longer than 4 words, then the
+ * FOUR bit in JRCTRL register must be set.
+ */
+ if (desc_len(desc) >= 4)
+ flags |= DECO_JQCR_FOUR;
- wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
+ /* Instruct the DECO to execute it */
+ wr_reg32(&topregs->deco.jr_ctl_hi, flags);
timeout = 10000000;
- while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) &&
- --timeout)
+ do {
+ deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
+ /*
+ * If an error occured in the descriptor, then
+ * the DECO status field will be set to 0x0D
+ */
+ if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
+ DESC_DBG_DECO_STAT_HOST_ERR)
+ break;
cpu_relax();
+ } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
- if (!timeout) {
- dev_err(ctrldev, "failed to instantiate RNG\n");
- ret = -EIO;
- }
+ *status = rd_reg32(&topregs->deco.op_status_hi) &
+ DECO_OP_STATUS_HI_ERR_MASK;
+ /* Mark the DECO as free */
clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
-out:
+
+ if (!timeout)
+ return -EAGAIN;
+
+ return 0;
+}
+
+/*
+ * instantiate_rng - builds and executes a descriptor on DECO0,
+ * which initializes the RNG block.
+ * @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
+ * by an external entry, 0 otherwise.
+ * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK;
+ * Caution: this can be done only once; if the keys need to be
+ * regenerated, a POR is required
+ *
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
+ * f.i. there was a RNG hardware error due to not "good enough"
+ * entropy being aquired.
+ */
+static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+ int gen_sk)
+{
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+ struct caam_full __iomem *topregs;
+ struct rng4tst __iomem *r4tst;
+ u32 *desc, status, rdsta_val;
+ int ret = 0, sh_idx;
+
+ topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+ r4tst = &topregs->ctrl.r4tst[0];
+
+ desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, this state handle
+ * was initialized by somebody else, so it's left alone.
+ */
+ if ((1 << sh_idx) & state_handle_mask)
+ continue;
+
+ /* Create the descriptor for instantiating RNG State Handle */
+ build_instantiation_desc(desc, sh_idx, gen_sk);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+ /*
+ * If ret is not 0, or descriptor status is not 0, then
+ * something went wrong. No need to try the next state
+ * handle (if available), bail out here.
+ * Also, if for some reason, the State Handle didn't get
+ * instantiated although the descriptor has finished
+ * without any error (HW optimizations for later
+ * CAAM eras), then try again.
+ */
+ rdsta_val =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK;
+ if (status || !(rdsta_val & (1 << sh_idx)))
+ ret = -EAGAIN;
+ if (ret)
+ break;
+
+ dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+ /* Clear the contents before recreating the descriptor */
+ memset(desc, 0x00, CAAM_CMD_SZ * 7);
+ }
+
kfree(desc);
+
return ret;
}
/*
- * By default, the TRNG runs for 200 clocks per sample;
- * 1600 clocks per sample generates better entropy.
+ * deinstantiate_rng - builds and executes a descriptor on DECO0,
+ * which deinitializes the RNG block.
+ * @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
+ *
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
*/
-static void kick_trng(struct platform_device *pdev)
+static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
+{
+ u32 *desc, status;
+ int sh_idx, ret = 0;
+
+ desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, then it means the state
+ * handle was initialized by us, and thus it needs to be
+ * deintialized as well
+ */
+ if ((1 << sh_idx) & state_handle_mask) {
+ /*
+ * Create the descriptor for deinstantating this state
+ * handle
+ */
+ build_deinstantiation_desc(desc, sh_idx);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+ if (ret || status) {
+ dev_err(ctrldev,
+ "Failed to deinstantiate RNG4 SH%d\n",
+ sh_idx);
+ break;
+ }
+ dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
+ }
+ }
+
+ kfree(desc);
+
+ return ret;
+}
+
+static int caam_remove(struct platform_device *pdev)
+{
+ struct device *ctrldev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_full __iomem *topregs;
+ int ring, ret = 0;
+
+ ctrldev = &pdev->dev;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+ topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+
+ /* Remove platform devices for JobRs */
+ for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+ if (ctrlpriv->jrpdev[ring])
+ of_device_unregister(ctrlpriv->jrpdev[ring]);
+ }
+
+ /* De-initialize RNG state handles initialized by this driver. */
+ if (ctrlpriv->rng4_sh_init)
+ deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
+
+ /* Shut down debug views */
+#ifdef CONFIG_DEBUG_FS
+ debugfs_remove_recursive(ctrlpriv->dfs_root);
+#endif
+
+ /* Unmap controller region */
+ iounmap(&topregs->ctrl);
+
+ kfree(ctrlpriv->jrpdev);
+ kfree(ctrlpriv);
+
+ return ret;
+}
+
+/*
+ * kick_trng - sets the various parameters for enabling the initialization
+ * of the RNG4 block in CAAM
+ * @pdev - pointer to the platform device
+ * @ent_delay - Defines the length (in system clocks) of each entropy sample.
+ */
+static void kick_trng(struct platform_device *pdev, int ent_delay)
{
struct device *ctrldev = &pdev->dev;
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
/* put RNG4 into program mode */
setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
- /* 1600 clocks per sample */
+
+ /*
+ * Performance-wise, it does not make sense to
+ * set the delay to a value that is lower
+ * than the last one that worked (i.e. the state handles
+ * were instantiated properly. Thus, instead of wasting
+ * time trying to set the values controlling the sample
+ * frequency, the function simply returns.
+ */
+ val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
+ >> RTSDCTL_ENT_DLY_SHIFT;
+ if (ent_delay <= val) {
+ /* put RNG4 into run mode */
+ clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
+ return;
+ }
+
val = rd_reg32(&r4tst->rtsdctl);
- val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT);
+ val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+ (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
wr_reg32(&r4tst->rtsdctl, val);
- /* min. freq. count */
- wr_reg32(&r4tst->rtfrqmin, 400);
- /* max. freq. count */
- wr_reg32(&r4tst->rtfrqmax, 6400);
+ /* min. freq. count, equal to 1/4 of the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
+ /* max. freq. count, equal to 8 times the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
/* put RNG4 into run mode */
clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
}
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, rspec;
+ int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
u64 caam_id;
struct device *dev;
struct device_node *nprop, *np;
rspec++;
}
- ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
- if (ctrlpriv->jrdev == NULL) {
+ ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
+ GFP_KERNEL);
+ if (ctrlpriv->jrpdev == NULL) {
iounmap(&topregs->ctrl);
return -ENOMEM;
}
ring = 0;
ctrlpriv->total_jobrs = 0;
for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
- caam_jr_probe(pdev, np, ring);
+ ctrlpriv->jrpdev[ring] =
+ of_platform_device_create(np, NULL, dev);
+ if (!ctrlpriv->jrpdev[ring]) {
+ pr_warn("JR%d Platform device creation error\n", ring);
+ continue;
+ }
ctrlpriv->total_jobrs++;
ring++;
}
if (!ring) {
for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
- caam_jr_probe(pdev, np, ring);
+ ctrlpriv->jrpdev[ring] =
+ of_platform_device_create(np, NULL, dev);
+ if (!ctrlpriv->jrpdev[ring]) {
+ pr_warn("JR%d Platform device creation error\n",
+ ring);
+ continue;
+ }
ctrlpriv->total_jobrs++;
ring++;
}
/*
* If SEC has RNG version >= 4 and RNG state handle has not been
- * already instantiated ,do RNG instantiation
+ * already instantiated, do RNG instantiation
*/
- if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
- !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
- kick_trng(pdev);
- ret = instantiate_rng(dev);
+ if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
+ ctrlpriv->rng4_sh_init =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
+ /*
+ * If the secure keys (TDKEK, JDKEK, TDSK), were already
+ * generated, signal this to the function that is instantiating
+ * the state handles. An error would occur if RNG4 attempts
+ * to regenerate these keys before the next POR.
+ */
+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+ ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
+ do {
+ int inst_handles =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
+ RDSTA_IFMASK;
+ /*
+ * If either SH were instantiated by somebody else
+ * (e.g. u-boot) then it is assumed that the entropy
+ * parameters are properly set and thus the function
+ * setting these (kick_trng(...)) is skipped.
+ * Also, if a handle was instantiated, do not change
+ * the TRNG parameters.
+ */
+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ kick_trng(pdev, ent_delay);
+ ent_delay += 400;
+ }
+ /*
+ * if instantiate_rng(...) fails, the loop will rerun
+ * and the kick_trng(...) function will modfiy the
+ * upper and lower limits of the entropy sampling
+ * interval, leading to a sucessful initialization of
+ * the RNG.
+ */
+ ret = instantiate_rng(dev, inst_handles,
+ gen_sk);
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
+ dev_err(dev, "failed to instantiate RNG");
caam_remove(pdev);
return ret;
}
+ /*
+ * Set handles init'ed by this module as the complement of the
+ * already initialized ones
+ */
+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
/* Enable RDB bit so that RNG works faster */
setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
/* randomizer AAI set */
#define OP_ALG_AAI_RNG (0x00 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_NOZERO (0x10 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_ODD (0x20 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NZB (0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_OBP (0x20 << OP_ALG_AAI_SHIFT)
+
+/* RNG4 AAI set */
+#define OP_ALG_AAI_RNG4_SH_0 (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SH_1 (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_PS (0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_AI (0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SK (0x100 << OP_ALG_AAI_SHIFT)
/* hmac/smac AAI set */
#define OP_ALG_AAI_HASH (0x00 << OP_ALG_AAI_SHIFT)
#define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT)
#define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT)
-/* RNG4 set */
-#define OP_ALG_RNG4_SHIFT 4
-#define OP_ALG_RNG4_MASK (0x1f3 << OP_ALG_RNG4_SHIFT)
-
-#define OP_ALG_RNG4_SK (0x100 << OP_ALG_RNG4_SHIFT)
-
#define OP_ALG_AS_SHIFT 2
#define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT)
#define OP_ALG_AS_UPDATE (0 << OP_ALG_AS_SHIFT)
/* Private sub-storage for a single JobR */
struct caam_drv_private_jr {
- struct device *parentdev; /* points back to controller dev */
- struct platform_device *jr_pdev;/* points to platform device for JR */
+ struct list_head list_node; /* Job Ring device list */
+ struct device *dev;
int ridx;
struct caam_job_ring __iomem *rregs; /* JobR's register space */
struct tasklet_struct irqtask;
int irq; /* One per queue */
+ /* Number of scatterlist crypt transforms active on the JobR */
+ atomic_t tfm_count ____cacheline_aligned;
+
/* Job ring info */
int ringsize; /* Size of rings (assume input = output) */
struct caam_jrentry_info *entinfo; /* Alloc'ed 1 per ring entry */
struct caam_drv_private {
struct device *dev;
- struct device **jrdev; /* Alloc'ed array per sub-device */
+ struct platform_device **jrpdev; /* Alloc'ed array per sub-device */
struct platform_device *pdev;
/* Physical-presence section */
u8 qi_present; /* Nonzero if QI present in device */
int secvio_irq; /* Security violation interrupt number */
- /* which jr allocated to scatterlist crypto */
- atomic_t tfm_count ____cacheline_aligned;
- /* list of registered crypto algorithms (mk generic context handle?) */
- struct list_head alg_list;
- /* list of registered hash algorithms (mk generic context handle?) */
- struct list_head hash_list;
+#define RNG4_MAX_HANDLES 2
+ /* RNG4 block */
+ u32 rng4_sh_init; /* This bitmap shows which of the State
+ Handles of the RNG4 block are initialized
+ by this driver */
/*
* debugfs entries for developer view into driver/device
*/
#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include "compat.h"
#include "regs.h"
#include "desc.h"
#include "intern.h"
+struct jr_driver_data {
+ /* List of Physical JobR's with the Driver */
+ struct list_head jr_list;
+ spinlock_t jr_alloc_lock; /* jr_list lock */
+} ____cacheline_aligned;
+
+static struct jr_driver_data driver_data;
+
+static int caam_reset_hw_jr(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+ unsigned int timeout = 100000;
+
+ /*
+ * mask interrupts since we are going to poll
+ * for reset completion status
+ */
+ setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+ /* initiate flush (required prior to reset) */
+ wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+ while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
+ JRINT_ERR_HALT_INPROGRESS) && --timeout)
+ cpu_relax();
+
+ if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
+ JRINT_ERR_HALT_COMPLETE || timeout == 0) {
+ dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
+ return -EIO;
+ }
+
+ /* initiate reset */
+ timeout = 100000;
+ wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+ while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+ cpu_relax();
+
+ if (timeout == 0) {
+ dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
+ return -EIO;
+ }
+
+ /* unmask interrupts */
+ clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+ return 0;
+}
+
+/*
+ * Shutdown JobR independent of platform property code
+ */
+int caam_jr_shutdown(struct device *dev)
+{
+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+ dma_addr_t inpbusaddr, outbusaddr;
+ int ret;
+
+ ret = caam_reset_hw_jr(dev);
+
+ tasklet_kill(&jrp->irqtask);
+
+ /* Release interrupt */
+ free_irq(jrp->irq, dev);
+
+ /* Free rings */
+ inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
+ outbusaddr = rd_reg64(&jrp->rregs->outring_base);
+ dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
+ jrp->inpring, inpbusaddr);
+ dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
+ jrp->outring, outbusaddr);
+ kfree(jrp->entinfo);
+
+ return ret;
+}
+
+static int caam_jr_remove(struct platform_device *pdev)
+{
+ int ret;
+ struct device *jrdev;
+ struct caam_drv_private_jr *jrpriv;
+
+ jrdev = &pdev->dev;
+ jrpriv = dev_get_drvdata(jrdev);
+
+ /*
+ * Return EBUSY if job ring already allocated.
+ */
+ if (atomic_read(&jrpriv->tfm_count)) {
+ dev_err(jrdev, "Device is busy\n");
+ return -EBUSY;
+ }
+
+ /* Remove the node from Physical JobR list maintained by driver */
+ spin_lock(&driver_data.jr_alloc_lock);
+ list_del(&jrpriv->list_node);
+ spin_unlock(&driver_data.jr_alloc_lock);
+
+ /* Release ring */
+ ret = caam_jr_shutdown(jrdev);
+ if (ret)
+ dev_err(jrdev, "Failed to shut down job ring\n");
+ irq_dispose_mapping(jrpriv->irq);
+
+ return ret;
+}
+
/* Main per-ring interrupt handler */
static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
{
clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
}
+/**
+ * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
+ *
+ * returns : pointer to the newly allocated physical
+ * JobR dev can be written to if successful.
+ **/
+struct device *caam_jr_alloc(void)
+{
+ struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
+ struct device *dev = NULL;
+ int min_tfm_cnt = INT_MAX;
+ int tfm_cnt;
+
+ spin_lock(&driver_data.jr_alloc_lock);
+
+ if (list_empty(&driver_data.jr_list)) {
+ spin_unlock(&driver_data.jr_alloc_lock);
+ return ERR_PTR(-ENODEV);
+ }
+
+ list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
+ tfm_cnt = atomic_read(&jrpriv->tfm_count);
+ if (tfm_cnt < min_tfm_cnt) {
+ min_tfm_cnt = tfm_cnt;
+ min_jrpriv = jrpriv;
+ }
+ if (!min_tfm_cnt)
+ break;
+ }
+
+ if (min_jrpriv) {
+ atomic_inc(&min_jrpriv->tfm_count);
+ dev = min_jrpriv->dev;
+ }
+ spin_unlock(&driver_data.jr_alloc_lock);
+
+ return dev;
+}
+EXPORT_SYMBOL(caam_jr_alloc);
+
+/**
+ * caam_jr_free() - Free the Job Ring
+ * @rdev - points to the dev that identifies the Job ring to
+ * be released.
+ **/
+void caam_jr_free(struct device *rdev)
+{
+ struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
+
+ atomic_dec(&jrpriv->tfm_count);
+}
+EXPORT_SYMBOL(caam_jr_free);
+
/**
* caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
* -EBUSY if the queue is full, -EIO if it cannot map the caller's
}
EXPORT_SYMBOL(caam_jr_enqueue);
-static int caam_reset_hw_jr(struct device *dev)
-{
- struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
- unsigned int timeout = 100000;
-
- /*
- * mask interrupts since we are going to poll
- * for reset completion status
- */
- setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-
- /* initiate flush (required prior to reset) */
- wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
- JRINT_ERR_HALT_INPROGRESS) && --timeout)
- cpu_relax();
-
- if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
- JRINT_ERR_HALT_COMPLETE || timeout == 0) {
- dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
- return -EIO;
- }
-
- /* initiate reset */
- timeout = 100000;
- wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
- cpu_relax();
-
- if (timeout == 0) {
- dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
- return -EIO;
- }
-
- /* unmask interrupts */
- clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-
- return 0;
-}
-
/*
* Init JobR independent of platform property detection
*/
/* Connect job ring interrupt handler. */
error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
- "caam-jobr", dev);
+ dev_name(dev), dev);
if (error) {
dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
jrp->ridx, jrp->irq);
return 0;
}
-/*
- * Shutdown JobR independent of platform property code
- */
-int caam_jr_shutdown(struct device *dev)
-{
- struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
- dma_addr_t inpbusaddr, outbusaddr;
- int ret;
-
- ret = caam_reset_hw_jr(dev);
-
- tasklet_kill(&jrp->irqtask);
-
- /* Release interrupt */
- free_irq(jrp->irq, dev);
-
- /* Free rings */
- inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
- outbusaddr = rd_reg64(&jrp->rregs->outring_base);
- dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
- jrp->inpring, inpbusaddr);
- dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
- jrp->outring, outbusaddr);
- kfree(jrp->entinfo);
- of_device_unregister(jrp->jr_pdev);
-
- return ret;
-}
/*
- * Probe routine for each detected JobR subsystem. It assumes that
- * property detection was picked up externally.
+ * Probe routine for each detected JobR subsystem.
*/
-int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
- int ring)
+static int caam_jr_probe(struct platform_device *pdev)
{
- struct device *ctrldev, *jrdev;
- struct platform_device *jr_pdev;
- struct caam_drv_private *ctrlpriv;
+ struct device *jrdev;
+ struct device_node *nprop;
+ struct caam_job_ring __iomem *ctrl;
struct caam_drv_private_jr *jrpriv;
- u32 *jroffset;
+ static int total_jobrs;
int error;
- ctrldev = &pdev->dev;
- ctrlpriv = dev_get_drvdata(ctrldev);
-
+ jrdev = &pdev->dev;
jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
GFP_KERNEL);
- if (jrpriv == NULL) {
- dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
- ring);
+ if (!jrpriv)
return -ENOMEM;
- }
- jrpriv->parentdev = ctrldev; /* point back to parent */
- jrpriv->ridx = ring; /* save ring identity relative to detection */
- /*
- * Derive a pointer to the detected JobRs regs
- * Driver has already iomapped the entire space, we just
- * need to add in the offset to this JobR. Don't know if I
- * like this long-term, but it'll run
- */
- jroffset = (u32 *)of_get_property(np, "reg", NULL);
- jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
- + *jroffset);
+ dev_set_drvdata(jrdev, jrpriv);
- /* Build a local dev for each detected queue */
- jr_pdev = of_platform_device_create(np, NULL, ctrldev);
- if (jr_pdev == NULL) {
- kfree(jrpriv);
- return -EINVAL;
+ /* save ring identity relative to detection */
+ jrpriv->ridx = total_jobrs++;
+
+ nprop = pdev->dev.of_node;
+ /* Get configuration properties from device tree */
+ /* First, get register page */
+ ctrl = of_iomap(nprop, 0);
+ if (!ctrl) {
+ dev_err(jrdev, "of_iomap() failed\n");
+ return -ENOMEM;
}
- jrpriv->jr_pdev = jr_pdev;
- jrdev = &jr_pdev->dev;
- dev_set_drvdata(jrdev, jrpriv);
- ctrlpriv->jrdev[ring] = jrdev;
+ jrpriv->rregs = (struct caam_job_ring __force *)ctrl;
if (sizeof(dma_addr_t) == sizeof(u64))
- if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring"))
+ if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
dma_set_mask(jrdev, DMA_BIT_MASK(40));
else
dma_set_mask(jrdev, DMA_BIT_MASK(36));
dma_set_mask(jrdev, DMA_BIT_MASK(32));
/* Identify the interrupt */
- jrpriv->irq = irq_of_parse_and_map(np, 0);
+ jrpriv->irq = irq_of_parse_and_map(nprop, 0);
/* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */
if (error) {
- of_device_unregister(jr_pdev);
kfree(jrpriv);
return error;
}
- return error;
+ jrpriv->dev = jrdev;
+ spin_lock(&driver_data.jr_alloc_lock);
+ list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
+ spin_unlock(&driver_data.jr_alloc_lock);
+
+ atomic_set(&jrpriv->tfm_count, 0);
+
+ return 0;
+}
+
+static struct of_device_id caam_jr_match[] = {
+ {
+ .compatible = "fsl,sec-v4.0-job-ring",
+ },
+ {
+ .compatible = "fsl,sec4.0-job-ring",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, caam_jr_match);
+
+static struct platform_driver caam_jr_driver = {
+ .driver = {
+ .name = "caam_jr",
+ .owner = THIS_MODULE,
+ .of_match_table = caam_jr_match,
+ },
+ .probe = caam_jr_probe,
+ .remove = caam_jr_remove,
+};
+
+static int __init jr_driver_init(void)
+{
+ spin_lock_init(&driver_data.jr_alloc_lock);
+ INIT_LIST_HEAD(&driver_data.jr_list);
+ return platform_driver_register(&caam_jr_driver);
+}
+
+static void __exit jr_driver_exit(void)
+{
+ platform_driver_unregister(&caam_jr_driver);
}
+
+module_init(jr_driver_init);
+module_exit(jr_driver_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FSL CAAM JR request backend");
+MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
#define JR_H
/* Prototypes for backend-level services exposed to APIs */
+struct device *caam_jr_alloc(void);
+void caam_jr_free(struct device *rdev);
int caam_jr_enqueue(struct device *dev, u32 *desc,
void (*cbk)(struct device *dev, u32 *desc, u32 status,
void *areq),
void *areq);
-extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
- int ring);
-extern int caam_jr_shutdown(struct device *dev);
#endif /* JR_H */
/* RNG4 TRNG test registers */
struct rng4tst {
-#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
u32 rtmctl; /* misc. control register */
u32 rtscmisc; /* statistical check misc. register */
u32 rtpkrrng; /* poker range register */
};
#define RTSDCTL_ENT_DLY_SHIFT 16
#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
+#define RTSDCTL_ENT_DLY_MIN 1200
+#define RTSDCTL_ENT_DLY_MAX 12800
u32 rtsdctl; /* seed control register */
union {
u32 rtsblim; /* PRGM=1: sparse bit limit register */
u32 rtfrqcnt; /* PRGM=0: freq. count register */
};
u32 rsvd1[40];
+#define RDSTA_SKVT 0x80000000
+#define RDSTA_SKVN 0x40000000
#define RDSTA_IF0 0x00000001
+#define RDSTA_IF1 0x00000002
+#define RDSTA_IFMASK (RDSTA_IF1 | RDSTA_IF0)
u32 rdsta;
u32 rsvd2[15];
};
u32 jr_ctl_hi; /* CxJRR - JobR Control Register @800 */
u32 jr_ctl_lo;
u64 jr_descaddr; /* CxDADR - JobR Descriptor Address */
+#define DECO_OP_STATUS_HI_ERR_MASK 0xF00000FF
u32 op_status_hi; /* DxOPSTA - DECO Operation Status */
u32 op_status_lo;
u32 rsvd24[2];
u32 rsvd29[48];
u32 descbuf[64]; /* DxDESB - Descriptor buffer */
u32 rscvd30[193];
+#define DESC_DBG_DECO_STAT_HOST_ERR 0x00D00000
+#define DESC_DBG_DECO_STAT_VALID 0x80000000
+#define DESC_DBG_DECO_STAT_MASK 0x00F00000
u32 desc_dbg; /* DxDDR - DECO Debug Register */
u32 rsvd31[126];
};
-/* DECO DBG Register Valid Bit*/
-#define DECO_DBG_VALID 0x80000000
#define DECO_JQCR_WHL 0x20000000
#define DECO_JQCR_FOUR 0x10000000
return nents;
}
+/* Map SG page in kernel virtual address space and copy */
+static inline void sg_map_copy(u8 *dest, struct scatterlist *sg,
+ int len, int offset)
+{
+ u8 *mapped_addr;
+
+ /*
+ * Page here can be user-space pinned using get_user_pages
+ * Same must be kmapped before use and kunmapped subsequently
+ */
+ mapped_addr = kmap_atomic(sg_page(sg));
+ memcpy(dest, mapped_addr + offset, len);
+ kunmap_atomic(mapped_addr);
+}
+
/* Copy from len bytes of sg to dest, starting from beginning */
static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
{
int cpy_index = 0, next_cpy_index = current_sg->length;
while (next_cpy_index < len) {
- memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
- current_sg->length);
+ sg_map_copy(dest + cpy_index, current_sg, current_sg->length,
+ current_sg->offset);
current_sg = scatterwalk_sg_next(current_sg);
cpy_index = next_cpy_index;
next_cpy_index += current_sg->length;
}
if (cpy_index < len)
- memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
- len - cpy_index);
+ sg_map_copy(dest + cpy_index, current_sg, len-cpy_index,
+ current_sg->offset);
}
/* Copy sg data, from to_skip to end, to dest */
int to_skip, unsigned int end)
{
struct scatterlist *current_sg = sg;
- int sg_index, cpy_index;
+ int sg_index, cpy_index, offset;
sg_index = current_sg->length;
while (sg_index <= to_skip) {
sg_index += current_sg->length;
}
cpy_index = sg_index - to_skip;
- memcpy(dest, (u8 *) sg_virt(current_sg) +
- current_sg->length - cpy_index, cpy_index);
- current_sg = scatterwalk_sg_next(current_sg);
- if (end - sg_index)
+ offset = current_sg->offset + current_sg->length - cpy_index;
+ sg_map_copy(dest, current_sg, cpy_index, offset);
+ if (end - sg_index) {
+ current_sg = scatterwalk_sg_next(current_sg);
sg_copy(dest + cpy_index, current_sg, end - sg_index);
+ }
}
platform_set_drvdata(pdev, dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- dev_err(&pdev->dev, "failed to get IORESOURCE_MEM\n");
- return -ENXIO;
- }
- dev->dcp_regs_base = devm_ioremap(&pdev->dev, r->start,
- resource_size(r));
+ dev->dcp_regs_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(dev->dcp_regs_base))
+ return PTR_ERR(dev->dcp_regs_base);
dcp_set(dev, DCP_CTRL_SFRST, DCP_REG_CTRL);
udelay(10);
return -EIO;
}
dev->dcp_vmi_irq = r->start;
- ret = request_irq(dev->dcp_vmi_irq, dcp_vmi_irq, 0, "dcp", dev);
+ ret = devm_request_irq(&pdev->dev, dev->dcp_vmi_irq, dcp_vmi_irq, 0,
+ "dcp", dev);
if (ret != 0) {
dev_err(&pdev->dev, "can't request_irq (0)\n");
return -EIO;
r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
if (!r) {
dev_err(&pdev->dev, "can't get IRQ resource (1)\n");
- ret = -EIO;
- goto err_free_irq0;
+ return -EIO;
}
dev->dcp_irq = r->start;
- ret = request_irq(dev->dcp_irq, dcp_irq, 0, "dcp", dev);
+ ret = devm_request_irq(&pdev->dev, dev->dcp_irq, dcp_irq, 0, "dcp",
+ dev);
if (ret != 0) {
dev_err(&pdev->dev, "can't request_irq (1)\n");
- ret = -EIO;
- goto err_free_irq0;
+ return -EIO;
}
dev->hw_pkg[0] = dma_alloc_coherent(&pdev->dev,
GFP_KERNEL);
if (!dev->hw_pkg[0]) {
dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
- ret = -ENOMEM;
- goto err_free_irq1;
+ return -ENOMEM;
}
for (i = 1; i < DCP_MAX_PKG; i++) {
for (j = 0; j < i; j++)
crypto_unregister_alg(&algs[j]);
err_free_key_iv:
+ tasklet_kill(&dev->done_task);
+ tasklet_kill(&dev->queue_task);
dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
dev->payload_base_dma);
err_free_hw_packet:
dma_free_coherent(&pdev->dev, DCP_MAX_PKG *
sizeof(struct dcp_hw_packet), dev->hw_pkg[0],
dev->hw_phys_pkg);
-err_free_irq1:
- free_irq(dev->dcp_irq, dev);
-err_free_irq0:
- free_irq(dev->dcp_vmi_irq, dev);
return ret;
}
int j;
dev = platform_get_drvdata(pdev);
- dma_free_coherent(&pdev->dev,
- DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
- dev->hw_pkg[0], dev->hw_phys_pkg);
-
- dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
- dev->payload_base_dma);
+ misc_deregister(&dev->dcp_bootstream_misc);
- free_irq(dev->dcp_irq, dev);
- free_irq(dev->dcp_vmi_irq, dev);
+ for (j = 0; j < ARRAY_SIZE(algs); j++)
+ crypto_unregister_alg(&algs[j]);
tasklet_kill(&dev->done_task);
tasklet_kill(&dev->queue_task);
- for (j = 0; j < ARRAY_SIZE(algs); j++)
- crypto_unregister_alg(&algs[j]);
+ dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
+ dev->payload_base_dma);
- misc_deregister(&dev->dcp_bootstream_misc);
+ dma_free_coherent(&pdev->dev,
+ DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
+ dev->hw_pkg[0], dev->hw_phys_pkg);
return 0;
}
unsigned int keylen)
{
struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
- struct rtattr *rta = (struct rtattr *)key;
- struct crypto_authenc_key_param *param;
+ struct crypto_authenc_keys keys;
- if (!RTA_OK(rta, keylen))
- goto badkey;
- if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
- goto badkey;
- if (RTA_PAYLOAD(rta) < sizeof(*param))
+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
goto badkey;
- param = RTA_DATA(rta);
- ctx->enckey_len = be32_to_cpu(param->enckeylen);
-
- key += RTA_ALIGN(rta->rta_len);
- keylen -= RTA_ALIGN(rta->rta_len);
+ if (keys.authkeylen > sizeof(ctx->authkey))
+ goto badkey;
- if (keylen < ctx->enckey_len)
+ if (keys.enckeylen > sizeof(ctx->enckey))
goto badkey;
- ctx->authkey_len = keylen - ctx->enckey_len;
- memcpy(ctx->enckey, key + ctx->authkey_len, ctx->enckey_len);
- memcpy(ctx->authkey, key, ctx->authkey_len);
+ memcpy(ctx->authkey, keys.authkey, keys.authkeylen);
+ memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
+ ctx->authkey_len = keys.authkeylen;
+ ctx->enckey_len = keys.enckeylen;
return aead_setup(tfm, crypto_aead_authsize(tfm));
badkey:
- ctx->enckey_len = 0;
crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
return mv_cra_hash_init(tfm, "sha1", COP_HMAC_SHA1, SHA1_BLOCK_SIZE);
}
-irqreturn_t crypto_int(int irq, void *priv)
+static irqreturn_t crypto_int(int irq, void *priv)
{
u32 val;
return IRQ_HANDLED;
}
-struct crypto_alg mv_aes_alg_ecb = {
+static struct crypto_alg mv_aes_alg_ecb = {
.cra_name = "ecb(aes)",
.cra_driver_name = "mv-ecb-aes",
.cra_priority = 300,
},
};
-struct crypto_alg mv_aes_alg_cbc = {
+static struct crypto_alg mv_aes_alg_cbc = {
.cra_name = "cbc(aes)",
.cra_driver_name = "mv-cbc-aes",
.cra_priority = 300,
},
};
-struct ahash_alg mv_sha1_alg = {
+static struct ahash_alg mv_sha1_alg = {
.init = mv_hash_init,
.update = mv_hash_update,
.final = mv_hash_final,
}
};
-struct ahash_alg mv_hmac_sha1_alg = {
+static struct ahash_alg mv_hmac_sha1_alg = {
.init = mv_hash_init,
.update = mv_hash_update,
.final = mv_hash_final,
goto err_unmap_sram;
}
- ret = request_irq(irq, crypto_int, IRQF_DISABLED, dev_name(&pdev->dev),
+ ret = request_irq(irq, crypto_int, 0, dev_name(&pdev->dev),
cp);
if (ret)
goto err_thread;
.driver = {
.owner = THIS_MODULE,
.name = "mv_crypto",
- .of_match_table = of_match_ptr(mv_cesa_of_match_table),
+ .of_match_table = mv_cesa_of_match_table,
},
};
MODULE_ALIAS("platform:mv_crypto");
if (dd->flags & FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
if (dd->flags & FLAGS_CTR) {
- val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
+ val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK;
}
if (dd->flags & FLAGS_ENCRYPT)
return err;
}
-int omap_aes_check_aligned(struct scatterlist *sg)
+static int omap_aes_check_aligned(struct scatterlist *sg)
{
while (sg) {
if (!IS_ALIGNED(sg->offset, 4))
return 0;
}
-int omap_aes_copy_sgs(struct omap_aes_dev *dd)
+static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
{
void *buf_in, *buf_out;
int pages;
MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support.");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Dmitry Kasatkin");
+MODULE_ALIAS("platform:omap-sham");
{
struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm);
struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg);
- struct rtattr *rta = (void *)key;
- struct crypto_authenc_key_param *param;
- unsigned int authkeylen, enckeylen;
+ struct crypto_authenc_keys keys;
int err = -EINVAL;
- if (!RTA_OK(rta, keylen))
+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
goto badkey;
- if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
+ if (keys.enckeylen > AES_MAX_KEY_SIZE)
goto badkey;
- if (RTA_PAYLOAD(rta) < sizeof(*param))
- goto badkey;
-
- param = RTA_DATA(rta);
- enckeylen = be32_to_cpu(param->enckeylen);
-
- key += RTA_ALIGN(rta->rta_len);
- keylen -= RTA_ALIGN(rta->rta_len);
-
- if (keylen < enckeylen)
- goto badkey;
-
- authkeylen = keylen - enckeylen;
-
- if (enckeylen > AES_MAX_KEY_SIZE)
+ if (keys.authkeylen > sizeof(ctx->hash_ctx))
goto badkey;
if ((alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
SPA_CTRL_CIPH_ALG_AES)
- err = spacc_aead_aes_setkey(tfm, key + authkeylen, enckeylen);
+ err = spacc_aead_aes_setkey(tfm, keys.enckey, keys.enckeylen);
else
- err = spacc_aead_des_setkey(tfm, key + authkeylen, enckeylen);
+ err = spacc_aead_des_setkey(tfm, keys.enckey, keys.enckeylen);
if (err)
goto badkey;
- memcpy(ctx->hash_ctx, key, authkeylen);
- ctx->hash_key_len = authkeylen;
+ memcpy(ctx->hash_ctx, keys.authkey, keys.authkeylen);
+ ctx->hash_key_len = keys.authkeylen;
return 0;
.driver = {
.name = SAHARA_NAME,
.owner = THIS_MODULE,
- .of_match_table = of_match_ptr(sahara_dt_ids),
+ .of_match_table = sahara_dt_ids,
},
.id_table = sahara_platform_ids,
};
const u8 *key, unsigned int keylen)
{
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct rtattr *rta = (void *)key;
- struct crypto_authenc_key_param *param;
- unsigned int authkeylen;
- unsigned int enckeylen;
-
- if (!RTA_OK(rta, keylen))
- goto badkey;
+ struct crypto_authenc_keys keys;
- if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
goto badkey;
- if (RTA_PAYLOAD(rta) < sizeof(*param))
+ if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
goto badkey;
- param = RTA_DATA(rta);
- enckeylen = be32_to_cpu(param->enckeylen);
-
- key += RTA_ALIGN(rta->rta_len);
- keylen -= RTA_ALIGN(rta->rta_len);
+ memcpy(ctx->key, keys.authkey, keys.authkeylen);
+ memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
- if (keylen < enckeylen)
- goto badkey;
-
- authkeylen = keylen - enckeylen;
-
- if (keylen > TALITOS_MAX_KEY_SIZE)
- goto badkey;
-
- memcpy(&ctx->key, key, keylen);
-
- ctx->keylen = keylen;
- ctx->enckeylen = enckeylen;
- ctx->authkeylen = authkeylen;
+ ctx->keylen = keys.authkeylen + keys.enckeylen;
+ ctx->enckeylen = keys.enckeylen;
+ ctx->authkeylen = keys.authkeylen;
return 0;
if (edesc->assoc_chained)
talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE);
- else
+ else if (areq->assoclen)
/* assoc_nents counts also for IV in non-contiguous cases */
dma_unmap_sg(dev, areq->assoc,
edesc->assoc_nents ? edesc->assoc_nents - 1 : 1,
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
} else {
- to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc));
+ if (areq->assoclen)
+ to_talitos_ptr(&desc->ptr[1],
+ sg_dma_address(areq->assoc));
+ else
+ to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);
desc->ptr[1].j_extent = 0;
}
unsigned int authsize,
unsigned int ivsize,
int icv_stashing,
- u32 cryptoflags)
+ u32 cryptoflags,
+ bool encrypt)
{
struct talitos_edesc *edesc;
int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
return ERR_PTR(-EINVAL);
}
- if (iv)
+ if (ivsize)
iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
- if (assoc) {
+ if (assoclen) {
/*
* Currently it is assumed that iv is provided whenever assoc
* is.
assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
}
- src_nents = sg_count(src, cryptlen + authsize, &src_chained);
- src_nents = (src_nents == 1) ? 0 : src_nents;
-
- if (!dst) {
- dst_nents = 0;
- } else {
- if (dst == src) {
- dst_nents = src_nents;
- } else {
- dst_nents = sg_count(dst, cryptlen + authsize,
- &dst_chained);
- dst_nents = (dst_nents == 1) ? 0 : dst_nents;
- }
+ if (!dst || dst == src) {
+ src_nents = sg_count(src, cryptlen + authsize, &src_chained);
+ src_nents = (src_nents == 1) ? 0 : src_nents;
+ dst_nents = dst ? src_nents : 0;
+ } else { /* dst && dst != src*/
+ src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize),
+ &src_chained);
+ src_nents = (src_nents == 1) ? 0 : src_nents;
+ dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0),
+ &dst_chained);
+ dst_nents = (dst_nents == 1) ? 0 : dst_nents;
}
/*
edesc = kmalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
- talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
+ if (assoc_chained)
+ talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
+ else if (assoclen)
+ dma_unmap_sg(dev, assoc,
+ assoc_nents ? assoc_nents - 1 : 1,
+ DMA_TO_DEVICE);
+
if (iv_dma)
dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
+
dev_err(dev, "could not allocate edescriptor\n");
return ERR_PTR(-ENOMEM);
}
}
static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
- int icv_stashing)
+ int icv_stashing, bool encrypt)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
iv, areq->assoclen, areq->cryptlen,
ctx->authsize, ivsize, icv_stashing,
- areq->base.flags);
+ areq->base.flags, encrypt);
}
static int aead_encrypt(struct aead_request *req)
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(req, req->iv, 0);
+ edesc = aead_edesc_alloc(req, req->iv, 0, true);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
req->cryptlen -= authsize;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(req, req->iv, 1);
+ edesc = aead_edesc_alloc(req, req->iv, 1, false);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(areq, req->giv, 0);
+ edesc = aead_edesc_alloc(areq, req->giv, 0, true);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
}
static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
- areq)
+ areq, bool encrypt)
{
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
areq->info, 0, areq->nbytes, 0, ivsize, 0,
- areq->base.flags);
+ areq->base.flags, encrypt);
}
static int ablkcipher_encrypt(struct ablkcipher_request *areq)
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = ablkcipher_edesc_alloc(areq);
+ edesc = ablkcipher_edesc_alloc(areq, true);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = ablkcipher_edesc_alloc(areq);
+ edesc = ablkcipher_edesc_alloc(areq, false);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
- nbytes, 0, 0, 0, areq->base.flags);
+ nbytes, 0, 0, 0, areq->base.flags, false);
}
static int ahash_init(struct ahash_request *areq)
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
static DECLARE_WORK(aes_work, aes_workqueue_handler);
static struct workqueue_struct *aes_wq;
-extern unsigned long long tegra_chip_uid(void);
-
static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset)
{
return readl(dd->io_base + offset);
struct tegra_aes_dev *dd = aes_dev;
struct tegra_aes_ctx *ctx = &rng_ctx;
struct tegra_aes_slot *key_slot;
- struct timespec ts;
int ret = 0;
- u64 nsec, tmp[2];
+ u8 tmp[16]; /* 16 bytes = 128 bits of entropy */
u8 *dt;
if (!ctx || !dd) {
- dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n",
+ pr_err("ctx=0x%x, dd=0x%x\n",
(unsigned int)ctx, (unsigned int)dd);
return -EINVAL;
}
if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) {
dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128;
} else {
- getnstimeofday(&ts);
- nsec = timespec_to_ns(&ts);
- do_div(nsec, 1000);
- nsec ^= dd->ctr << 56;
- dd->ctr++;
- tmp[0] = nsec;
- tmp[1] = tegra_chip_uid();
- dt = (u8 *)tmp;
+ get_random_bytes(tmp, sizeof(tmp));
+ dt = tmp;
}
memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ);
return 0;
}
-void tegra_aes_cra_exit(struct crypto_tfm *tfm)
+static void tegra_aes_cra_exit(struct crypto_tfm *tfm)
{
struct tegra_aes_ctx *ctx =
crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm);
}
/* Initialize the vde clock */
- dd->aes_clk = clk_get(dev, "vde");
+ dd->aes_clk = devm_clk_get(dev, "vde");
if (IS_ERR(dd->aes_clk)) {
dev_err(dev, "iclock intialization failed.\n");
err = -ENODEV;
if (dd->buf_out)
dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
dd->buf_out, dd->dma_buf_out);
- if (!IS_ERR(dd->aes_clk))
- clk_put(dd->aes_clk);
if (aes_wq)
destroy_workqueue(aes_wq);
spin_lock(&list_lock);
dd->buf_in, dd->dma_buf_in);
dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
dd->buf_out, dd->dma_buf_out);
- clk_put(dd->aes_clk);
aes_dev = NULL;
return 0;
}
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)
* 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);
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)
* @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)
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++) {
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);
return chan;
}
- return NULL;
+ return ERR_PTR(ret_no_channel);
}
/**
/*
* 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,
#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"
void *callback_param;
/* Channel-slave specific configuration */
+ unsigned int slave_id;
struct dma_slave_config dma_sconfig;
struct tegra_dma_channel_regs channel_reg;
};
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;
}
memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
+ if (!tdc->slave_id)
+ tdc->slave_id = sconfig->slave_id;
tdc->config_init = true;
return 0;
}
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;
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;
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 */
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);
}
/* 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);
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];
.cmd_per_lun = 1,
.can_queue = 1,
.sdev_attrs = sbp2_scsi_sysfs_attrs,
+ .no_write_same = 1,
};
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
static int efi_pstore_open(struct pstore_info *psi)
{
- efivar_entry_iter_begin();
psi->data = NULL;
return 0;
}
static int efi_pstore_close(struct pstore_info *psi)
{
- efivar_entry_iter_end();
psi->data = NULL;
return 0;
}
char **buf;
};
+static inline u64 generic_id(unsigned long timestamp,
+ unsigned int part, int count)
+{
+ return (timestamp * 100 + part) * 1000 + count;
+}
+
static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
cb_data->type, &part, &cnt, &time, &data_type) == 5) {
- *cb_data->id = part;
+ *cb_data->id = generic_id(time, part, cnt);
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
*cb_data->compressed = false;
} else if (sscanf(name, "dump-type%u-%u-%d-%lu",
cb_data->type, &part, &cnt, &time) == 4) {
- *cb_data->id = part;
+ *cb_data->id = generic_id(time, part, cnt);
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
* which doesn't support holding
* multiple logs, remains.
*/
- *cb_data->id = part;
+ *cb_data->id = generic_id(time, part, 0);
*cb_data->count = 0;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
__efivar_entry_get(entry, &entry->var.Attributes,
&entry->var.DataSize, entry->var.Data);
size = entry->var.DataSize;
+ memcpy(*cb_data->buf, entry->var.Data,
+ (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size));
- *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
- if (*cb_data->buf == NULL)
- return -ENOMEM;
return size;
}
+/**
+ * efi_pstore_scan_sysfs_enter
+ * @entry: scanning entry
+ * @next: next entry
+ * @head: list head
+ */
+static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,
+ struct efivar_entry *next,
+ struct list_head *head)
+{
+ pos->scanning = true;
+ if (&next->list != head)
+ next->scanning = true;
+}
+
+/**
+ * __efi_pstore_scan_sysfs_exit
+ * @entry: deleting entry
+ * @turn_off_scanning: Check if a scanning flag should be turned off
+ */
+static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
+ bool turn_off_scanning)
+{
+ if (entry->deleting) {
+ list_del(&entry->list);
+ efivar_entry_iter_end();
+ efivar_unregister(entry);
+ efivar_entry_iter_begin();
+ } else if (turn_off_scanning)
+ entry->scanning = false;
+}
+
+/**
+ * efi_pstore_scan_sysfs_exit
+ * @pos: scanning entry
+ * @next: next entry
+ * @head: list head
+ * @stop: a flag checking if scanning will stop
+ */
+static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
+ struct efivar_entry *next,
+ struct list_head *head, bool stop)
+{
+ __efi_pstore_scan_sysfs_exit(pos, true);
+ if (stop)
+ __efi_pstore_scan_sysfs_exit(next, &next->list != head);
+}
+
+/**
+ * efi_pstore_sysfs_entry_iter
+ *
+ * @data: function-specific data to pass to callback
+ * @pos: entry to begin iterating from
+ *
+ * You MUST call efivar_enter_iter_begin() before this function, and
+ * efivar_entry_iter_end() afterwards.
+ *
+ * It is possible to begin iteration from an arbitrary entry within
+ * the list by passing @pos. @pos is updated on return to point to
+ * the next entry of the last one passed to efi_pstore_read_func().
+ * To begin iterating from the beginning of the list @pos must be %NULL.
+ */
+static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
+{
+ struct efivar_entry *entry, *n;
+ struct list_head *head = &efivar_sysfs_list;
+ int size = 0;
+
+ if (!*pos) {
+ list_for_each_entry_safe(entry, n, head, list) {
+ efi_pstore_scan_sysfs_enter(entry, n, head);
+
+ size = efi_pstore_read_func(entry, data);
+ efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
+ if (size)
+ break;
+ }
+ *pos = n;
+ return size;
+ }
+
+ list_for_each_entry_safe_from((*pos), n, head, list) {
+ efi_pstore_scan_sysfs_enter((*pos), n, head);
+
+ size = efi_pstore_read_func((*pos), data);
+ efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
+ if (size)
+ break;
+ }
+ *pos = n;
+ return size;
+}
+
+/**
+ * efi_pstore_read
+ *
+ * This function returns a size of NVRAM entry logged via efi_pstore_write().
+ * The meaning and behavior of efi_pstore/pstore are as below.
+ *
+ * size > 0: Got data of an entry logged via efi_pstore_write() successfully,
+ * and pstore filesystem will continue reading subsequent entries.
+ * size == 0: Entry was not logged via efi_pstore_write(),
+ * and efi_pstore driver will continue reading subsequent entries.
+ * size < 0: Failed to get data of entry logging via efi_pstore_write(),
+ * and pstore will stop reading entry.
+ */
static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
char **buf, bool *compressed,
struct pstore_info *psi)
{
struct pstore_read_data data;
+ ssize_t size;
data.id = id;
data.type = type;
data.compressed = compressed;
data.buf = buf;
- return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
- (struct efivar_entry **)&psi->data);
+ *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
+ if (!*data.buf)
+ return -ENOMEM;
+
+ efivar_entry_iter_begin();
+ size = efi_pstore_sysfs_entry_iter(&data,
+ (struct efivar_entry **)&psi->data);
+ efivar_entry_iter_end();
+ if (size <= 0)
+ kfree(*data.buf);
+ return size;
}
static int efi_pstore_write(enum pstore_type_id type,
return 0;
}
+ if (entry->scanning) {
+ /*
+ * Skip deletion because this entry will be deleted
+ * after scanning is completed.
+ */
+ entry->deleting = true;
+ } else
+ list_del(&entry->list);
+
/* found */
__efivar_entry_delete(entry);
- list_del(&entry->list);
return 1;
}
char name[DUMP_NAME_LEN];
efi_char16_t efi_name[DUMP_NAME_LEN];
int found, i;
+ unsigned int part;
- sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
- time.tv_sec);
+ do_div(id, 1000);
+ part = do_div(id, 100);
+ sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec);
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];
- edata.id = id;
+ edata.id = part;
edata.type = type;
edata.count = count;
edata.time = time;
efivar_entry_iter_begin();
found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
- efivar_entry_iter_end();
- if (found)
+ if (found && !entry->scanning) {
+ efivar_entry_iter_end();
efivar_unregister(entry);
+ } else
+ efivar_entry_iter_end();
return 0;
}
else if (__efivar_entry_delete(entry))
err = -EIO;
- efivar_entry_iter_end();
-
- if (err)
+ if (err) {
+ efivar_entry_iter_end();
return err;
+ }
- efivar_unregister(entry);
+ if (!entry->scanning) {
+ efivar_entry_iter_end();
+ efivar_unregister(entry);
+ } else
+ efivar_entry_iter_end();
/* It's dead Jim.... */
return count;
if (!found)
return NULL;
- if (remove)
- list_del(&entry->list);
+ if (remove) {
+ if (entry->scanning) {
+ /*
+ * The entry will be deleted
+ * after scanning is completed.
+ */
+ entry->deleting = true;
+ } else
+ list_del(&entry->list);
+ }
return entry;
}
spin_unlock_irqrestore(&kona_gpio->lock, flags);
/* return the specified bit status */
- return !!(val & bit);
+ return !!(val & BIT(bit));
}
static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
u32 val;
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+ u32 out_mask, out_shadow;
- val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+ out_mask = in_be32(mm->regs + GPIO_DIR);
- return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+ val = in_be32(mm->regs + GPIO_DAT) & ~out_mask;
+ out_shadow = mpc8xxx_gc->data & out_mask;
+
+ return (val | out_shadow) & mpc8xxx_gpio2mask(gpio);
}
static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
struct irq_domain *domain;
- unsigned int summary_irq;
+ int summary_irq;
void __iomem *msm_tlmm_base;
};
spinlock_t lock;
void __iomem *membase;
void __iomem *percpu_membase;
- unsigned int irqbase;
+ int irqbase;
struct irq_domain *domain;
int soc_variant;
};
if (!chip->base)
return -ENOMEM;
- chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR,
- irq_base, &pl061_domain_ops, chip);
- if (!chip->domain)
- return -ENODEV;
-
spin_lock_init(&chip->lock);
chip->gc.request = pl061_gpio_request;
irq_set_chained_handler(irq, pl061_irq_handler);
irq_set_handler_data(irq, chip);
+ chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR,
+ irq_base, &pl061_domain_ops, chip);
+ if (!chip->domain)
+ return -ENODEV;
+
for (i = 0; i < PL061_GPIO_NR; i++) {
if (pdata) {
if (pdata->directions & (1 << i))
if (!p->irq_domain) {
ret = -ENXIO;
dev_err(&pdev->dev, "cannot initialize irq domain\n");
- goto err1;
+ goto err0;
}
if (devm_request_irq(&pdev->dev, irq->start,
int mask = BIT(offset);
int val = TB10X_GPIO_DIR_OUT << offset;
+ tb10x_gpio_set(chip, offset, value);
tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val);
return 0;
static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
{
struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip);
+ int ret = -EINVAL;
mutex_lock(&priv->mutex);
if (offset < TWL4030_GPIO_MAX)
- twl4030_set_gpio_dataout(offset, value);
+ ret = twl4030_set_gpio_direction(offset, 0);
priv->direction |= BIT(offset);
mutex_unlock(&priv->mutex);
twl_set(chip, offset, value);
- return 0;
+ return ret;
}
static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
static int gpio_twl4030_remove(struct platform_device *pdev);
-static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
+static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
+ struct twl4030_gpio_platform_data *pdata)
{
struct twl4030_gpio_platform_data *omap_twl_info;
if (!omap_twl_info)
return NULL;
+ if (pdata)
+ *omap_twl_info = *pdata;
+
omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
"ti,use-leds");
mutex_init(&priv->mutex);
if (node)
- pdata = of_gpio_twl4030(&pdev->dev);
+ pdata = of_gpio_twl4030(&pdev->dev, pdata);
if (pdata == NULL) {
dev_err(&pdev->dev, "Platform data is missing\n");
MODULE_DESCRIPTION("Philips UCB1400 GPIO driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ucb1400_gpio");
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/acpi.h>
+#include <linux/gpio/driver.h>
#define CREATE_TRACE_POINTS
#include <trace/events/gpio.h>
}
EXPORT_SYMBOL_GPL(gpiochip_find);
+static int gpiochip_match_name(struct gpio_chip *chip, void *data)
+{
+ const char *name = data;
+
+ return !strcmp(chip->label, name);
+}
+
+static struct gpio_chip *find_chip_by_name(const char *name)
+{
+ return gpiochip_find((void *)name, gpiochip_match_name);
+}
+
#ifdef CONFIG_PINCTRL
/**
ret = pinctrl_get_group_pins(pctldev, pin_group,
&pin_range->range.pins,
&pin_range->range.npins);
- if (ret < 0)
+ if (ret < 0) {
+ kfree(pin_range);
return ret;
+ }
pinctrl_add_gpio_range(pctldev, &pin_range->range);
mutex_unlock(&gpio_lookup_lock);
}
-/*
- * Caller must have a acquired gpio_lookup_lock
- */
-static struct gpio_chip *find_chip_by_name(const char *name)
-{
- struct gpio_chip *chip = NULL;
-
- list_for_each_entry(chip, &gpio_lookup_list, list) {
- if (chip->label == NULL)
- continue;
- if (!strcmp(chip->label, name))
- break;
- }
-
- return chip;
-}
-
#ifdef CONFIG_OF
static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
- unsigned int idx, unsigned long *flags)
+ unsigned int idx,
+ enum gpio_lookup_flags *flags)
{
char prop_name[32]; /* 32 is max size of property name */
enum of_gpio_flags of_flags;
return desc;
if (of_flags & OF_GPIO_ACTIVE_LOW)
- *flags |= GPIOF_ACTIVE_LOW;
+ *flags |= GPIO_ACTIVE_LOW;
return desc;
}
#else
static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
- unsigned int idx, unsigned long *flags)
+ unsigned int idx,
+ enum gpio_lookup_flags *flags)
{
return ERR_PTR(-ENODEV);
}
#endif
static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
- unsigned int idx, unsigned long *flags)
+ unsigned int idx,
+ enum gpio_lookup_flags *flags)
{
struct acpi_gpio_info info;
struct gpio_desc *desc;
return desc;
if (info.gpioint && info.active_low)
- *flags |= GPIOF_ACTIVE_LOW;
+ *flags |= GPIO_ACTIVE_LOW;
return desc;
}
static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
- unsigned int idx, unsigned long *flags)
+ unsigned int idx,
+ enum gpio_lookup_flags *flags)
{
const char *dev_id = dev ? dev_name(dev) : NULL;
struct gpio_desc *desc = ERR_PTR(-ENODEV);
continue;
}
- if (chip->ngpio >= p->chip_hwnum) {
+ if (chip->ngpio <= p->chip_hwnum) {
dev_warn(dev, "GPIO chip %s has %d GPIOs\n",
chip->label, chip->ngpio);
continue;
const char *con_id,
unsigned int idx)
{
- struct gpio_desc *desc;
+ struct gpio_desc *desc = NULL;
int status;
- unsigned long flags = 0;
+ enum gpio_lookup_flags flags = 0;
dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
} else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) {
dev_dbg(dev, "using ACPI for GPIO lookup\n");
desc = acpi_find_gpio(dev, con_id, idx, &flags);
- } else {
+ }
+
+ /*
+ * Either we are not using DT or ACPI, or their lookup did not return
+ * a result. In that case, use platform lookup as a fallback.
+ */
+ if (!desc || IS_ERR(desc)) {
+ struct gpio_desc *pdesc;
dev_dbg(dev, "using lookup tables for GPIO lookup");
- desc = gpiod_find(dev, con_id, idx, &flags);
+ pdesc = gpiod_find(dev, con_id, idx, &flags);
+ /* If used as fallback, do not replace the previous error */
+ if (!IS_ERR(pdesc) || !desc)
+ desc = pdesc;
}
if (IS_ERR(desc)) {
- dev_warn(dev, "lookup for GPIO %s failed\n", con_id);
+ dev_dbg(dev, "lookup for GPIO %s failed\n", con_id);
return desc;
}
if (status < 0)
return ERR_PTR(status);
- if (flags & GPIOF_ACTIVE_LOW)
+ if (flags & GPIO_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+ if (flags & GPIO_OPEN_DRAIN)
+ set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+ if (flags & GPIO_OPEN_SOURCE)
+ set_bit(FLAG_OPEN_SOURCE, &desc->flags);
return desc;
}
minor_str = "card%d";
minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL);
- if (!minor->dev) {
+ if (!minor->kdev) {
r = -ENOMEM;
goto error;
}
hwmon->hwmon = NULL;
return ret;
#else
- hwmon->hwmon = NULL;
return 0;
#endif
}
- DRM_FILE_OFFSET);
qxl_fence_remove_release(&bo->fence, release->id);
qxl_bo_unref(&bo);
+ kfree(entry);
}
spin_lock(&qdev->release_idr_lock);
idr_remove(&qdev->release_idr, release->id);
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
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
+#include <linux/reset.h>
#include "dc.h"
#include "drm.h"
unsigned long value;
/* hardware initialization */
- tegra_periph_reset_deassert(dc->clk);
+ reset_control_deassert(dc->rst);
usleep_range(10000, 20000);
if (dc->pipe)
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;
#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;
int pipe;
struct clk *clk;
+ struct reset_control *rst;
void __iomem *regs;
int irq;
#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"
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);
};
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;
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");
*/
#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"
struct clk *clk_parent;
struct clk *clk;
+ struct reset_control *rst;
const struct tegra_hdmi_config *config;
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);
{
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);
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;
- Stantum multitouch panels
- Touch International Panels
- Unitec Panels
+ - Wistron optical touch panels
- XAT optical touch panels
- Xiroku optical touch panels
- Zytronic touch panels
appleir->hid = hid;
+ /* force input as some remotes bypass the input registration */
+ hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
+
spin_lock_init(&appleir->lock);
setup_timer(&appleir->key_up_timer,
key_up_tick, (unsigned long) appleir);
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
{ }
};
#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE 0x0138
+#define USB_DEVICE_ID_GENIUS_MANTICORE 0x0153
#define USB_DEVICE_ID_GENIUS_GX_IMPERATOR 0x4018
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
#define USB_VENDOR_ID_NINTENDO 0x057e
-#define USB_VENDOR_ID_NINTENDO2 0x054c
#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
#define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330
#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
+#define USB_VENDOR_ID_WISTRON 0x0fb8
+#define USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH 0x1109
+
#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
case USB_DEVICE_ID_GENIUS_GX_IMPERATOR:
rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 83,
"Genius Gx Imperator Keyboard");
+ case USB_DEVICE_ID_GENIUS_MANTICORE:
+ rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104,
+ "Genius Manticore Keyboard");
break;
}
return rdesc;
goto enabling_err;
}
break;
+ case USB_DEVICE_ID_GENIUS_MANTICORE:
+ /*
+ * The manticore keyboard needs to have all the interfaces
+ * opened at least once to be fully functional.
+ */
+ if (hid_hw_open(hdev))
+ hid_hw_close(hdev);
+ break;
}
return 0;
USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+ USB_DEVICE_ID_GENIUS_MANTICORE) },
{ }
};
MODULE_DEVICE_TABLE(hid, kye_devices);
{ .driver_data = MT_CLS_NSMU,
MT_USB_DEVICE(USB_VENDOR_ID_UNITEC,
USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
+
+ /* Wistron panels */
+ { .driver_data = MT_CLS_NSMU,
+ MT_USB_DEVICE(USB_VENDOR_ID_WISTRON,
+ USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH) },
+
/* XAT */
{ .driver_data = MT_CLS_NSMU,
MT_USB_DEVICE(USB_VENDOR_ID_XAT,
struct sony_sc {
unsigned long quirks;
+#ifdef CONFIG_SONY_FF
+ struct work_struct rumble_worker;
+ struct hid_device *hdev;
+ __u8 left;
+ __u8 right;
+#endif
+
void *extra;
};
}
#ifdef CONFIG_SONY_FF
-static int sony_play_effect(struct input_dev *dev, void *data,
- struct ff_effect *effect)
+static void sony_rumble_worker(struct work_struct *work)
{
+ struct sony_sc *sc = container_of(work, struct sony_sc, rumble_worker);
unsigned char buf[] = {
0x01,
0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x27, 0x10, 0x00, 0x32,
0x00, 0x00, 0x00, 0x00, 0x00
};
- __u8 left;
- __u8 right;
+
+ buf[3] = sc->right;
+ buf[5] = sc->left;
+
+ sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
+ HID_OUTPUT_REPORT);
+}
+
+static int sony_play_effect(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
struct hid_device *hid = input_get_drvdata(dev);
+ struct sony_sc *sc = hid_get_drvdata(hid);
if (effect->type != FF_RUMBLE)
return 0;
- left = effect->u.rumble.strong_magnitude / 256;
- right = effect->u.rumble.weak_magnitude ? 1 : 0;
-
- buf[3] = right;
- buf[5] = left;
+ sc->left = effect->u.rumble.strong_magnitude / 256;
+ sc->right = effect->u.rumble.weak_magnitude ? 1 : 0;
- return hid->hid_output_raw_report(hid, buf, sizeof(buf),
- HID_OUTPUT_REPORT);
+ schedule_work(&sc->rumble_worker);
+ return 0;
}
static int sony_init_ff(struct hid_device *hdev)
struct hid_input *hidinput = list_entry(hdev->inputs.next,
struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
+ struct sony_sc *sc = hid_get_drvdata(hdev);
+
+ sc->hdev = hdev;
+ INIT_WORK(&sc->rumble_worker, sony_rumble_worker);
input_set_capability(input_dev, EV_FF, FF_RUMBLE);
return input_ff_create_memless(input_dev, NULL, sony_play_effect);
}
+static void sony_destroy_ff(struct hid_device *hdev)
+{
+ struct sony_sc *sc = hid_get_drvdata(hdev);
+
+ cancel_work_sync(&sc->rumble_worker);
+}
+
#else
static int sony_init_ff(struct hid_device *hdev)
{
return 0;
}
+
+static void sony_destroy_ff(struct hid_device *hdev)
+{
+}
#endif
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (sc->quirks & BUZZ_CONTROLLER)
buzz_remove(hdev);
+ sony_destroy_ff(hdev);
+
hid_hw_stop(hdev);
}
goto done;
}
- if (vendor == USB_VENDOR_ID_NINTENDO ||
- vendor == USB_VENDOR_ID_NINTENDO2) {
+ if (vendor == USB_VENDOR_ID_NINTENDO) {
if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE) {
devtype = WIIMOTE_DEV_GEN10;
goto done;
static const struct hid_device_id wiimote_hid_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
USB_DEVICE_ID_NINTENDO_WIIMOTE) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2,
- USB_DEVICE_ID_NINTENDO_WIIMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
{ }
*/
struct uhid_create_req_compat *compat;
- compat = kmalloc(sizeof(*compat), GFP_KERNEL);
+ compat = kzalloc(sizeof(*compat), GFP_KERNEL);
if (!compat)
return -ENOMEM;
#include <linux/err.h>
#include <acpi/acpi.h>
-#include <acpi/acpixf.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/clk.h>
#include <linux/slab.h>
/* Hardware register offsets and field defintions */
{.compatible = "brcm,kona-i2c",},
{},
};
-MODULE_DEVICE_TABLE(of, kona_i2c_of_match);
+MODULE_DEVICE_TABLE(of, bcm_kona_i2c_of_match);
static struct platform_driver bcm_kona_i2c_driver = {
.driver = {
strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));
adap->algo = &bcm2835_i2c_algo;
adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = pdev->dev.of_node;
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,
int reg, u16 val)
{
- __raw_writew(val, i2c_dev->base + reg);
+ writew_relaxed(val, i2c_dev->base + reg);
}
static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
{
- return __raw_readw(i2c_dev->base + reg);
+ return readw_relaxed(i2c_dev->base + reg);
}
/* Generate a pulse on the i2c clock pin. */
#define USB_VENDOR_ID_DIOLAN 0x0abf
#define USB_DEVICE_ID_DIOLAN_U2C 0x3370
-#define DIOLAN_OUT_EP 0x02
-#define DIOLAN_IN_EP 0x84
/* commands via USB, must match command ids in the firmware */
#define CMD_I2C_READ 0x01
struct i2c_diolan_u2c {
u8 obuffer[DIOLAN_OUTBUF_LEN]; /* output buffer */
u8 ibuffer[DIOLAN_INBUF_LEN]; /* input buffer */
+ int ep_in, ep_out; /* Endpoints */
struct usb_device *usb_dev; /* the usb device for this device */
struct usb_interface *interface;/* the interface for this device */
struct i2c_adapter adapter; /* i2c related things */
return -EINVAL;
ret = usb_bulk_msg(dev->usb_dev,
- usb_sndbulkpipe(dev->usb_dev, DIOLAN_OUT_EP),
+ usb_sndbulkpipe(dev->usb_dev, dev->ep_out),
dev->obuffer, dev->olen, &actual,
DIOLAN_USB_TIMEOUT);
if (!ret) {
tmpret = usb_bulk_msg(dev->usb_dev,
usb_rcvbulkpipe(dev->usb_dev,
- DIOLAN_IN_EP),
+ dev->ep_in),
dev->ibuffer,
sizeof(dev->ibuffer), &actual,
DIOLAN_USB_TIMEOUT);
int ret;
ret = usb_bulk_msg(dev->usb_dev,
- usb_rcvbulkpipe(dev->usb_dev, DIOLAN_IN_EP),
+ usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),
dev->ibuffer, sizeof(dev->ibuffer), &actual,
DIOLAN_USB_TIMEOUT);
if (ret < 0 || actual == 0)
static int diolan_u2c_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
+ struct usb_host_interface *hostif = interface->cur_altsetting;
struct i2c_diolan_u2c *dev;
int ret;
+ if (hostif->desc.bInterfaceNumber != 0
+ || hostif->desc.bNumEndpoints < 2)
+ return -ENODEV;
+
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
ret = -ENOMEM;
goto error;
}
+ dev->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
+ dev->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface;
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
int reg, u16 val)
{
- __raw_writew(val, i2c_dev->base +
+ writew_relaxed(val, i2c_dev->base +
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
{
- return __raw_readw(i2c_dev->base +
+ return readw_relaxed(i2c_dev->base +
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
};
#ifdef CONFIG_OF
+static struct omap_i2c_bus_platform_data omap2420_pdata = {
+ .rev = OMAP_I2C_IP_VERSION_1,
+ .flags = OMAP_I2C_FLAG_NO_FIFO |
+ OMAP_I2C_FLAG_SIMPLE_CLOCK |
+ OMAP_I2C_FLAG_16BIT_DATA_REG |
+ OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+static struct omap_i2c_bus_platform_data omap2430_pdata = {
+ .rev = OMAP_I2C_IP_VERSION_1,
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 |
+ OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
+};
+
static struct omap_i2c_bus_platform_data omap3_pdata = {
.rev = OMAP_I2C_IP_VERSION_1,
.flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
.compatible = "ti,omap3-i2c",
.data = &omap3_pdata,
},
+ {
+ .compatible = "ti,omap2430-i2c",
+ .data = &omap2430_pdata,
+ },
+ {
+ .compatible = "ti,omap2420-i2c",
+ .data = &omap2420_pdata,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
* Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
* On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset.
* Also since the omap_i2c_read_reg uses reg_map_ip_* a
- * raw_readw is done.
+ * readw_relaxed is done.
*/
- rev = __raw_readw(dev->base + 0x04);
+ rev = readw_relaxed(dev->base + 0x04);
dev->scheme = OMAP_I2C_SCHEME(rev);
switch (dev->scheme) {
#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>
struct i2c_adapter adapter;
struct clk *div_clk;
struct clk *fast_clk;
+ struct reset_control *rst;
void __iomem *base;
int cont_id;
int irq;
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);
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)
{
.enter = NULL }
};
-static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = {
+static struct cpuidle_state avn_cstates[] __initdata = {
{
.name = "C1-AVN",
.desc = "MWAIT 0x00",
{
.name = "C6-AVN",
.desc = "MWAIT 0x51",
- .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
+ .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 15,
.target_residency = 45,
.enter = &intel_idle },
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
{
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
mutex_lock(&st->buf_lock);
st->tx[0] = KXSD9_READ(address);
ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
- if (ret)
- return ret;
- return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+ if (!ret)
+ ret = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+ mutex_unlock(&st->buf_lock);
+ return ret;
}
static IIO_CONST_ATTR(accel_scale_available,
} else {
if (!st->caps->has_tsmr) {
dev_err(&pdev->dev, "We don't support non-TSMR adc\n");
+ ret = -ENODEV;
goto error_disable_adc_clk;
}
/* sample rates to sign extension table */
static const int mcp3422_sign_extend[4] = {
- [MCP3422_SRATE_240] = 12,
- [MCP3422_SRATE_60] = 14,
- [MCP3422_SRATE_15] = 16,
- [MCP3422_SRATE_3] = 18 };
+ [MCP3422_SRATE_240] = 11,
+ [MCP3422_SRATE_60] = 13,
+ [MCP3422_SRATE_15] = 15,
+ [MCP3422_SRATE_3] = 17 };
/* Client data (each client gets its own) */
struct mcp3422 {
unsigned long flags,
const struct iio_buffer_setup_ops *setup_ops)
{
+ struct iio_buffer *buffer;
int ret;
- indio_dev->buffer = iio_kfifo_allocate(indio_dev);
- if (!indio_dev->buffer)
+ buffer = iio_kfifo_allocate(indio_dev);
+ if (!buffer)
return -ENOMEM;
+ iio_device_attach_buffer(indio_dev, buffer);
+
ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
flags, indio_dev->name, indio_dev);
if (ret)
return 0;
}
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev)
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
{
- iio_trigger_unregister(indio_dev->trig);
- iio_trigger_free(indio_dev->trig);
- indio_dev->trig = NULL;
+ iio_trigger_unregister(attrb->trigger);
+ iio_trigger_free(attrb->trigger);
}
EXPORT_SYMBOL(hid_sensor_remove_trigger);
dev_err(&indio_dev->dev, "Trigger Register Failed\n");
goto error_free_trig;
}
- indio_dev->trig = trig;
+ indio_dev->trig = attrb->trigger = trig;
return ret;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev);
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
#endif
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
{
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
config TCS3472
tristate "TAOS TCS3472 color light-to-digital converter"
depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
If you say yes here you get support for the TAOS TCS3472
family of color light-to-digital converters with IR filter.
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
{
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct als_state *als_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
config MAG3110
tristate "Freescale MAG3110 3-Axis Magnetometer"
depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the Freescale MAG3110 3-Axis
magnetometer.
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&magn_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
{
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct magn_3d_state *magn_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev);
+ hid_sensor_remove_trigger(&magn_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_SCALE), \
.scan_index = idx, \
- .scan_type = IIO_ST('s', 16, 16, IIO_BE), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
}
static const struct iio_chan_spec mag3110_channels[] = {
#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
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;
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);
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
if (WARN_ON(down_interruptible(&i8042tregs)))
return -1;
- if (hp_sdc_enqueue_transaction(&t)) return -1;
+ if (hp_sdc_enqueue_transaction(&t)) {
+ up(&i8042tregs);
+ return -1;
+ }
/* Sleep until results come back. */
if (WARN_ON(down_interruptible(&i8042tregs)))
To compile this driver as a module, choose M here: the
module will be called stmpe-ts.
+config TOUCHSCREEN_SUR40
+ tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
+ depends on USB
+ select INPUT_POLLDEV
+ help
+ Say Y here if you want support for the Samsung SUR40 touchscreen
+ (also known as Microsoft Surface 2.0 or Microsoft PixelSense).
+
+ To compile this driver as a module, choose M here: the
+ module will be called sur40.
+
config TOUCHSCREEN_TPS6507X
tristate "TPS6507x based touchscreens"
depends on I2C
obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
+obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o
obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o
obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
}
#ifdef CONFIG_PM_SLEEP
-static int atmel_wm97xx_suspend(struct *dev)
+static int atmel_wm97xx_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev);
dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__);
- if (!work_pending(&cd->watchdog_work))
- schedule_work(&cd->watchdog_work);
+ schedule_work(&cd->watchdog_work);
return;
}
--- /dev/null
+/*
+ * Surface2.0/SUR40/PixelSense input driver
+ *
+ * Copyright (c) 2013 by Florian 'floe' Echtler <floe@butterbrot.org>
+ *
+ * Derived from the USB Skeleton driver 1.1,
+ * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * and from the Apple USB BCM5974 multitouch driver,
+ * Copyright (c) 2008 Henrik Rydberg (rydberg@euromail.se)
+ *
+ * and from the generic hid-multitouch driver,
+ * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/printk.h>
+#include <linux/input-polldev.h>
+#include <linux/input/mt.h>
+#include <linux/usb/input.h>
+
+/* read 512 bytes from endpoint 0x86 -> get header + blobs */
+struct sur40_header {
+
+ __le16 type; /* always 0x0001 */
+ __le16 count; /* count of blobs (if 0: continue prev. packet) */
+
+ __le32 packet_id; /* unique ID for all packets in one frame */
+
+ __le32 timestamp; /* milliseconds (inc. by 16 or 17 each frame) */
+ __le32 unknown; /* "epoch?" always 02/03 00 00 00 */
+
+} __packed;
+
+struct sur40_blob {
+
+ __le16 blob_id;
+
+ u8 action; /* 0x02 = enter/exit, 0x03 = update (?) */
+ u8 unknown; /* always 0x01 or 0x02 (no idea what this is?) */
+
+ __le16 bb_pos_x; /* upper left corner of bounding box */
+ __le16 bb_pos_y;
+
+ __le16 bb_size_x; /* size of bounding box */
+ __le16 bb_size_y;
+
+ __le16 pos_x; /* finger tip position */
+ __le16 pos_y;
+
+ __le16 ctr_x; /* centroid position */
+ __le16 ctr_y;
+
+ __le16 axis_x; /* somehow related to major/minor axis, mostly: */
+ __le16 axis_y; /* axis_x == bb_size_y && axis_y == bb_size_x */
+
+ __le32 angle; /* orientation in radians relative to x axis -
+ actually an IEEE754 float, don't use in kernel */
+
+ __le32 area; /* size in pixels/pressure (?) */
+
+ u8 padding[32];
+
+} __packed;
+
+/* combined header/blob data */
+struct sur40_data {
+ struct sur40_header header;
+ struct sur40_blob blobs[];
+} __packed;
+
+
+/* version information */
+#define DRIVER_SHORT "sur40"
+#define DRIVER_AUTHOR "Florian 'floe' Echtler <floe@butterbrot.org>"
+#define DRIVER_DESC "Surface2.0/SUR40/PixelSense input driver"
+
+/* vendor and device IDs */
+#define ID_MICROSOFT 0x045e
+#define ID_SUR40 0x0775
+
+/* sensor resolution */
+#define SENSOR_RES_X 1920
+#define SENSOR_RES_Y 1080
+
+/* touch data endpoint */
+#define TOUCH_ENDPOINT 0x86
+
+/* polling interval (ms) */
+#define POLL_INTERVAL 10
+
+/* maximum number of contacts FIXME: this is a guess? */
+#define MAX_CONTACTS 64
+
+/* control commands */
+#define SUR40_GET_VERSION 0xb0 /* 12 bytes string */
+#define SUR40_UNKNOWN1 0xb3 /* 5 bytes */
+#define SUR40_UNKNOWN2 0xc1 /* 24 bytes */
+
+#define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */
+#define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */
+
+/*
+ * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
+ * here by mistake which is very likely to have corrupted the firmware EEPROM
+ * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
+ * Should you ever run into a similar problem, the background story to this
+ * incident and instructions on how to fix the corrupted EEPROM are available
+ * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
+*/
+
+struct sur40_state {
+
+ struct usb_device *usbdev;
+ struct device *dev;
+ struct input_polled_dev *input;
+
+ struct sur40_data *bulk_in_buffer;
+ size_t bulk_in_size;
+ u8 bulk_in_epaddr;
+
+ char phys[64];
+};
+
+static int sur40_command(struct sur40_state *dev,
+ u8 command, u16 index, void *buffer, u16 size)
+{
+ return usb_control_msg(dev->usbdev, usb_rcvctrlpipe(dev->usbdev, 0),
+ command,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ 0x00, index, buffer, size, 1000);
+}
+
+/* Initialization routine, called from sur40_open */
+static int sur40_init(struct sur40_state *dev)
+{
+ int result;
+ u8 buffer[24];
+
+ /* stupidly replay the original MS driver init sequence */
+ result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12);
+ if (result < 0)
+ return result;
+
+ result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12);
+ if (result < 0)
+ return result;
+
+ result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12);
+ if (result < 0)
+ return result;
+
+ result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24);
+ if (result < 0)
+ return result;
+
+ result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5);
+ if (result < 0)
+ return result;
+
+ result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12);
+
+ /*
+ * Discard the result buffer - no known data inside except
+ * some version strings, maybe extract these sometime...
+ */
+
+ return result;
+}
+
+/*
+ * Callback routines from input_polled_dev
+ */
+
+/* Enable the device, polling will now start. */
+static void sur40_open(struct input_polled_dev *polldev)
+{
+ struct sur40_state *sur40 = polldev->private;
+
+ dev_dbg(sur40->dev, "open\n");
+ sur40_init(sur40);
+}
+
+/* Disable device, polling has stopped. */
+static void sur40_close(struct input_polled_dev *polldev)
+{
+ struct sur40_state *sur40 = polldev->private;
+
+ dev_dbg(sur40->dev, "close\n");
+ /*
+ * There is no known way to stop the device, so we simply
+ * stop polling.
+ */
+}
+
+/*
+ * This function is called when a whole contact has been processed,
+ * so that it can assign it to a slot and store the data there.
+ */
+static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
+{
+ int wide, major, minor;
+
+ int bb_size_x = le16_to_cpu(blob->bb_size_x);
+ int bb_size_y = le16_to_cpu(blob->bb_size_y);
+
+ int pos_x = le16_to_cpu(blob->pos_x);
+ int pos_y = le16_to_cpu(blob->pos_y);
+
+ int ctr_x = le16_to_cpu(blob->ctr_x);
+ int ctr_y = le16_to_cpu(blob->ctr_y);
+
+ int slotnum = input_mt_get_slot_by_key(input, blob->blob_id);
+ if (slotnum < 0 || slotnum >= MAX_CONTACTS)
+ return;
+
+ input_mt_slot(input, slotnum);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
+ wide = (bb_size_x > bb_size_y);
+ major = max(bb_size_x, bb_size_y);
+ minor = min(bb_size_x, bb_size_y);
+
+ input_report_abs(input, ABS_MT_POSITION_X, pos_x);
+ input_report_abs(input, ABS_MT_POSITION_Y, pos_y);
+ input_report_abs(input, ABS_MT_TOOL_X, ctr_x);
+ input_report_abs(input, ABS_MT_TOOL_Y, ctr_y);
+
+ /* TODO: use a better orientation measure */
+ input_report_abs(input, ABS_MT_ORIENTATION, wide);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR, major);
+ input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
+}
+
+/* core function: poll for new input data */
+static void sur40_poll(struct input_polled_dev *polldev)
+{
+
+ struct sur40_state *sur40 = polldev->private;
+ struct input_dev *input = polldev->input;
+ int result, bulk_read, need_blobs, packet_blobs, i;
+ u32 packet_id;
+
+ struct sur40_header *header = &sur40->bulk_in_buffer->header;
+ struct sur40_blob *inblob = &sur40->bulk_in_buffer->blobs[0];
+
+ dev_dbg(sur40->dev, "poll\n");
+
+ need_blobs = -1;
+
+ do {
+
+ /* perform a blocking bulk read to get data from the device */
+ result = usb_bulk_msg(sur40->usbdev,
+ usb_rcvbulkpipe(sur40->usbdev, sur40->bulk_in_epaddr),
+ sur40->bulk_in_buffer, sur40->bulk_in_size,
+ &bulk_read, 1000);
+
+ dev_dbg(sur40->dev, "received %d bytes\n", bulk_read);
+
+ if (result < 0) {
+ dev_err(sur40->dev, "error in usb_bulk_read\n");
+ return;
+ }
+
+ result = bulk_read - sizeof(struct sur40_header);
+
+ if (result % sizeof(struct sur40_blob) != 0) {
+ dev_err(sur40->dev, "transfer size mismatch\n");
+ return;
+ }
+
+ /* first packet? */
+ if (need_blobs == -1) {
+ need_blobs = le16_to_cpu(header->count);
+ dev_dbg(sur40->dev, "need %d blobs\n", need_blobs);
+ packet_id = header->packet_id;
+ }
+
+ /*
+ * Sanity check. when video data is also being retrieved, the
+ * packet ID will usually increase in the middle of a series
+ * instead of at the end.
+ */
+ if (packet_id != header->packet_id)
+ dev_warn(sur40->dev, "packet ID mismatch\n");
+
+ packet_blobs = result / sizeof(struct sur40_blob);
+ dev_dbg(sur40->dev, "received %d blobs\n", packet_blobs);
+
+ /* packets always contain at least 4 blobs, even if empty */
+ if (packet_blobs > need_blobs)
+ packet_blobs = need_blobs;
+
+ for (i = 0; i < packet_blobs; i++) {
+ need_blobs--;
+ dev_dbg(sur40->dev, "processing blob\n");
+ sur40_report_blob(&(inblob[i]), input);
+ }
+
+ } while (need_blobs > 0);
+
+ input_mt_sync_frame(input);
+ input_sync(input);
+}
+
+/* Initialize input device parameters. */
+static void sur40_input_setup(struct input_dev *input_dev)
+{
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_ABS, input_dev->evbit);
+
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+ 0, SENSOR_RES_X, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+ 0, SENSOR_RES_Y, 0, 0);
+
+ input_set_abs_params(input_dev, ABS_MT_TOOL_X,
+ 0, SENSOR_RES_X, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOOL_Y,
+ 0, SENSOR_RES_Y, 0, 0);
+
+ /* max value unknown, but major/minor axis
+ * can never be larger than screen */
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+ 0, SENSOR_RES_X, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+ 0, SENSOR_RES_Y, 0, 0);
+
+ input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
+
+ input_mt_init_slots(input_dev, MAX_CONTACTS,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+}
+
+/* Check candidate USB interface. */
+static int sur40_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *usbdev = interface_to_usbdev(interface);
+ struct sur40_state *sur40;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ struct input_polled_dev *poll_dev;
+ int error;
+
+ /* Check if we really have the right interface. */
+ iface_desc = &interface->altsetting[0];
+ if (iface_desc->desc.bInterfaceClass != 0xFF)
+ return -ENODEV;
+
+ /* Use endpoint #4 (0x86). */
+ endpoint = &iface_desc->endpoint[4].desc;
+ if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
+ return -ENODEV;
+
+ /* Allocate memory for our device state and initialize it. */
+ sur40 = kzalloc(sizeof(struct sur40_state), GFP_KERNEL);
+ if (!sur40)
+ return -ENOMEM;
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ error = -ENOMEM;
+ goto err_free_dev;
+ }
+
+ /* Set up polled input device control structure */
+ poll_dev->private = sur40;
+ poll_dev->poll_interval = POLL_INTERVAL;
+ poll_dev->open = sur40_open;
+ poll_dev->poll = sur40_poll;
+ poll_dev->close = sur40_close;
+
+ /* Set up regular input device structure */
+ sur40_input_setup(poll_dev->input);
+
+ poll_dev->input->name = "Samsung SUR40";
+ usb_to_input_id(usbdev, &poll_dev->input->id);
+ usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys));
+ strlcat(sur40->phys, "/input0", sizeof(sur40->phys));
+ poll_dev->input->phys = sur40->phys;
+ poll_dev->input->dev.parent = &interface->dev;
+
+ sur40->usbdev = usbdev;
+ sur40->dev = &interface->dev;
+ sur40->input = poll_dev;
+
+ /* use the bulk-in endpoint tested above */
+ sur40->bulk_in_size = usb_endpoint_maxp(endpoint);
+ sur40->bulk_in_epaddr = endpoint->bEndpointAddress;
+ sur40->bulk_in_buffer = kmalloc(sur40->bulk_in_size, GFP_KERNEL);
+ if (!sur40->bulk_in_buffer) {
+ dev_err(&interface->dev, "Unable to allocate input buffer.");
+ error = -ENOMEM;
+ goto err_free_polldev;
+ }
+
+ error = input_register_polled_device(poll_dev);
+ if (error) {
+ dev_err(&interface->dev,
+ "Unable to register polled input device.");
+ goto err_free_buffer;
+ }
+
+ /* we can register the device now, as it is ready */
+ usb_set_intfdata(interface, sur40);
+ dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC);
+
+ return 0;
+
+err_free_buffer:
+ kfree(sur40->bulk_in_buffer);
+err_free_polldev:
+ input_free_polled_device(sur40->input);
+err_free_dev:
+ kfree(sur40);
+
+ return error;
+}
+
+/* Unregister device & clean up. */
+static void sur40_disconnect(struct usb_interface *interface)
+{
+ struct sur40_state *sur40 = usb_get_intfdata(interface);
+
+ input_unregister_polled_device(sur40->input);
+ input_free_polled_device(sur40->input);
+ kfree(sur40->bulk_in_buffer);
+ kfree(sur40);
+
+ usb_set_intfdata(interface, NULL);
+ dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
+}
+
+static const struct usb_device_id sur40_table[] = {
+ { USB_DEVICE(ID_MICROSOFT, ID_SUR40) }, /* Samsung SUR40 */
+ { } /* terminating null entry */
+};
+MODULE_DEVICE_TABLE(usb, sur40_table);
+
+/* USB-specific object needed to register this driver with the USB subsystem. */
+static struct usb_driver sur40_driver = {
+ .name = DRIVER_SHORT,
+ .probe = sur40_probe,
+ .disconnect = sur40_disconnect,
+ .id_table = sur40_table,
+};
+
+module_usb_driver(sur40_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
if (WARN_ON(!gic->domain))
return;
+ if (gic_nr == 0) {
#ifdef CONFIG_SMP
- set_smp_cross_call(gic_raise_softirq);
- register_cpu_notifier(&gic_cpu_notifier);
+ set_smp_cross_call(gic_raise_softirq);
+ register_cpu_notifier(&gic_cpu_notifier);
#endif
-
- set_handle_irq(gic_handle_irq);
+ set_handle_irq(gic_handle_irq);
+ }
gic_chip.flags |= gic_arch_extn.flags;
gic_dist_init(gic);
(sizeof(struct led_pwm_data) * num_leds);
}
-static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
+static int led_pwm_create_of(struct platform_device *pdev,
+ struct led_pwm_priv *priv)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *child;
- struct led_pwm_priv *priv;
- int count, ret;
-
- /* count LEDs in this device, so we know how much to allocate */
- count = of_get_child_count(node);
- if (!count)
- return NULL;
-
- priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
- GFP_KERNEL);
- if (!priv)
- return NULL;
+ int ret;
for_each_child_of_node(node, child) {
struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
if (IS_ERR(led_dat->pwm)) {
dev_err(&pdev->dev, "unable to request PWM for %s\n",
led_dat->cdev.name);
+ ret = PTR_ERR(led_dat->pwm);
goto err;
}
/* Get the period from PWM core when n*/
priv->num_leds++;
}
- return priv;
+ return 0;
err:
while (priv->num_leds--)
led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
- return NULL;
+ return ret;
}
static int led_pwm_probe(struct platform_device *pdev)
{
struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct led_pwm_priv *priv;
- int i, ret = 0;
+ int count, i;
+ int ret = 0;
+
+ if (pdata)
+ count = pdata->num_leds;
+ else
+ count = of_get_child_count(pdev->dev.of_node);
+
+ if (!count)
+ return -EINVAL;
- if (pdata && pdata->num_leds) {
- priv = devm_kzalloc(&pdev->dev,
- sizeof_pwm_leds_priv(pdata->num_leds),
- GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
+ priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- for (i = 0; i < pdata->num_leds; i++) {
+ if (pdata) {
+ for (i = 0; i < count; i++) {
struct led_pwm *cur_led = &pdata->leds[i];
struct led_pwm_data *led_dat = &priv->leds[i];
if (ret < 0)
goto err;
}
- priv->num_leds = pdata->num_leds;
+ priv->num_leds = count;
} else {
- priv = led_pwm_create_of(pdev);
- if (!priv)
- return -ENODEV;
+ ret = led_pwm_create_of(pdev, priv);
+ if (ret)
+ return ret;
}
platform_set_drvdata(pdev, priv);
windfarm_ad7417_sensor.o \
windfarm_lm75_sensor.o \
windfarm_lm87_sensor.o \
+ windfarm_max6690_sensor.o \
windfarm_pid.o \
windfarm_cpufreq_clamp.o \
windfarm_rm31.o
finish_wait(&mddev->sb_wait, &wq);
}
-static void bi_complete(struct bio *bio, int error)
-{
- complete((struct completion*)bio->bi_private);
-}
-
int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
struct page *page, int rw, bool metadata_op)
{
struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
- struct completion event;
int ret;
rw |= REQ_SYNC;
else
bio->bi_sector = sector + rdev->data_offset;
bio_add_page(bio, page, size, 0);
- init_completion(&event);
- bio->bi_private = &event;
- bio->bi_end_io = bi_complete;
- submit_bio(rw, bio);
- wait_for_completion(&event);
+ submit_bio_wait(rw, bio);
ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
bio_put(bio);
if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
return;
if ( ! (
- (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
+ (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<<MD_CHANGE_PENDING)) ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
(mddev->external == 0 && mddev->safemode == 1) ||
} else
init_stripe(sh, sector, previous);
} else {
+ spin_lock(&conf->device_lock);
if (atomic_read(&sh->count)) {
BUG_ON(!list_empty(&sh->lru)
&& !test_bit(STRIPE_EXPANDING, &sh->state)
&& !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)
- && !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state));
+ );
} else {
- spin_lock(&conf->device_lock);
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
- if (list_empty(&sh->lru) &&
- !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state) &&
- !test_bit(STRIPE_EXPANDING, &sh->state))
- BUG();
+ BUG_ON(list_empty(&sh->lru));
list_del_init(&sh->lru);
if (sh->group) {
sh->group->stripes_cnt--;
sh->group = NULL;
}
- spin_unlock(&conf->device_lock);
}
+ spin_unlock(&conf->device_lock);
}
} while (sh == NULL);
for (i = 0; i < *group_cnt; i++) {
struct r5worker_group *group;
- group = worker_groups[i];
+ group = &(*worker_groups)[i];
INIT_LIST_HEAD(&group->handle_list);
group->conf = conf;
group->workers = workers + i * cnt;
{
char name[ENCLOSURE_NAME_SIZE];
+ /*
+ * In odd circumstances, like multipath devices, something else may
+ * already have removed the links, so check for this condition first.
+ */
+ if (!cdev->dev->kobj.sd)
+ return;
+
enclosure_link_name(cdev, name);
sysfs_remove_link(&cdev->dev->kobj, name);
sysfs_remove_link(&cdev->cdev.kobj, "device");
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
+#include <linux/of.h>
#include <linux/omap-dma.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#define OMAP_MMC_CMDTYPE_AC 2
#define OMAP_MMC_CMDTYPE_ADTC 3
-#define OMAP_DMA_MMC_TX 21
-#define OMAP_DMA_MMC_RX 22
-#define OMAP_DMA_MMC2_TX 54
-#define OMAP_DMA_MMC2_RX 55
-
-#define OMAP24XX_DMA_MMC2_TX 47
-#define OMAP24XX_DMA_MMC2_RX 48
-#define OMAP24XX_DMA_MMC1_TX 61
-#define OMAP24XX_DMA_MMC1_RX 62
-
-
#define DRIVER_NAME "mmci-omap"
/* Specifies how often in millisecs to poll for card status changes
struct mmc_omap_host *host = NULL;
struct resource *res;
dma_cap_mask_t mask;
- unsigned sig;
+ unsigned sig = 0;
int i, ret = 0;
int irq;
}
if (pdata->nr_slots == 0) {
dev_err(&pdev->dev, "no slots\n");
- return -ENXIO;
+ return -EPROBE_DEFER;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->dma_tx_burst = -1;
host->dma_rx_burst = -1;
- if (mmc_omap2())
- sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX;
- else
- sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
- host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+ if (res)
+ sig = res->start;
+ host->dma_tx = dma_request_slave_channel_compat(mask,
+ omap_dma_filter_fn, &sig, &pdev->dev, "tx");
if (!host->dma_tx)
dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
sig);
- if (mmc_omap2())
- sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
- else
- sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
- host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+ if (res)
+ sig = res->start;
+ host->dma_rx = dma_request_slave_channel_compat(mask,
+ omap_dma_filter_fn, &sig, &pdev->dev, "rx");
if (!host->dma_rx)
dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
sig);
return 0;
}
+#if IS_BUILTIN(CONFIG_OF)
+static const struct of_device_id mmc_omap_match[] = {
+ { .compatible = "ti,omap2420-mmc", },
+ { },
+};
+#endif
+
static struct platform_driver mmc_omap_driver = {
.probe = mmc_omap_probe,
.remove = mmc_omap_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mmc_omap_match),
},
};
if (!miimon) {
pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
pr_warning("Forcing miimon to 100msec\n");
- miimon = 100;
+ miimon = BOND_DEFAULT_MIIMON;
}
}
if (!miimon) {
pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n");
pr_warning("Forcing miimon to 100msec\n");
- miimon = 100;
+ miimon = BOND_DEFAULT_MIIMON;
}
}
return -EPERM;
}
- if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
- pr_err("%s: %s mode is incompatible with arp monitoring.\n",
- bond->dev->name, bond_mode_tbl[mode].modename);
- return -EINVAL;
+ if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
+ pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
+ bond->dev->name, bond_mode_tbl[mode].modename);
+ /* disable arp monitoring */
+ bond->params.arp_interval = 0;
+ /* set miimon to default value */
+ bond->params.miimon = BOND_DEFAULT_MIIMON;
+ pr_info("%s: Setting MII monitoring interval to %d.\n",
+ bond->dev->name, bond->params.miimon);
}
/* don't cache arp_validate between modes */
ret = -EINVAL;
goto out;
}
- if (bond->params.mode == BOND_MODE_ALB ||
- bond->params.mode == BOND_MODE_TLB ||
- bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_NO_USES_ARP(bond->params.mode)) {
pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
bond->dev->name, bond->dev->name);
ret = -EINVAL;
#define BOND_MAX_ARP_TARGETS 16
+#define BOND_DEFAULT_MIIMON 100
+
#define IS_UP(dev) \
((((dev)->flags & IFF_UP) == IFF_UP) && \
netif_running(dev) && \
((mode) == BOND_MODE_TLB) || \
((mode) == BOND_MODE_ALB))
+#define BOND_NO_USES_ARP(mode) \
+ (((mode) == BOND_MODE_8023AD) || \
+ ((mode) == BOND_MODE_TLB) || \
+ ((mode) == BOND_MODE_ALB))
+
#define TX_QUEUE_OVERRIDE(mode) \
(((mode) == BOND_MODE_ACTIVEBACKUP) || \
((mode) == BOND_MODE_ROUNDROBIN))
return 0;
}
-static int c_can_get_berr_counter(const struct net_device *dev,
- struct can_berr_counter *bec)
+static int __c_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
- c_can_pm_runtime_get_sync(priv);
-
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
ERR_CNT_REC_SHIFT;
bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
+ return 0;
+}
+
+static int c_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ c_can_pm_runtime_get_sync(priv);
+ err = __c_can_get_berr_counter(dev, bec);
c_can_pm_runtime_put_sync(priv);
- return 0;
+ return err;
}
/*
if (!(val & (1 << (msg_obj_no - 1)))) {
can_get_echo_skb(dev,
msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
+ c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL);
stats->tx_bytes += priv->read_reg(priv,
C_CAN_IFACE(MSGCTRL_REG, 0))
& IF_MCONT_DLC_MASK;
if (unlikely(!skb))
return 0;
- c_can_get_berr_counter(dev, &bec);
+ __c_can_get_berr_counter(dev, &bec);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
ERR_CNT_RP_SHIFT;
dev_err(&pdev->dev, "no ipg clock defined\n");
return PTR_ERR(clk_ipg);
}
- clock_freq = clk_get_rate(clk_ipg);
clk_per = devm_clk_get(&pdev->dev, "per");
if (IS_ERR(clk_per)) {
dev_err(&pdev->dev, "no per clock defined\n");
return PTR_ERR(clk_per);
}
+ clock_freq = clk_get_rate(clk_per);
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
uint8_t isrc, status;
int n = 0;
- /* Shared interrupts and IRQ off? */
- if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
- return IRQ_NONE;
-
if (priv->pre_irq)
priv->pre_irq(priv);
+ /* Shared interrupts and IRQ off? */
+ if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
+ goto out;
+
while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
(n < SJA1000_MAX_IRQ)) {
- n++;
+
status = priv->read_reg(priv, SJA1000_SR);
/* check for absent controller due to hw unplug */
if (status == 0xFF && sja1000_is_absent(priv))
- return IRQ_NONE;
+ goto out;
if (isrc & IRQ_WUI)
netdev_warn(dev, "wakeup interrupt\n");
status = priv->read_reg(priv, SJA1000_SR);
/* check for absent controller */
if (status == 0xFF && sja1000_is_absent(priv))
- return IRQ_NONE;
+ goto out;
}
}
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
if (sja1000_err(dev, isrc, status))
break;
}
+ n++;
}
-
+out:
if (priv->post_irq)
priv->post_irq(priv);
static ssize_t tg3_show_temp(struct device *dev,
struct device_attribute *devattr, char *buf)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct tg3 *tp = netdev_priv(netdev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct tg3 *tp = dev_get_drvdata(dev);
u32 temperature;
spin_lock_bh(&tp->lock);
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL,
TG3_TEMP_MAX_OFFSET);
-static struct attribute *tg3_attributes[] = {
+static struct attribute *tg3_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
NULL
};
-
-static const struct attribute_group tg3_group = {
- .attrs = tg3_attributes,
-};
+ATTRIBUTE_GROUPS(tg3);
static void tg3_hwmon_close(struct tg3 *tp)
{
if (tp->hwmon_dev) {
hwmon_device_unregister(tp->hwmon_dev);
tp->hwmon_dev = NULL;
- sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
}
}
static void tg3_hwmon_open(struct tg3 *tp)
{
- int i, err;
+ int i;
u32 size = 0;
struct pci_dev *pdev = tp->pdev;
struct tg3_ocir ocirs[TG3_SD_NUM_RECS];
if (!size)
return;
- /* Register hwmon sysfs hooks */
- err = sysfs_create_group(&pdev->dev.kobj, &tg3_group);
- if (err) {
- dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n");
- return;
- }
-
- tp->hwmon_dev = hwmon_device_register(&pdev->dev);
+ tp->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, "tg3",
+ tp, tg3_groups);
if (IS_ERR(tp->hwmon_dev)) {
tp->hwmon_dev = NULL;
dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
- sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
}
}
};
#define be_physfn(adapter) (!adapter->virtfn)
+#define be_virtfn(adapter) (adapter->virtfn)
#define sriov_enabled(adapter) (adapter->num_vfs > 0)
#define sriov_want(adapter) (be_physfn(adapter) && \
(num_vfs || pci_num_vf(adapter->pdev)))
} else {
req->hdr.version = 2;
req->page_size = 1; /* 1 for 4K */
+
+ /* coalesce-wm field in this cmd is not relevant to Lancer.
+ * Lancer uses COMMON_MODIFY_CQ to set this field
+ */
+ if (!lancer_chip(adapter))
+ AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
+ ctxt, coalesce_wm);
AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
no_delay);
AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
be_roce_dev_close(adapter);
- for_all_evt_queues(adapter, eqo, i) {
- if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
+ if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
+ for_all_evt_queues(adapter, eqo, i) {
napi_disable(&eqo->napi);
be_disable_busy_poll(eqo);
}
memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
}
- /* On BE3 VFs this cmd may fail due to lack of privilege.
- * Ignore the failure as in this case pmac_id is fetched
- * in the IFACE_CREATE cmd.
- */
- be_cmd_pmac_add(adapter, mac, adapter->if_handle,
- &adapter->pmac_id[0], 0);
+ /* For BE3-R VFs, the PF programs the initial MAC address */
+ if (!(BEx_chip(adapter) && be_virtfn(adapter)))
+ be_cmd_pmac_add(adapter, mac, adapter->if_handle,
+ &adapter->pmac_id[0], 0);
return 0;
}
if (adapter->wol)
be_setup_wol(adapter, true);
+ be_intr_set(adapter, false);
cancel_delayed_work_sync(&adapter->func_recovery_work);
netif_device_detach(netdev);
if (status)
return status;
+ be_intr_set(adapter, true);
/* tell fw we're ready to fire cmds */
status = be_cmd_fw_init(adapter);
if (status)
#define E1000_MAX_INTR 10
+/*
+ * Count for polling __E1000_RESET condition every 10-20msec.
+ */
+#define E1000_CHECK_RESET_COUNT 50
+
/* TX/RX descriptor defines */
#define E1000_DEFAULT_TXD 256
#define E1000_MAX_TXD 256
struct delayed_work watchdog_task;
struct delayed_work fifo_stall_task;
struct delayed_work phy_info_task;
-
- struct mutex mutex;
};
enum e1000_state_t {
{
set_bit(__E1000_DOWN, &adapter->flags);
- /* Only kill reset task if adapter is not resetting */
- if (!test_bit(__E1000_RESETTING, &adapter->flags))
- cancel_work_sync(&adapter->reset_task);
-
cancel_delayed_work_sync(&adapter->watchdog_task);
+
+ /*
+ * Since the watchdog task can reschedule other tasks, we should cancel
+ * it first, otherwise we can run into the situation when a work is
+ * still running after the adapter has been turned down.
+ */
+
cancel_delayed_work_sync(&adapter->phy_info_task);
cancel_delayed_work_sync(&adapter->fifo_stall_task);
+
+ /* Only kill reset task if adapter is not resetting */
+ if (!test_bit(__E1000_RESETTING, &adapter->flags))
+ cancel_work_sync(&adapter->reset_task);
}
void e1000_down(struct e1000_adapter *adapter)
e1000_clean_all_rx_rings(adapter);
}
-static void e1000_reinit_safe(struct e1000_adapter *adapter)
-{
- while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
- msleep(1);
- mutex_lock(&adapter->mutex);
- e1000_down(adapter);
- e1000_up(adapter);
- mutex_unlock(&adapter->mutex);
- clear_bit(__E1000_RESETTING, &adapter->flags);
-}
-
void e1000_reinit_locked(struct e1000_adapter *adapter)
{
- /* if rtnl_lock is not held the call path is bogus */
- ASSERT_RTNL();
WARN_ON(in_interrupt());
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1);
e1000_irq_disable(adapter);
spin_lock_init(&adapter->stats_lock);
- mutex_init(&adapter->mutex);
set_bit(__E1000_DOWN, &adapter->flags);
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+ usleep_range(10000, 20000);
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
e1000_down(adapter);
struct e1000_adapter *adapter = container_of(work,
struct e1000_adapter,
phy_info_task.work);
- if (test_bit(__E1000_DOWN, &adapter->flags))
- return;
- mutex_lock(&adapter->mutex);
+
e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
- mutex_unlock(&adapter->mutex);
}
/**
struct net_device *netdev = adapter->netdev;
u32 tctl;
- if (test_bit(__E1000_DOWN, &adapter->flags))
- return;
- mutex_lock(&adapter->mutex);
if (atomic_read(&adapter->tx_fifo_stall)) {
if ((er32(TDT) == er32(TDH)) &&
(er32(TDFT) == er32(TDFH)) &&
schedule_delayed_work(&adapter->fifo_stall_task, 1);
}
}
- mutex_unlock(&adapter->mutex);
}
bool e1000_has_link(struct e1000_adapter *adapter)
struct e1000_tx_ring *txdr = adapter->tx_ring;
u32 link, tctl;
- if (test_bit(__E1000_DOWN, &adapter->flags))
- return;
-
- mutex_lock(&adapter->mutex);
link = e1000_has_link(adapter);
if ((netif_carrier_ok(netdev)) && link)
goto link_up;
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
/* exit immediately since reset is imminent */
- goto unlock;
+ return;
}
}
/* Reschedule the task */
if (!test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
-
-unlock:
- mutex_unlock(&adapter->mutex);
}
enum latency_range {
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, reset_task);
- if (test_bit(__E1000_DOWN, &adapter->flags))
- return;
e_err(drv, "Reset adapter\n");
- e1000_reinit_safe(adapter);
+ e1000_reinit_locked(adapter);
}
/**
netif_device_detach(netdev);
if (netif_running(netdev)) {
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+ usleep_range(10000, 20000);
+
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
e1000_down(adapter);
}
{
struct igb_adapter *adapter = netdev_priv(netdev);
- wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC |
- WAKE_PHY;
wol->wolopts = 0;
if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
return;
+ wol->supported = WAKE_UCAST | WAKE_MCAST |
+ WAKE_BCAST | WAKE_MAGIC |
+ WAKE_PHY;
+
/* apply any specific unsupported masks here */
switch (adapter->hw.device_id) {
default:
rx_ring->l2_accel_priv = NULL;
}
-int ixgbe_fwd_ring_down(struct net_device *vdev,
- struct ixgbe_fwd_adapter *accel)
+static int ixgbe_fwd_ring_down(struct net_device *vdev,
+ struct ixgbe_fwd_adapter *accel)
{
struct ixgbe_adapter *adapter = accel->real_adapter;
unsigned int rxbase = accel->rx_base_queue;
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXHASH |
- NETIF_F_RXCSUM |
- NETIF_F_HW_L2FW_DOFFLOAD;
+ NETIF_F_RXCSUM;
- netdev->hw_features = netdev->features;
+ netdev->hw_features = netdev->features | NETIF_F_HW_L2FW_DOFFLOAD;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
+static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
/**
* ixgbe_identify_phy_generic - Get physical layer module
*
* Searches for and identifies the QSFP module and assigns appropriate PHY type
**/
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
{
struct ixgbe_adapter *adapter = hw->back;
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
u16 *list_offset,
u16 *data_offset);
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
- struct mlx4_en_tx_ring *tx_ring;
int i, carrier_ok;
memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST);
carrier_ok = netif_carrier_ok(dev);
netif_carrier_off(dev);
-retry_tx:
/* Wait until all tx queues are empty.
* there should not be any additional incoming traffic
* since we turned the carrier off */
msleep(200);
- for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) {
- tx_ring = priv->tx_ring[i];
- if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb))
- goto retry_tx;
- }
if (priv->mdev->dev->caps.flags &
MLX4_DEV_CAP_FLAG_UC_LOOPBACK) {
le32_to_cpu(txd->opts1) & 0xffff,
PCI_DMA_TODEVICE);
- bytes_compl += skb->len;
- pkts_compl++;
-
if (status & LastFrag) {
if (status & (TxError | TxFIFOUnder)) {
netif_dbg(cp, tx_err, cp->dev,
netif_dbg(cp, tx_done, cp->dev,
"tx done, slot %d\n", tx_tail);
}
+ bytes_compl += skb->len;
+ pkts_compl++;
dev_kfree_skb_irq(skb);
}
rtl_writephy(tp, 0x14, 0x9065);
rtl_writephy(tp, 0x14, 0x1065);
+ /* Check ALDPS bit, disable it if enabled */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ if (rtl_readphy(tp, 0x10) & 0x0004)
+ rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
+
rtl_writephy(tp, 0x1f, 0x0000);
}
unsigned long last_update;
struct device *device;
struct efx_mcdi_mon_attribute *attrs;
+ struct attribute_group group;
+ const struct attribute_group *groups[2];
unsigned int n_attrs;
};
return rc;
}
-static ssize_t efx_mcdi_mon_show_name(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "%s\n", KBUILD_MODNAME);
-}
-
static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
efx_dword_t *entry)
{
- struct efx_nic *efx = dev_get_drvdata(dev);
+ struct efx_nic *efx = dev_get_drvdata(dev->parent);
struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
int rc;
efx_mcdi_sensor_type[mon_attr->type].label);
}
-static int
+static void
efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
ssize_t (*reader)(struct device *,
struct device_attribute *, char *),
{
struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs];
- int rc;
strlcpy(attr->name, name, sizeof(attr->name));
attr->index = index;
attr->dev_attr.attr.name = attr->name;
attr->dev_attr.attr.mode = S_IRUGO;
attr->dev_attr.show = reader;
- rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr);
- if (rc == 0)
- ++hwmon->n_attrs;
- return rc;
+ hwmon->group.attrs[hwmon->n_attrs++] = &attr->dev_attr.attr;
}
int efx_mcdi_mon_probe(struct efx_nic *efx)
efx_mcdi_mon_update(efx);
/* Allocate space for the maximum possible number of
- * attributes for this set of sensors: name of the driver plus
+ * attributes for this set of sensors:
* value, min, max, crit, alarm and label for each sensor.
*/
- n_attrs = 1 + 6 * n_sensors;
+ n_attrs = 6 * n_sensors;
hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL);
if (!hwmon->attrs) {
rc = -ENOMEM;
goto fail;
}
-
- hwmon->device = hwmon_device_register(&efx->pci_dev->dev);
- if (IS_ERR(hwmon->device)) {
- rc = PTR_ERR(hwmon->device);
+ hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *),
+ GFP_KERNEL);
+ if (!hwmon->group.attrs) {
+ rc = -ENOMEM;
goto fail;
}
- rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0);
- if (rc)
- goto fail;
-
for (i = 0, j = -1, type = -1; ; i++) {
enum efx_hwmon_type hwmon_type;
const char *hwmon_prefix;
page = type / 32;
j = -1;
if (page == n_pages)
- return 0;
+ goto hwmon_register;
MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE,
page);
if (min1 != max1) {
snprintf(name, sizeof(name), "%s%u_input",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_value, i, type, 0);
- if (rc)
- goto fail;
if (hwmon_type != EFX_HWMON_POWER) {
snprintf(name, sizeof(name), "%s%u_min",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_limit,
i, type, min1);
- if (rc)
- goto fail;
}
snprintf(name, sizeof(name), "%s%u_max",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_limit,
i, type, max1);
- if (rc)
- goto fail;
if (min2 != max2) {
/* Assume max2 is critical value.
*/
snprintf(name, sizeof(name), "%s%u_crit",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_limit,
i, type, max2);
- if (rc)
- goto fail;
}
}
snprintf(name, sizeof(name), "%s%u_alarm",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_alarm, i, type, 0);
- if (rc)
- goto fail;
if (type < ARRAY_SIZE(efx_mcdi_sensor_type) &&
efx_mcdi_sensor_type[type].label) {
snprintf(name, sizeof(name), "%s%u_label",
hwmon_prefix, hwmon_index);
- rc = efx_mcdi_mon_add_attr(
+ efx_mcdi_mon_add_attr(
efx, name, efx_mcdi_mon_show_label, i, type, 0);
- if (rc)
- goto fail;
}
}
+hwmon_register:
+ hwmon->groups[0] = &hwmon->group;
+ hwmon->device = hwmon_device_register_with_groups(&efx->pci_dev->dev,
+ KBUILD_MODNAME, NULL,
+ hwmon->groups);
+ if (IS_ERR(hwmon->device)) {
+ rc = PTR_ERR(hwmon->device);
+ goto fail;
+ }
+
+ return 0;
+
fail:
efx_mcdi_mon_remove(efx);
return rc;
void efx_mcdi_mon_remove(struct efx_nic *efx)
{
struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
- unsigned int i;
- for (i = 0; i < hwmon->n_attrs; i++)
- device_remove_file(&efx->pci_dev->dev,
- &hwmon->attrs[i].dev_attr);
- kfree(hwmon->attrs);
if (hwmon->device)
hwmon_device_unregister(hwmon->device);
+ kfree(hwmon->attrs);
+ kfree(hwmon->group.attrs);
efx_nic_free_buffer(efx, &hwmon->dma_buf);
}
defined(CONFIG_MACH_LITTLETON) ||\
defined(CONFIG_MACH_ZYLONITE2) ||\
defined(CONFIG_ARCH_VIPER) ||\
- defined(CONFIG_MACH_STARGATE2)
+ defined(CONFIG_MACH_STARGATE2) ||\
+ defined(CONFIG_ARCH_VERSATILE)
#include <asm/mach-types.h>
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
#define SMC_IRQ_FLAGS (-1) /* from resource */
/* We actually can't write halfwords properly if not word aligned */
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
-#elif defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT 1
-#define SMC_CAN_USE_16BIT 1
-#define SMC_CAN_USE_32BIT 1
-#define SMC_NOWAIT 1
-
-#define SMC_inb(a, r) readb((a) + (r))
-#define SMC_inw(a, r) readw((a) + (r))
-#define SMC_inl(a, r) readl((a) + (r))
-#define SMC_outb(v, a, r) writeb(v, (a) + (r))
-#define SMC_outw(v, a, r) writew(v, (a) + (r))
-#define SMC_outl(v, a, r) writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
-#define SMC_IRQ_FLAGS (-1) /* from resource */
-
#elif defined(CONFIG_MN10300)
/*
unsigned int rx_done;
unsigned long flags;
- spin_lock_irqsave(&vptr->lock, flags);
/*
* Do rx and tx twice for performance (taken from the VIA
* out-of-tree driver).
*/
- rx_done = velocity_rx_srv(vptr, budget / 2);
- velocity_tx_srv(vptr);
- rx_done += velocity_rx_srv(vptr, budget - rx_done);
+ rx_done = velocity_rx_srv(vptr, budget);
+ spin_lock_irqsave(&vptr->lock, flags);
velocity_tx_srv(vptr);
-
/* If budget not fully consumed, exit the polling mode */
if (rx_done < budget) {
napi_complete(napi);
if (ret < 0)
goto out_free_tmp_vptr_1;
+ napi_disable(&vptr->napi);
+
spin_lock_irqsave(&vptr->lock, flags);
netif_stop_queue(dev);
velocity_give_many_rx_descs(vptr);
+ napi_enable(&vptr->napi);
+
mac_enable_int(vptr->mac_regs);
netif_start_queue(dev);
rcu_read_lock();
vlan = rcu_dereference(q->vlan);
if (vlan)
- vlan->dev->stats.tx_dropped++;
+ this_cpu_inc(vlan->pcpu_stats->tx_dropped);
rcu_read_unlock();
return err;
const struct sk_buff *skb,
const struct iovec *iv, int len)
{
- struct macvlan_dev *vlan;
int ret;
int vnet_hdr_len = 0;
int vlan_offset = 0;
copied += len;
done:
- rcu_read_lock();
- vlan = rcu_dereference(q->vlan);
- if (vlan) {
- preempt_disable();
- macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
- preempt_enable();
- }
- rcu_read_unlock();
-
return ret ? ret : copied;
}
#define PHY_ID_VSC8234 0x000fc620
#define PHY_ID_VSC8244 0x000fc6c0
+#define PHY_ID_VSC8514 0x00070670
#define PHY_ID_VSC8574 0x000704a0
#define PHY_ID_VSC8662 0x00070660
#define PHY_ID_VSC8221 0x000fc550
err = phy_write(phydev, MII_VSC8244_IMASK,
(phydev->drv->phy_id == PHY_ID_VSC8234 ||
phydev->drv->phy_id == PHY_ID_VSC8244 ||
+ phydev->drv->phy_id == PHY_ID_VSC8514 ||
phydev->drv->phy_id == PHY_ID_VSC8574) ?
MII_VSC8244_IMASK_MASK :
MII_VSC8221_IMASK_MASK);
.ack_interrupt = &vsc824x_ack_interrupt,
.config_intr = &vsc82xx_config_intr,
.driver = { .owner = THIS_MODULE,},
+}, {
+ .phy_id = PHY_ID_VSC8514,
+ .name = "Vitesse VSC8514",
+ .phy_id_mask = 0x000ffff0,
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &vsc824x_config_init,
+ .config_aneg = &vsc82x4_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &vsc824x_ack_interrupt,
+ .config_intr = &vsc82xx_config_intr,
+ .driver = { .owner = THIS_MODULE,},
}, {
.phy_id = PHY_ID_VSC8574,
.name = "Vitesse VSC8574",
static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
{ PHY_ID_VSC8234, 0x000ffff0 },
{ PHY_ID_VSC8244, 0x000fffc0 },
+ { PHY_ID_VSC8514, 0x000ffff0 },
{ PHY_ID_VSC8574, 0x000ffff0 },
{ PHY_ID_VSC8662, 0x000ffff0 },
{ PHY_ID_VSC8221, 0x000ffff0 },
return 0;
}
+static void __team_carrier_check(struct team *team);
+
static int team_user_linkup_option_set(struct team *team,
struct team_gsetter_ctx *ctx)
{
port->user.linkup = ctx->data.bool_val;
team_refresh_port_linkup(port);
+ __team_carrier_check(port->team);
return 0;
}
port->user.linkup_enabled = ctx->data.bool_val;
team_refresh_port_linkup(port);
+ __team_carrier_check(port->team);
return 0;
}
return skb;
}
-static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
+static struct sk_buff *receive_small(void *buf, unsigned int len)
{
- struct skb_vnet_hdr *hdr = skb_vnet_hdr(head_skb);
+ struct sk_buff * skb = buf;
+
+ len -= sizeof(struct virtio_net_hdr);
+ skb_trim(skb, len);
+
+ return skb;
+}
+
+static struct sk_buff *receive_big(struct net_device *dev,
+ struct receive_queue *rq,
+ void *buf,
+ unsigned int len)
+{
+ struct page *page = buf;
+ struct sk_buff *skb = page_to_skb(rq, page, 0, len, PAGE_SIZE);
+
+ if (unlikely(!skb))
+ goto err;
+
+ return skb;
+
+err:
+ dev->stats.rx_dropped++;
+ give_pages(rq, page);
+ return NULL;
+}
+
+static struct sk_buff *receive_mergeable(struct net_device *dev,
+ struct receive_queue *rq,
+ void *buf,
+ unsigned int len)
+{
+ struct skb_vnet_hdr *hdr = buf;
+ int num_buf = hdr->mhdr.num_buffers;
+ struct page *page = virt_to_head_page(buf);
+ int offset = buf - page_address(page);
+ struct sk_buff *head_skb = page_to_skb(rq, page, offset, len,
+ MERGE_BUFFER_LEN);
struct sk_buff *curr_skb = head_skb;
- char *buf;
- struct page *page;
- int num_buf, len, offset;
- num_buf = hdr->mhdr.num_buffers;
+ if (unlikely(!curr_skb))
+ goto err_skb;
+
while (--num_buf) {
- int num_skb_frags = skb_shinfo(curr_skb)->nr_frags;
+ int num_skb_frags;
+
buf = virtqueue_get_buf(rq->vq, &len);
if (unlikely(!buf)) {
- pr_debug("%s: rx error: %d buffers missing\n",
- head_skb->dev->name, hdr->mhdr.num_buffers);
- head_skb->dev->stats.rx_length_errors++;
- return -EINVAL;
+ pr_debug("%s: rx error: %d buffers out of %d missing\n",
+ dev->name, num_buf, hdr->mhdr.num_buffers);
+ dev->stats.rx_length_errors++;
+ goto err_buf;
}
if (unlikely(len > MERGE_BUFFER_LEN)) {
pr_debug("%s: rx error: merge buffer too long\n",
- head_skb->dev->name);
+ dev->name);
len = MERGE_BUFFER_LEN;
}
+
+ page = virt_to_head_page(buf);
+ --rq->num;
+
+ num_skb_frags = skb_shinfo(curr_skb)->nr_frags;
if (unlikely(num_skb_frags == MAX_SKB_FRAGS)) {
struct sk_buff *nskb = alloc_skb(0, GFP_ATOMIC);
- if (unlikely(!nskb)) {
- head_skb->dev->stats.rx_dropped++;
- return -ENOMEM;
- }
+
+ if (unlikely(!nskb))
+ goto err_skb;
if (curr_skb == head_skb)
skb_shinfo(curr_skb)->frag_list = nskb;
else
head_skb->len += len;
head_skb->truesize += MERGE_BUFFER_LEN;
}
- page = virt_to_head_page(buf);
- offset = buf - (char *)page_address(page);
+ offset = buf - page_address(page);
if (skb_can_coalesce(curr_skb, num_skb_frags, page, offset)) {
put_page(page);
skb_coalesce_rx_frag(curr_skb, num_skb_frags - 1,
skb_add_rx_frag(curr_skb, num_skb_frags, page,
offset, len, MERGE_BUFFER_LEN);
}
+ }
+
+ return head_skb;
+
+err_skb:
+ put_page(page);
+ while (--num_buf) {
+ buf = virtqueue_get_buf(rq->vq, &len);
+ if (unlikely(!buf)) {
+ pr_debug("%s: rx error: %d buffers missing\n",
+ dev->name, num_buf);
+ dev->stats.rx_length_errors++;
+ break;
+ }
+ page = virt_to_head_page(buf);
+ put_page(page);
--rq->num;
}
- return 0;
+err_buf:
+ dev->stats.rx_dropped++;
+ dev_kfree_skb(head_skb);
+ return NULL;
}
static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
struct net_device *dev = vi->dev;
struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
struct sk_buff *skb;
- struct page *page;
struct skb_vnet_hdr *hdr;
if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
return;
}
- if (!vi->mergeable_rx_bufs && !vi->big_packets) {
- skb = buf;
- len -= sizeof(struct virtio_net_hdr);
- skb_trim(skb, len);
- } else if (vi->mergeable_rx_bufs) {
- struct page *page = virt_to_head_page(buf);
- skb = page_to_skb(rq, page,
- (char *)buf - (char *)page_address(page),
- len, MERGE_BUFFER_LEN);
- if (unlikely(!skb)) {
- dev->stats.rx_dropped++;
- put_page(page);
- return;
- }
- if (receive_mergeable(rq, skb)) {
- dev_kfree_skb(skb);
- return;
- }
- } else {
- page = buf;
- skb = page_to_skb(rq, page, 0, len, PAGE_SIZE);
- if (unlikely(!skb)) {
- dev->stats.rx_dropped++;
- give_pages(rq, page);
- return;
- }
- }
+ if (vi->mergeable_rx_bufs)
+ skb = receive_mergeable(dev, rq, buf, len);
+ else if (vi->big_packets)
+ skb = receive_big(dev, rq, buf, len);
+ else
+ skb = receive_small(buf, len);
+
+ if (unlikely(!skb))
+ return;
hdr = skb_vnet_hdr(skb);
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
VIRTIO_NET_CTRL_MAC_TABLE_SET,
sg, NULL))
- dev_warn(&dev->dev, "Failed to set MAC fitler table.\n");
+ dev_warn(&dev->dev, "Failed to set MAC filter table.\n");
kfree(buf);
}
#include <linux/udp.h>
#include <net/tcp.h>
+#include <net/ip6_checksum.h>
#include <xen/xen.h>
#include <xen/events.h>
ndev->event_cb = NULL;
}
+static void ntb_irq_work(unsigned long data)
+{
+ struct ntb_db_cb *db_cb = (struct ntb_db_cb *)data;
+ int rc;
+
+ rc = db_cb->callback(db_cb->data, db_cb->db_num);
+ if (rc)
+ tasklet_schedule(&db_cb->irq_work);
+ else {
+ struct ntb_device *ndev = db_cb->ndev;
+ unsigned long mask;
+
+ mask = readw(ndev->reg_ofs.ldb_mask);
+ clear_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+ writew(mask, ndev->reg_ofs.ldb_mask);
+ }
+}
+
/**
* ntb_register_db_callback() - register a callback for doorbell interrupt
* @ndev: pointer to ntb_device instance
* RETURNS: An appropriate -ERRNO error value on error, or zero for success.
*/
int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
- void *data, void (*func)(void *data, int db_num))
+ void *data, int (*func)(void *data, int db_num))
{
unsigned long mask;
ndev->db_cb[idx].callback = func;
ndev->db_cb[idx].data = data;
+ ndev->db_cb[idx].ndev = ndev;
+
+ tasklet_init(&ndev->db_cb[idx].irq_work, ntb_irq_work,
+ (unsigned long) &ndev->db_cb[idx]);
/* unmask interrupt */
mask = readw(ndev->reg_ofs.ldb_mask);
set_bit(idx * ndev->bits_per_vector, &mask);
writew(mask, ndev->reg_ofs.ldb_mask);
+ tasklet_disable(&ndev->db_cb[idx].irq_work);
+
ndev->db_cb[idx].callback = NULL;
}
return -EINVAL;
ndev->limits.max_mw = SNB_ERRATA_MAX_MW;
+ ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->reg_ofs.spad_write = ndev->mw[1].vbase +
SNB_SPAD_OFFSET;
ndev->reg_ofs.rdb = ndev->mw[1].vbase +
*/
writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base +
SNB_PBAR4LMT_OFFSET);
+ /* HW errata on the Limit registers. They can only be
+ * written when the base register is 4GB aligned and
+ * < 32bit. This should already be the case based on the
+ * driver defaults, but write the Limit registers first
+ * just in case.
+ */
} else {
ndev->limits.max_mw = SNB_MAX_MW;
+
+ /* HW Errata on bit 14 of b2bdoorbell register. Writes
+ * will not be mirrored to the remote system. Shrink
+ * the number of bits by one, since bit 14 is the last
+ * bit.
+ */
+ ndev->limits.max_db_bits = SNB_MAX_DB_BITS - 1;
ndev->reg_ofs.spad_write = ndev->reg_base +
SNB_B2B_SPAD_OFFSET;
ndev->reg_ofs.rdb = ndev->reg_base +
* something silly
*/
writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET);
+ /* HW errata on the Limit registers. They can only be
+ * written when the base register is 4GB aligned and
+ * < 32bit. This should already be the case based on the
+ * driver defaults, but write the Limit registers first
+ * just in case.
+ */
}
/* The Xeon errata workaround requires setting SBAR Base
* have an equal amount.
*/
ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
+ ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
/* Note: The SDOORBELL is the cause of the errata. You REALLY
* don't want to touch it.
*/
* have an equal amount.
*/
ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
+ ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET;
ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET;
ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET;
ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET;
- ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->limits.msix_cnt = SNB_MSIX_CNT;
ndev->bits_per_vector = SNB_DB_BITS_PER_VEC;
{
struct ntb_db_cb *db_cb = data;
struct ntb_device *ndev = db_cb->ndev;
+ unsigned long mask;
dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
db_cb->db_num);
- if (db_cb->callback)
- db_cb->callback(db_cb->data, db_cb->db_num);
+ mask = readw(ndev->reg_ofs.ldb_mask);
+ set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+ writew(mask, ndev->reg_ofs.ldb_mask);
+
+ tasklet_schedule(&db_cb->irq_work);
/* No need to check for the specific HB irq, any interrupt means
* we're connected.
{
struct ntb_db_cb *db_cb = data;
struct ntb_device *ndev = db_cb->ndev;
+ unsigned long mask;
dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
db_cb->db_num);
- if (db_cb->callback)
- db_cb->callback(db_cb->data, db_cb->db_num);
+ mask = readw(ndev->reg_ofs.ldb_mask);
+ set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+ writew(mask, ndev->reg_ofs.ldb_mask);
+
+ tasklet_schedule(&db_cb->irq_work);
/* On Sandybridge, there are 16 bits in the interrupt register
* but only 4 vectors. So, 5 bits are assigned to the first 3
dev_err(&ndev->pdev->dev, "Error determining link status\n");
/* bit 15 is always the link bit */
- writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.ldb);
+ writew(1 << SNB_LINK_DB, ndev->reg_ofs.ldb);
return IRQ_HANDLED;
}
"Only %d MSI-X vectors. Limiting the number of queues to that number.\n",
rc);
msix_entries = rc;
+
+ rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries);
+ if (rc)
+ goto err1;
}
for (i = 0; i < msix_entries; i++) {
*/
if (ndev->hw_type == BWD_HW)
writeq(~0, ndev->reg_ofs.ldb_mask);
- else
- writew(~(1 << ndev->limits.max_db_bits),
- ndev->reg_ofs.ldb_mask);
+ else {
+ u16 var = 1 << SNB_LINK_DB;
+ writew(~var, ndev->reg_ofs.ldb_mask);
+ }
rc = ntb_setup_msix(ndev);
if (!rc)
}
}
+static void ntb_hw_link_up(struct ntb_device *ndev)
+{
+ if (ndev->conn_type == NTB_CONN_TRANSPARENT)
+ ntb_link_event(ndev, NTB_LINK_UP);
+ else {
+ u32 ntb_cntl;
+
+ /* Let's bring the NTB link up */
+ ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
+ ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK);
+ ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP;
+ ntb_cntl |= NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP;
+ writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+ }
+}
+
+static void ntb_hw_link_down(struct ntb_device *ndev)
+{
+ u32 ntb_cntl;
+
+ if (ndev->conn_type == NTB_CONN_TRANSPARENT) {
+ ntb_link_event(ndev, NTB_LINK_DOWN);
+ return;
+ }
+
+ /* Bring NTB link down */
+ ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
+ ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP);
+ ntb_cntl &= ~(NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP);
+ ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK;
+ writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+}
+
static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct ntb_device *ndev;
if (rc)
goto err6;
- /* Let's bring the NTB link up */
- writel(NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP,
- ndev->reg_ofs.lnk_cntl);
+ ntb_hw_link_up(ndev);
return 0;
{
struct ntb_device *ndev = pci_get_drvdata(pdev);
int i;
- u32 ntb_cntl;
- /* Bring NTB link down */
- ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
- ntb_cntl |= NTB_CNTL_LINK_DISABLE;
- writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+ ntb_hw_link_down(ndev);
ntb_transport_free(ndev->ntb_transport);
};
struct ntb_db_cb {
- void (*callback) (void *data, int db_num);
+ int (*callback)(void *data, int db_num);
unsigned int db_num;
void *data;
struct ntb_device *ndev;
+ struct tasklet_struct irq_work;
};
struct ntb_device {
void ntb_unregister_transport(struct ntb_device *ndev);
void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr);
int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
- void *data, void (*db_cb_func) (void *data,
- int db_num));
+ void *data, int (*db_cb_func)(void *data,
+ int db_num));
void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx);
int ntb_register_event_callback(struct ntb_device *ndev,
void (*event_cb_func) (void *handle,
#define SNB_MAX_COMPAT_SPADS 16
/* Reserve the uppermost bit for link interrupt */
#define SNB_MAX_DB_BITS 15
+#define SNB_LINK_DB 15
#define SNB_DB_BITS_PER_VEC 5
#define SNB_MAX_MW 2
#define SNB_ERRATA_MAX_MW 1
#define SNB_SBAR2XLAT_OFFSET 0x0030
#define SNB_SBAR4XLAT_OFFSET 0x0038
#define SNB_SBAR0BASE_OFFSET 0x0040
-#define SNB_SBAR0BASE_OFFSET 0x0040
-#define SNB_SBAR2BASE_OFFSET 0x0048
-#define SNB_SBAR4BASE_OFFSET 0x0050
#define SNB_SBAR2BASE_OFFSET 0x0048
#define SNB_SBAR4BASE_OFFSET 0x0050
#define SNB_NTBCNTL_OFFSET 0x0058
#define BWD_LTSSMSTATEJMP_FORCEDETECT (1 << 2)
#define BWD_IBIST_ERR_OFLOW 0x7FFF7FFF
-#define NTB_CNTL_CFG_LOCK (1 << 0)
-#define NTB_CNTL_LINK_DISABLE (1 << 1)
-#define NTB_CNTL_BAR23_SNOOP (1 << 2)
-#define NTB_CNTL_BAR45_SNOOP (1 << 6)
-#define BWD_CNTL_LINK_DOWN (1 << 16)
+#define NTB_CNTL_CFG_LOCK (1 << 0)
+#define NTB_CNTL_LINK_DISABLE (1 << 1)
+#define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2)
+#define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4)
+#define NTB_CNTL_S2P_BAR45_SNOOP (1 << 6)
+#define NTB_CNTL_P2S_BAR45_SNOOP (1 << 8)
+#define BWD_CNTL_LINK_DOWN (1 << 16)
#define NTB_PPD_OFFSET 0x00D4
#define SNB_PPD_CONN_TYPE 0x0003
void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data,
void *data, int len);
- struct tasklet_struct rx_work;
struct list_head rx_pend_q;
struct list_head rx_free_q;
spinlock_t ntb_rx_pend_q_lock;
return 0;
}
-static void ntb_qp_link_cleanup(struct work_struct *work)
+static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
{
- struct ntb_transport_qp *qp = container_of(work,
- struct ntb_transport_qp,
- link_cleanup);
struct ntb_transport *nt = qp->transport;
struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
dev_info(&pdev->dev, "qp %d: Link Down\n", qp->qp_num);
qp->qp_link = NTB_LINK_DOWN;
+}
+
+static void ntb_qp_link_cleanup_work(struct work_struct *work)
+{
+ struct ntb_transport_qp *qp = container_of(work,
+ struct ntb_transport_qp,
+ link_cleanup);
+ struct ntb_transport *nt = qp->transport;
+
+ ntb_qp_link_cleanup(qp);
if (nt->transport_link == NTB_LINK_UP)
schedule_delayed_work(&qp->link_work,
schedule_work(&qp->link_cleanup);
}
-static void ntb_transport_link_cleanup(struct work_struct *work)
+static void ntb_transport_link_cleanup(struct ntb_transport *nt)
{
- struct ntb_transport *nt = container_of(work, struct ntb_transport,
- link_cleanup);
int i;
+ /* Pass along the info to any clients */
+ for (i = 0; i < nt->max_qps; i++)
+ if (!test_bit(i, &nt->qp_bitmap))
+ ntb_qp_link_cleanup(&nt->qps[i]);
+
if (nt->transport_link == NTB_LINK_DOWN)
cancel_delayed_work_sync(&nt->link_work);
else
nt->transport_link = NTB_LINK_DOWN;
- /* Pass along the info to any clients */
- for (i = 0; i < nt->max_qps; i++)
- if (!test_bit(i, &nt->qp_bitmap))
- ntb_qp_link_down(&nt->qps[i]);
-
/* The scratchpad registers keep the values if the remote side
* goes down, blast them now to give them a sane value the next
* time they are accessed
ntb_write_local_spad(nt->ndev, i, 0);
}
+static void ntb_transport_link_cleanup_work(struct work_struct *work)
+{
+ struct ntb_transport *nt = container_of(work, struct ntb_transport,
+ link_cleanup);
+
+ ntb_transport_link_cleanup(nt);
+}
+
static void ntb_transport_event_callback(void *data, enum ntb_hw_event event)
{
struct ntb_transport *nt = data;
}
INIT_DELAYED_WORK(&qp->link_work, ntb_qp_link_work);
- INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup);
+ INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup_work);
spin_lock_init(&qp->ntb_rx_pend_q_lock);
spin_lock_init(&qp->ntb_rx_free_q_lock);
}
INIT_DELAYED_WORK(&nt->link_work, ntb_transport_link_work);
- INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup);
+ INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup_work);
rc = ntb_register_event_callback(nt->ndev,
ntb_transport_event_callback);
struct ntb_device *ndev = nt->ndev;
int i;
- nt->transport_link = NTB_LINK_DOWN;
+ ntb_transport_link_cleanup(nt);
/* verify that all the qp's are freed */
for (i = 0; i < nt->max_qps; i++) {
goto out;
}
-static void ntb_transport_rx(unsigned long data)
+static int ntb_transport_rxc_db(void *data, int db_num)
{
- struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data;
+ struct ntb_transport_qp *qp = data;
int rc, i;
+ dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
+ __func__, db_num);
+
/* Limit the number of packets processed in a single interrupt to
* provide fairness to others
*/
if (qp->dma_chan)
dma_async_issue_pending(qp->dma_chan);
-}
-
-static void ntb_transport_rxc_db(void *data, int db_num)
-{
- struct ntb_transport_qp *qp = data;
-
- dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
- __func__, db_num);
- tasklet_schedule(&qp->rx_work);
+ return i;
}
static void ntb_tx_copy_callback(void *data)
qp->tx_handler = handlers->tx_handler;
qp->event_handler = handlers->event_handler;
+ dmaengine_get();
qp->dma_chan = dma_find_channel(DMA_MEMCPY);
- if (!qp->dma_chan)
+ if (!qp->dma_chan) {
+ dmaengine_put();
dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n");
- else
- dmaengine_get();
+ }
for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
entry = kzalloc(sizeof(struct ntb_queue_entry), GFP_ATOMIC);
&qp->tx_free_q);
}
- tasklet_init(&qp->rx_work, ntb_transport_rx, (unsigned long) qp);
-
rc = ntb_register_db_callback(qp->ndev, free_queue, qp,
ntb_transport_rxc_db);
if (rc)
- goto err3;
+ goto err2;
dev_info(&pdev->dev, "NTB Transport QP %d created\n", qp->qp_num);
return qp;
-err3:
- tasklet_disable(&qp->rx_work);
err2:
while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
kfree(entry);
err1:
while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
kfree(entry);
+ if (qp->dma_chan)
+ dmaengine_put();
set_bit(free_queue, &nt->qp_bitmap);
err:
return NULL;
}
ntb_unregister_db_callback(qp->ndev, qp->qp_num);
- tasklet_disable(&qp->rx_work);
cancel_delayed_work_sync(&qp->link_work);
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#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>
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;
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);
/* 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);
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);
}
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) {
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);
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);
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);
*
* Init/reset quirks for USB host controllers should be in the
* USB quirks file, where their drivers can access reuse it.
- *
- * The bridge optimization stuff has been removed. If you really
- * have a silly BIOS which is unable to set your host bridge right,
- * use the PowerTweak utility (see http://powertweak.sourceforge.net).
*/
#include <linux/types.h>
config PINCTRL_IMX27
bool "IMX27 pinctrl driver"
- depends on OF
depends on SOC_IMX27
select PINCTRL_IMX1_CORE
help
Say Y here to enable the imx27 pinctrl driver
+
+config PINCTRL_IMX25
+ bool "IMX25 pinctrl driver"
+ depends on OF
+ depends on SOC_IMX25
+ select PINCTRL_IMX
+ help
+ Say Y here to enable the imx25 pinctrl driver
+
config PINCTRL_IMX35
bool "IMX35 pinctrl driver"
- depends on OF
depends on SOC_IMX35
select PINCTRL_IMX
help
config PINCTRL_IMX50
bool "IMX50 pinctrl driver"
- depends on OF
depends on SOC_IMX50
select PINCTRL_IMX
help
config PINCTRL_IMX51
bool "IMX51 pinctrl driver"
- depends on OF
depends on SOC_IMX51
select PINCTRL_IMX
help
config PINCTRL_IMX53
bool "IMX53 pinctrl driver"
- depends on OF
depends on SOC_IMX53
select PINCTRL_IMX
help
config PINCTRL_IMX6Q
bool "IMX6Q/DL pinctrl driver"
- depends on OF
depends on SOC_IMX6Q
select PINCTRL_IMX
help
config PINCTRL_IMX6SL
bool "IMX6SL pinctrl driver"
- depends on OF
depends on SOC_IMX6SL
select PINCTRL_IMX
help
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
- depends on OF
depends on SOC_VF610
select PINCTRL_IMX
help
bool
select PINCTRL_MXS
+config PINCTRL_MSM
+ bool
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
+
+config PINCTRL_MSM8X74
+ bool "Qualcomm 8x74 pin controller driver"
+ depends on OF && OF_IRQ
+ select PINCTRL_MSM
+
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on ARCH_U8500 || ARCH_NOMADIK
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
+obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
+obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
+obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
{
const struct pinconf_ops *ops = pctldev->desc->confops;
- /* We must be able to read out pin status */
- if (!ops->pin_config_get && !ops->pin_config_group_get) {
- dev_err(pctldev->dev,
- "pinconf must be able to read out pin status\n");
- return -EINVAL;
- }
/* We have to be able to config the pins in SOME way */
if (!ops->pin_config_set && !ops->pin_config_group_set) {
dev_err(pctldev->dev,
const struct pinconf_ops *ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_get) {
- dev_err(pctldev->dev, "cannot get pin configuration, missing "
+ dev_dbg(pctldev->dev, "cannot get pin configuration, missing "
"pin_config_get() function in driver\n");
- return -EINVAL;
+ return -ENOTSUPP;
}
return ops->pin_config_get(pctldev, pin, config);
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
- dev_err(pctldev->dev, "cannot get configuration for pin "
+ dev_dbg(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
- ret = -EINVAL;
+ ret = -ENOTSUPP;
goto unlock;
}
const struct pinconf_ops *ops = pctldev->desc->confops;
unsigned i, pin;
- if (!ops || !ops->pin_config_get)
- return 0;
-
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): configs\n");
unsigned ngroups = pctlops->get_groups_count(pctldev);
unsigned selector = 0;
- if (!ops || !ops->pin_config_group_get)
- return 0;
-
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): configs\n");
ret = abx500_gpio_set_bits(chip,
AB8500_GPIO_ALTFUN_REG,
af.alt_bit1,
- !!(af.alta_val && BIT(0)));
+ !!(af.alta_val & BIT(0)));
if (ret < 0)
goto out;
goto out;
ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
- af.alt_bit1, !!(af.altb_val && BIT(0)));
+ af.alt_bit1, !!(af.altb_val & BIT(0)));
if (ret < 0)
goto out;
goto out;
ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
- af.alt_bit2, !!(af.altc_val && BIT(1)));
+ af.alt_bit2, !!(af.altc_val & BIT(1)));
break;
default:
-#ifndef PINCTRL_PINCTRL_ABx5O0_H
+#ifndef PINCTRL_PINCTRL_ABx500_H
#define PINCTRL_PINCTRL_ABx500_H
/* Package definitions */
};
/**
- * struct at91_pinctrl_mux_ops - describes an At91 mux ops group
+ * struct at91_pinctrl_mux_ops - describes an AT91 mux ops group
* on new IP with support for periph C and D the way to mux in
* periph A and B has changed
* So provide the right call back
unsigned pin;
int div;
- dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config);
+ *config = 0;
+ dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
pio = pin_to_controller(info, pin_to_bank(pin_id));
pin = pin_id % MAX_NB_GPIO_PER_BANK;
chained_irq_enter(chip, desc);
for (;;) {
/* Reading ISR acks pending (edge triggered) GPIO interrupts.
- * When there none are pending, we're finished unless we need
+ * When there are none pending, we're finished unless we need
* to process multiple banks (like ID_PIOCDE on sam9263).
*/
isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR);
prev = gpio_chips[at91_gpio->pioc_idx - 1];
/* The top level handler handles one bank of GPIOs, except
- * on some SoC it can handles up to three...
+ * on some SoC it can handle up to three...
* We only set up the handler for the first of the list.
*/
if (prev && prev->next == at91_gpio)
spin_lock_irqsave(&vg->lock, flags);
for (i = 0; i < vg->chip.ngpio; i++) {
+ const char *label;
offs = vg->range->pins[i] * 16;
conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
val = readl(vg->reg_base + offs + BYT_VAL_REG);
+ label = gpiochip_is_requested(chip, i);
+ if (!label)
+ label = "Unrequested";
+
seq_printf(s,
- " gpio-%-3d %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
+ " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
i,
+ label,
val & BYT_INPUT_EN ? " " : "in",
val & BYT_OUTPUT_EN ? " " : "out",
val & BYT_LEVEL ? "hi" : "lo",
{
}
+static unsigned int byt_irq_startup(struct irq_data *d)
+{
+ struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+
+ if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d)))
+ dev_err(vg->chip.dev,
+ "unable to lock HW IRQ %lu for IRQ\n",
+ irqd_to_hwirq(d));
+ byt_irq_unmask(d);
+ return 0;
+}
+
+static void byt_irq_shutdown(struct irq_data *d)
+{
+ struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+
+ byt_irq_mask(d);
+ gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
+}
+
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
+ .irq_startup = byt_irq_startup,
+ .irq_shutdown = byt_irq_shutdown,
};
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
return -EINVAL;
}
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret) {
+ pinctrl_unregister(ipctl->pctl);
+ dev_err(&pdev->dev, "Failed to populate subdevices\n");
+ return ret;
+ }
+
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
return 0;
--- /dev/null
+/*
+ * imx25 pinctrl driver.
+ *
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * This driver was mostly copied from the imx51 pinctrl driver which has:
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro, Inc.
+ *
+ * Author: Denis Carikli <denis@eukrea.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx25_pads {
+ MX25_PAD_RESERVE0 = 1,
+ MX25_PAD_RESERVE1 = 2,
+ MX25_PAD_A10 = 3,
+ MX25_PAD_A13 = 4,
+ MX25_PAD_A14 = 5,
+ MX25_PAD_A15 = 6,
+ MX25_PAD_A16 = 7,
+ MX25_PAD_A17 = 8,
+ MX25_PAD_A18 = 9,
+ MX25_PAD_A19 = 10,
+ MX25_PAD_A20 = 11,
+ MX25_PAD_A21 = 12,
+ MX25_PAD_A22 = 13,
+ MX25_PAD_A23 = 14,
+ MX25_PAD_A24 = 15,
+ MX25_PAD_A25 = 16,
+ MX25_PAD_EB0 = 17,
+ MX25_PAD_EB1 = 18,
+ MX25_PAD_OE = 19,
+ MX25_PAD_CS0 = 20,
+ MX25_PAD_CS1 = 21,
+ MX25_PAD_CS4 = 22,
+ MX25_PAD_CS5 = 23,
+ MX25_PAD_NF_CE0 = 24,
+ MX25_PAD_ECB = 25,
+ MX25_PAD_LBA = 26,
+ MX25_PAD_BCLK = 27,
+ MX25_PAD_RW = 28,
+ MX25_PAD_NFWE_B = 29,
+ MX25_PAD_NFRE_B = 30,
+ MX25_PAD_NFALE = 31,
+ MX25_PAD_NFCLE = 32,
+ MX25_PAD_NFWP_B = 33,
+ MX25_PAD_NFRB = 34,
+ MX25_PAD_D15 = 35,
+ MX25_PAD_D14 = 36,
+ MX25_PAD_D13 = 37,
+ MX25_PAD_D12 = 38,
+ MX25_PAD_D11 = 39,
+ MX25_PAD_D10 = 40,
+ MX25_PAD_D9 = 41,
+ MX25_PAD_D8 = 42,
+ MX25_PAD_D7 = 43,
+ MX25_PAD_D6 = 44,
+ MX25_PAD_D5 = 45,
+ MX25_PAD_D4 = 46,
+ MX25_PAD_D3 = 47,
+ MX25_PAD_D2 = 48,
+ MX25_PAD_D1 = 49,
+ MX25_PAD_D0 = 50,
+ MX25_PAD_LD0 = 51,
+ MX25_PAD_LD1 = 52,
+ MX25_PAD_LD2 = 53,
+ MX25_PAD_LD3 = 54,
+ MX25_PAD_LD4 = 55,
+ MX25_PAD_LD5 = 56,
+ MX25_PAD_LD6 = 57,
+ MX25_PAD_LD7 = 58,
+ MX25_PAD_LD8 = 59,
+ MX25_PAD_LD9 = 60,
+ MX25_PAD_LD10 = 61,
+ MX25_PAD_LD11 = 62,
+ MX25_PAD_LD12 = 63,
+ MX25_PAD_LD13 = 64,
+ MX25_PAD_LD14 = 65,
+ MX25_PAD_LD15 = 66,
+ MX25_PAD_HSYNC = 67,
+ MX25_PAD_VSYNC = 68,
+ MX25_PAD_LSCLK = 69,
+ MX25_PAD_OE_ACD = 70,
+ MX25_PAD_CONTRAST = 71,
+ MX25_PAD_PWM = 72,
+ MX25_PAD_CSI_D2 = 73,
+ MX25_PAD_CSI_D3 = 74,
+ MX25_PAD_CSI_D4 = 75,
+ MX25_PAD_CSI_D5 = 76,
+ MX25_PAD_CSI_D6 = 77,
+ MX25_PAD_CSI_D7 = 78,
+ MX25_PAD_CSI_D8 = 79,
+ MX25_PAD_CSI_D9 = 80,
+ MX25_PAD_CSI_MCLK = 81,
+ MX25_PAD_CSI_VSYNC = 82,
+ MX25_PAD_CSI_HSYNC = 83,
+ MX25_PAD_CSI_PIXCLK = 84,
+ MX25_PAD_I2C1_CLK = 85,
+ MX25_PAD_I2C1_DAT = 86,
+ MX25_PAD_CSPI1_MOSI = 87,
+ MX25_PAD_CSPI1_MISO = 88,
+ MX25_PAD_CSPI1_SS0 = 89,
+ MX25_PAD_CSPI1_SS1 = 90,
+ MX25_PAD_CSPI1_SCLK = 91,
+ MX25_PAD_CSPI1_RDY = 92,
+ MX25_PAD_UART1_RXD = 93,
+ MX25_PAD_UART1_TXD = 94,
+ MX25_PAD_UART1_RTS = 95,
+ MX25_PAD_UART1_CTS = 96,
+ MX25_PAD_UART2_RXD = 97,
+ MX25_PAD_UART2_TXD = 98,
+ MX25_PAD_UART2_RTS = 99,
+ MX25_PAD_UART2_CTS = 100,
+ MX25_PAD_SD1_CMD = 101,
+ MX25_PAD_SD1_CLK = 102,
+ MX25_PAD_SD1_DATA0 = 103,
+ MX25_PAD_SD1_DATA1 = 104,
+ MX25_PAD_SD1_DATA2 = 105,
+ MX25_PAD_SD1_DATA3 = 106,
+ MX25_PAD_KPP_ROW0 = 107,
+ MX25_PAD_KPP_ROW1 = 108,
+ MX25_PAD_KPP_ROW2 = 109,
+ MX25_PAD_KPP_ROW3 = 110,
+ MX25_PAD_KPP_COL0 = 111,
+ MX25_PAD_KPP_COL1 = 112,
+ MX25_PAD_KPP_COL2 = 113,
+ MX25_PAD_KPP_COL3 = 114,
+ MX25_PAD_FEC_MDC = 115,
+ MX25_PAD_FEC_MDIO = 116,
+ MX25_PAD_FEC_TDATA0 = 117,
+ MX25_PAD_FEC_TDATA1 = 118,
+ MX25_PAD_FEC_TX_EN = 119,
+ MX25_PAD_FEC_RDATA0 = 120,
+ MX25_PAD_FEC_RDATA1 = 121,
+ MX25_PAD_FEC_RX_DV = 122,
+ MX25_PAD_FEC_TX_CLK = 123,
+ MX25_PAD_RTCK = 124,
+ MX25_PAD_DE_B = 125,
+ MX25_PAD_GPIO_A = 126,
+ MX25_PAD_GPIO_B = 127,
+ MX25_PAD_GPIO_C = 128,
+ MX25_PAD_GPIO_D = 129,
+ MX25_PAD_GPIO_E = 130,
+ MX25_PAD_GPIO_F = 131,
+ MX25_PAD_EXT_ARMCLK = 132,
+ MX25_PAD_UPLL_BYPCLK = 133,
+ MX25_PAD_VSTBY_REQ = 134,
+ MX25_PAD_VSTBY_ACK = 135,
+ MX25_PAD_POWER_FAIL = 136,
+ MX25_PAD_CLKO = 137,
+ MX25_PAD_BOOT_MODE0 = 138,
+ MX25_PAD_BOOT_MODE1 = 139,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX25_PAD_RESERVE0),
+ IMX_PINCTRL_PIN(MX25_PAD_RESERVE1),
+ IMX_PINCTRL_PIN(MX25_PAD_A10),
+ IMX_PINCTRL_PIN(MX25_PAD_A13),
+ IMX_PINCTRL_PIN(MX25_PAD_A14),
+ IMX_PINCTRL_PIN(MX25_PAD_A15),
+ IMX_PINCTRL_PIN(MX25_PAD_A16),
+ IMX_PINCTRL_PIN(MX25_PAD_A17),
+ IMX_PINCTRL_PIN(MX25_PAD_A18),
+ IMX_PINCTRL_PIN(MX25_PAD_A19),
+ IMX_PINCTRL_PIN(MX25_PAD_A20),
+ IMX_PINCTRL_PIN(MX25_PAD_A21),
+ IMX_PINCTRL_PIN(MX25_PAD_A22),
+ IMX_PINCTRL_PIN(MX25_PAD_A23),
+ IMX_PINCTRL_PIN(MX25_PAD_A24),
+ IMX_PINCTRL_PIN(MX25_PAD_A25),
+ IMX_PINCTRL_PIN(MX25_PAD_EB0),
+ IMX_PINCTRL_PIN(MX25_PAD_EB1),
+ IMX_PINCTRL_PIN(MX25_PAD_OE),
+ IMX_PINCTRL_PIN(MX25_PAD_CS0),
+ IMX_PINCTRL_PIN(MX25_PAD_CS1),
+ IMX_PINCTRL_PIN(MX25_PAD_CS4),
+ IMX_PINCTRL_PIN(MX25_PAD_CS5),
+ IMX_PINCTRL_PIN(MX25_PAD_NF_CE0),
+ IMX_PINCTRL_PIN(MX25_PAD_ECB),
+ IMX_PINCTRL_PIN(MX25_PAD_LBA),
+ IMX_PINCTRL_PIN(MX25_PAD_BCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_RW),
+ IMX_PINCTRL_PIN(MX25_PAD_NFWE_B),
+ IMX_PINCTRL_PIN(MX25_PAD_NFRE_B),
+ IMX_PINCTRL_PIN(MX25_PAD_NFALE),
+ IMX_PINCTRL_PIN(MX25_PAD_NFCLE),
+ IMX_PINCTRL_PIN(MX25_PAD_NFWP_B),
+ IMX_PINCTRL_PIN(MX25_PAD_NFRB),
+ IMX_PINCTRL_PIN(MX25_PAD_D15),
+ IMX_PINCTRL_PIN(MX25_PAD_D14),
+ IMX_PINCTRL_PIN(MX25_PAD_D13),
+ IMX_PINCTRL_PIN(MX25_PAD_D12),
+ IMX_PINCTRL_PIN(MX25_PAD_D11),
+ IMX_PINCTRL_PIN(MX25_PAD_D10),
+ IMX_PINCTRL_PIN(MX25_PAD_D9),
+ IMX_PINCTRL_PIN(MX25_PAD_D8),
+ IMX_PINCTRL_PIN(MX25_PAD_D7),
+ IMX_PINCTRL_PIN(MX25_PAD_D6),
+ IMX_PINCTRL_PIN(MX25_PAD_D5),
+ IMX_PINCTRL_PIN(MX25_PAD_D4),
+ IMX_PINCTRL_PIN(MX25_PAD_D3),
+ IMX_PINCTRL_PIN(MX25_PAD_D2),
+ IMX_PINCTRL_PIN(MX25_PAD_D1),
+ IMX_PINCTRL_PIN(MX25_PAD_D0),
+ IMX_PINCTRL_PIN(MX25_PAD_LD0),
+ IMX_PINCTRL_PIN(MX25_PAD_LD1),
+ IMX_PINCTRL_PIN(MX25_PAD_LD2),
+ IMX_PINCTRL_PIN(MX25_PAD_LD3),
+ IMX_PINCTRL_PIN(MX25_PAD_LD4),
+ IMX_PINCTRL_PIN(MX25_PAD_LD5),
+ IMX_PINCTRL_PIN(MX25_PAD_LD6),
+ IMX_PINCTRL_PIN(MX25_PAD_LD7),
+ IMX_PINCTRL_PIN(MX25_PAD_LD8),
+ IMX_PINCTRL_PIN(MX25_PAD_LD9),
+ IMX_PINCTRL_PIN(MX25_PAD_LD10),
+ IMX_PINCTRL_PIN(MX25_PAD_LD11),
+ IMX_PINCTRL_PIN(MX25_PAD_LD12),
+ IMX_PINCTRL_PIN(MX25_PAD_LD13),
+ IMX_PINCTRL_PIN(MX25_PAD_LD14),
+ IMX_PINCTRL_PIN(MX25_PAD_LD15),
+ IMX_PINCTRL_PIN(MX25_PAD_HSYNC),
+ IMX_PINCTRL_PIN(MX25_PAD_VSYNC),
+ IMX_PINCTRL_PIN(MX25_PAD_LSCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_OE_ACD),
+ IMX_PINCTRL_PIN(MX25_PAD_CONTRAST),
+ IMX_PINCTRL_PIN(MX25_PAD_PWM),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D2),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D3),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D4),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D5),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D6),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D7),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D8),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_D9),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_MCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_VSYNC),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_HSYNC),
+ IMX_PINCTRL_PIN(MX25_PAD_CSI_PIXCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_I2C1_CLK),
+ IMX_PINCTRL_PIN(MX25_PAD_I2C1_DAT),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_MOSI),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_MISO),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SS0),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SS1),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_CSPI1_RDY),
+ IMX_PINCTRL_PIN(MX25_PAD_UART1_RXD),
+ IMX_PINCTRL_PIN(MX25_PAD_UART1_TXD),
+ IMX_PINCTRL_PIN(MX25_PAD_UART1_RTS),
+ IMX_PINCTRL_PIN(MX25_PAD_UART1_CTS),
+ IMX_PINCTRL_PIN(MX25_PAD_UART2_RXD),
+ IMX_PINCTRL_PIN(MX25_PAD_UART2_TXD),
+ IMX_PINCTRL_PIN(MX25_PAD_UART2_RTS),
+ IMX_PINCTRL_PIN(MX25_PAD_UART2_CTS),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_CMD),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_CLK),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA0),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA1),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA2),
+ IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA3),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW0),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW1),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW2),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW3),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_COL0),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_COL1),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_COL2),
+ IMX_PINCTRL_PIN(MX25_PAD_KPP_COL3),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_MDC),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_MDIO),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_TDATA0),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_TDATA1),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_TX_EN),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_RDATA0),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_RDATA1),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_RX_DV),
+ IMX_PINCTRL_PIN(MX25_PAD_FEC_TX_CLK),
+ IMX_PINCTRL_PIN(MX25_PAD_RTCK),
+ IMX_PINCTRL_PIN(MX25_PAD_DE_B),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_A),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_B),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_C),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_D),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_E),
+ IMX_PINCTRL_PIN(MX25_PAD_GPIO_F),
+ IMX_PINCTRL_PIN(MX25_PAD_EXT_ARMCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_UPLL_BYPCLK),
+ IMX_PINCTRL_PIN(MX25_PAD_VSTBY_REQ),
+ IMX_PINCTRL_PIN(MX25_PAD_VSTBY_ACK),
+ IMX_PINCTRL_PIN(MX25_PAD_POWER_FAIL),
+ IMX_PINCTRL_PIN(MX25_PAD_CLKO),
+ IMX_PINCTRL_PIN(MX25_PAD_BOOT_MODE0),
+ IMX_PINCTRL_PIN(MX25_PAD_BOOT_MODE1),
+};
+
+static struct imx_pinctrl_soc_info imx25_pinctrl_info = {
+ .pins = imx25_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx25_pinctrl_pads),
+};
+
+static struct of_device_id imx25_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx25-iomuxc", },
+ { /* sentinel */ }
+};
+
+static int imx25_pinctrl_probe(struct platform_device *pdev)
+{
+ return imx_pinctrl_probe(pdev, &imx25_pinctrl_info);
+}
+
+static struct platform_driver imx25_pinctrl_driver = {
+ .driver = {
+ .name = "imx25-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(imx25_pinctrl_of_match),
+ },
+ .probe = imx25_pinctrl_probe,
+ .remove = imx_pinctrl_remove,
+};
+
+static int __init imx25_pinctrl_init(void)
+{
+ return platform_driver_register(&imx25_pinctrl_driver);
+}
+arch_initcall(imx25_pinctrl_init);
+
+static void __exit imx25_pinctrl_exit(void)
+{
+ platform_driver_unregister(&imx25_pinctrl_driver);
+}
+module_exit(imx25_pinctrl_exit);
+MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>");
+MODULE_DESCRIPTION("Freescale IMX25 pinctrl driver");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include <linux/err.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_irq.h>
+#include <linux/spinlock.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-msm.h"
+#include "pinctrl-utils.h"
+
+/**
+ * struct msm_pinctrl - state for a pinctrl-msm device
+ * @dev: device handle.
+ * @pctrl: pinctrl handle.
+ * @domain: irqdomain handle.
+ * @chip: gpiochip handle.
+ * @irq: parent irq for the TLMM irq_chip.
+ * @lock: Spinlock to protect register resources as well
+ * as msm_pinctrl data structures.
+ * @enabled_irqs: Bitmap of currently enabled irqs.
+ * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
+ * detection.
+ * @wake_irqs: Bitmap of irqs with requested as wakeup source.
+ * @soc; Reference to soc_data of platform specific data.
+ * @regs: Base address for the TLMM register map.
+ */
+struct msm_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctrl;
+ struct irq_domain *domain;
+ struct gpio_chip chip;
+ unsigned irq;
+
+ spinlock_t lock;
+
+ unsigned long *enabled_irqs;
+ unsigned long *dual_edge_irqs;
+ unsigned long *wake_irqs;
+
+ const struct msm_pinctrl_soc_data *soc;
+ void __iomem *regs;
+};
+
+static int msm_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->soc->ngroups;
+}
+
+static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned group)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->soc->groups[group].name;
+}
+
+static int msm_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = pctrl->soc->groups[group].pins;
+ *num_pins = pctrl->soc->groups[group].npins;
+ return 0;
+}
+
+static struct pinctrl_ops msm_pinctrl_ops = {
+ .get_groups_count = msm_get_groups_count,
+ .get_group_name = msm_get_group_name,
+ .get_group_pins = msm_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int msm_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->soc->nfunctions;
+}
+
+static const char *msm_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned function)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->soc->functions[function].name;
+}
+
+static int msm_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pctrl->soc->functions[function].groups;
+ *num_groups = pctrl->soc->functions[function].ngroups;
+ return 0;
+}
+
+static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
+ unsigned function,
+ unsigned group)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ const struct msm_pingroup *g;
+ unsigned long flags;
+ u32 val;
+ int i;
+
+ g = &pctrl->soc->groups[group];
+
+ if (WARN_ON(g->mux_bit < 0))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
+ if (g->funcs[i] == function)
+ break;
+ }
+
+ if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
+ return -EINVAL;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->ctl_reg);
+ val &= ~(0x7 << g->mux_bit);
+ val |= i << g->mux_bit;
+ writel(val, pctrl->regs + g->ctl_reg);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
+static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
+ unsigned function,
+ unsigned group)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ const struct msm_pingroup *g;
+ unsigned long flags;
+ u32 val;
+
+ g = &pctrl->soc->groups[group];
+
+ if (WARN_ON(g->mux_bit < 0))
+ return;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ /* Clear the mux bits to select gpio mode */
+ val = readl(pctrl->regs + g->ctl_reg);
+ val &= ~(0x7 << g->mux_bit);
+ writel(val, pctrl->regs + g->ctl_reg);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static struct pinmux_ops msm_pinmux_ops = {
+ .get_functions_count = msm_get_functions_count,
+ .get_function_name = msm_get_function_name,
+ .get_function_groups = msm_get_function_groups,
+ .enable = msm_pinmux_enable,
+ .disable = msm_pinmux_disable,
+};
+
+static int msm_config_reg(struct msm_pinctrl *pctrl,
+ const struct msm_pingroup *g,
+ unsigned param,
+ unsigned *reg,
+ unsigned *mask,
+ unsigned *bit)
+{
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ *reg = g->ctl_reg;
+ *bit = g->pull_bit;
+ *mask = 3;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ *reg = g->ctl_reg;
+ *bit = g->pull_bit;
+ *mask = 3;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ *reg = g->ctl_reg;
+ *bit = g->pull_bit;
+ *mask = 3;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ *reg = g->ctl_reg;
+ *bit = g->drv_bit;
+ *mask = 7;
+ break;
+ default:
+ dev_err(pctrl->dev, "Invalid config param %04x\n", param);
+ return -ENOTSUPP;
+ }
+
+ if (*reg < 0) {
+ dev_err(pctrl->dev, "Config param %04x not supported on group %s\n",
+ param, g->name);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int msm_config_get(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *config)
+{
+ dev_err(pctldev->dev, "pin_config_set op not supported\n");
+ return -ENOTSUPP;
+}
+
+static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *configs, unsigned num_configs)
+{
+ dev_err(pctldev->dev, "pin_config_set op not supported\n");
+ return -ENOTSUPP;
+}
+
+#define MSM_NO_PULL 0
+#define MSM_PULL_DOWN 1
+#define MSM_PULL_UP 3
+
+static const unsigned msm_regval_to_drive[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+static const unsigned msm_drive_to_regval[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7 };
+
+static int msm_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int group,
+ unsigned long *config)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned param = pinconf_to_config_param(*config);
+ unsigned mask;
+ unsigned arg;
+ unsigned bit;
+ unsigned reg;
+ int ret;
+ u32 val;
+
+ g = &pctrl->soc->groups[group];
+
+ ret = msm_config_reg(pctrl, g, param, ®, &mask, &bit);
+ if (ret < 0)
+ return ret;
+
+ val = readl(pctrl->regs + reg);
+ arg = (val >> bit) & mask;
+
+ /* Convert register value to pinconf value */
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ arg = arg == MSM_NO_PULL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = arg == MSM_PULL_DOWN;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ arg = arg == MSM_PULL_UP;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ arg = msm_regval_to_drive[arg];
+ break;
+ default:
+ dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
+ param);
+ return -EINVAL;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int msm_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned group,
+ unsigned long *configs,
+ unsigned num_configs)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned long flags;
+ unsigned param;
+ unsigned mask;
+ unsigned arg;
+ unsigned bit;
+ unsigned reg;
+ int ret;
+ u32 val;
+ int i;
+
+ g = &pctrl->soc->groups[group];
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ ret = msm_config_reg(pctrl, g, param, ®, &mask, &bit);
+ if (ret < 0)
+ return ret;
+
+ /* Convert pinconf values to register values */
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ arg = MSM_NO_PULL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = MSM_PULL_DOWN;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ arg = MSM_PULL_UP;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* Check for invalid values */
+ if (arg > ARRAY_SIZE(msm_drive_to_regval))
+ arg = -1;
+ else
+ arg = msm_drive_to_regval[arg];
+ break;
+ default:
+ dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
+ param);
+ return -EINVAL;
+ }
+
+ /* Range-check user-supplied value */
+ if (arg & ~mask) {
+ dev_err(pctrl->dev, "config %x: %x is invalid\n", param, arg);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+ val = readl(pctrl->regs + reg);
+ val &= ~(mask << bit);
+ val |= arg << bit;
+ writel(val, pctrl->regs + reg);
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+ }
+
+ return 0;
+}
+
+static struct pinconf_ops msm_pinconf_ops = {
+ .pin_config_get = msm_config_get,
+ .pin_config_set = msm_config_set,
+ .pin_config_group_get = msm_config_group_get,
+ .pin_config_group_set = msm_config_group_set,
+};
+
+static struct pinctrl_desc msm_pinctrl_desc = {
+ .pctlops = &msm_pinctrl_ops,
+ .pmxops = &msm_pinmux_ops,
+ .confops = &msm_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+ unsigned long flags;
+ u32 val;
+
+ if (WARN_ON(offset >= pctrl->soc->ngroups))
+ return -EINVAL;
+
+ g = &pctrl->soc->groups[offset];
+
+ if (WARN_ON(g->oe_bit < 0))
+ return -EINVAL;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->ctl_reg);
+ val &= ~BIT(g->oe_bit);
+ writel(val, pctrl->regs + g->ctl_reg);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
+static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+ unsigned long flags;
+ u32 val;
+
+ if (WARN_ON(offset >= pctrl->soc->ngroups))
+ return -EINVAL;
+
+ g = &pctrl->soc->groups[offset];
+
+ if (WARN_ON(g->oe_bit < 0))
+ return -EINVAL;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ writel(value ? BIT(g->out_bit) : 0, pctrl->regs + g->io_reg);
+
+ val = readl(pctrl->regs + g->ctl_reg);
+ val |= BIT(g->oe_bit);
+ writel(val, pctrl->regs + g->ctl_reg);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+ u32 val;
+
+ if (WARN_ON(offset >= pctrl->soc->ngroups))
+ return -EINVAL;
+
+ g = &pctrl->soc->groups[offset];
+
+ val = readl(pctrl->regs + g->io_reg);
+ return !!(val & BIT(g->in_bit));
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+ unsigned long flags;
+ u32 val;
+
+ if (WARN_ON(offset >= pctrl->soc->ngroups))
+ return;
+
+ g = &pctrl->soc->groups[offset];
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->io_reg);
+ val |= BIT(g->out_bit);
+ writel(val, pctrl->regs + g->io_reg);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+
+ return irq_find_mapping(pctrl->domain, offset);
+}
+
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+ return pinctrl_request_gpio(gpio);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+ return pinctrl_free_gpio(gpio);
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void msm_gpio_dbg_show_one(struct seq_file *s,
+ struct pinctrl_dev *pctldev,
+ struct gpio_chip *chip,
+ unsigned offset,
+ unsigned gpio)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+ unsigned func;
+ int is_out;
+ int drive;
+ int pull;
+ u32 ctl_reg;
+
+ const char *pulls[] = {
+ "no pull",
+ "pull down",
+ "keeper",
+ "pull up"
+ };
+
+ g = &pctrl->soc->groups[offset];
+ ctl_reg = readl(pctrl->regs + g->ctl_reg);
+
+ is_out = !!(ctl_reg & BIT(g->oe_bit));
+ func = (ctl_reg >> g->mux_bit) & 7;
+ drive = (ctl_reg >> g->drv_bit) & 7;
+ pull = (ctl_reg >> g->pull_bit) & 3;
+
+ seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
+ seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
+ seq_printf(s, " %s", pulls[pull]);
+}
+
+static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ unsigned gpio = chip->base;
+ unsigned i;
+
+ for (i = 0; i < chip->ngpio; i++, gpio++) {
+ msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
+ seq_printf(s, "\n");
+ }
+}
+
+#else
+#define msm_gpio_dbg_show NULL
+#endif
+
+static struct gpio_chip msm_gpio_template = {
+ .direction_input = msm_gpio_direction_input,
+ .direction_output = msm_gpio_direction_output,
+ .get = msm_gpio_get,
+ .set = msm_gpio_set,
+ .to_irq = msm_gpio_to_irq,
+ .request = msm_gpio_request,
+ .free = msm_gpio_free,
+ .dbg_show = msm_gpio_dbg_show,
+};
+
+/* For dual-edge interrupts in software, since some hardware has no
+ * such support:
+ *
+ * At appropriate moments, this function may be called to flip the polarity
+ * settings of both-edge irq lines to try and catch the next edge.
+ *
+ * The attempt is considered successful if:
+ * - the status bit goes high, indicating that an edge was caught, or
+ * - the input value of the gpio doesn't change during the attempt.
+ * If the value changes twice during the process, that would cause the first
+ * test to fail but would force the second, as two opposite
+ * transitions would cause a detection no matter the polarity setting.
+ *
+ * The do-loop tries to sledge-hammer closed the timing hole between
+ * the initial value-read and the polarity-write - if the line value changes
+ * during that window, an interrupt is lost, the new polarity setting is
+ * incorrect, and the first success test will fail, causing a retry.
+ *
+ * Algorithm comes from Google's msmgpio driver.
+ */
+static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
+ const struct msm_pingroup *g,
+ struct irq_data *d)
+{
+ int loop_limit = 100;
+ unsigned val, val2, intstat;
+ unsigned pol;
+
+ do {
+ val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
+
+ pol = readl(pctrl->regs + g->intr_cfg_reg);
+ pol ^= BIT(g->intr_polarity_bit);
+ writel(pol, pctrl->regs + g->intr_cfg_reg);
+
+ val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
+ intstat = readl(pctrl->regs + g->intr_status_reg);
+ if (intstat || (val == val2))
+ return;
+ } while (loop_limit-- > 0);
+ dev_err(pctrl->dev, "dual-edge irq failed to stabilize, %#08x != %#08x\n",
+ val, val2);
+}
+
+static void msm_gpio_irq_mask(struct irq_data *d)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl;
+ unsigned long flags;
+ u32 val;
+
+ pctrl = irq_data_get_irq_chip_data(d);
+ if (!pctrl)
+ return;
+
+ if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
+ return;
+
+ g = &pctrl->soc->groups[d->hwirq];
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->intr_cfg_reg);
+ val &= ~BIT(g->intr_enable_bit);
+ writel(val, pctrl->regs + g->intr_cfg_reg);
+
+ clear_bit(d->hwirq, pctrl->enabled_irqs);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void msm_gpio_irq_unmask(struct irq_data *d)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl;
+ unsigned long flags;
+ u32 val;
+
+ pctrl = irq_data_get_irq_chip_data(d);
+ if (!pctrl)
+ return;
+
+ if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
+ return;
+
+ g = &pctrl->soc->groups[d->hwirq];
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->intr_status_reg);
+ val &= ~BIT(g->intr_status_bit);
+ writel(val, pctrl->regs + g->intr_status_reg);
+
+ val = readl(pctrl->regs + g->intr_cfg_reg);
+ val |= BIT(g->intr_enable_bit);
+ writel(val, pctrl->regs + g->intr_cfg_reg);
+
+ set_bit(d->hwirq, pctrl->enabled_irqs);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void msm_gpio_irq_ack(struct irq_data *d)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl;
+ unsigned long flags;
+ u32 val;
+
+ pctrl = irq_data_get_irq_chip_data(d);
+ if (!pctrl)
+ return;
+
+ if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
+ return;
+
+ g = &pctrl->soc->groups[d->hwirq];
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ val = readl(pctrl->regs + g->intr_status_reg);
+ val &= ~BIT(g->intr_status_bit);
+ writel(val, pctrl->regs + g->intr_status_reg);
+
+ if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+ msm_gpio_update_dual_edge_pos(pctrl, g, d);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+#define INTR_TARGET_PROC_APPS 4
+
+static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl;
+ unsigned long flags;
+ u32 val;
+
+ pctrl = irq_data_get_irq_chip_data(d);
+ if (!pctrl)
+ return -EINVAL;
+
+ if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
+ return -EINVAL;
+
+ g = &pctrl->soc->groups[d->hwirq];
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ /*
+ * For hw without possibility of detecting both edges
+ */
+ if (g->intr_detection_width == 1 && type == IRQ_TYPE_EDGE_BOTH)
+ set_bit(d->hwirq, pctrl->dual_edge_irqs);
+ else
+ clear_bit(d->hwirq, pctrl->dual_edge_irqs);
+
+ /* Route interrupts to application cpu */
+ val = readl(pctrl->regs + g->intr_target_reg);
+ val &= ~(7 << g->intr_target_bit);
+ val |= INTR_TARGET_PROC_APPS << g->intr_target_bit;
+ writel(val, pctrl->regs + g->intr_target_reg);
+
+ /* Update configuration for gpio.
+ * RAW_STATUS_EN is left on for all gpio irqs. Due to the
+ * internal circuitry of TLMM, toggling the RAW_STATUS
+ * could cause the INTR_STATUS to be set for EDGE interrupts.
+ */
+ val = readl(pctrl->regs + g->intr_cfg_reg);
+ val |= BIT(g->intr_raw_status_bit);
+ if (g->intr_detection_width == 2) {
+ val &= ~(3 << g->intr_detection_bit);
+ val &= ~(1 << g->intr_polarity_bit);
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ val |= 1 << g->intr_detection_bit;
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ val |= 2 << g->intr_detection_bit;
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ val |= 3 << g->intr_detection_bit;
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ }
+ } else if (g->intr_detection_width == 1) {
+ val &= ~(1 << g->intr_detection_bit);
+ val &= ~(1 << g->intr_polarity_bit);
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ val |= BIT(g->intr_detection_bit);
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ val |= BIT(g->intr_detection_bit);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ val |= BIT(g->intr_detection_bit);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ val |= BIT(g->intr_polarity_bit);
+ break;
+ }
+ } else {
+ BUG();
+ }
+ writel(val, pctrl->regs + g->intr_cfg_reg);
+
+ if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+ msm_gpio_update_dual_edge_pos(pctrl, g, d);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+
+ return 0;
+}
+
+static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct msm_pinctrl *pctrl;
+ unsigned long flags;
+ unsigned ngpio;
+
+ pctrl = irq_data_get_irq_chip_data(d);
+ if (!pctrl)
+ return -EINVAL;
+
+ ngpio = pctrl->chip.ngpio;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ if (on) {
+ if (bitmap_empty(pctrl->wake_irqs, ngpio))
+ enable_irq_wake(pctrl->irq);
+ set_bit(d->hwirq, pctrl->wake_irqs);
+ } else {
+ clear_bit(d->hwirq, pctrl->wake_irqs);
+ if (bitmap_empty(pctrl->wake_irqs, ngpio))
+ disable_irq_wake(pctrl->irq);
+ }
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
+static unsigned int msm_gpio_irq_startup(struct irq_data *d)
+{
+ struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
+
+ if (gpio_lock_as_irq(&pctrl->chip, d->hwirq)) {
+ dev_err(pctrl->dev, "unable to lock HW IRQ %lu for IRQ\n",
+ d->hwirq);
+ }
+ msm_gpio_irq_unmask(d);
+ return 0;
+}
+
+static void msm_gpio_irq_shutdown(struct irq_data *d)
+{
+ struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
+
+ msm_gpio_irq_mask(d);
+ gpio_unlock_as_irq(&pctrl->chip, d->hwirq);
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msmgpio",
+ .irq_mask = msm_gpio_irq_mask,
+ .irq_unmask = msm_gpio_irq_unmask,
+ .irq_ack = msm_gpio_irq_ack,
+ .irq_set_type = msm_gpio_irq_set_type,
+ .irq_set_wake = msm_gpio_irq_set_wake,
+ .irq_startup = msm_gpio_irq_startup,
+ .irq_shutdown = msm_gpio_irq_shutdown,
+};
+
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ const struct msm_pingroup *g;
+ struct msm_pinctrl *pctrl = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_get_chip(irq);
+ int irq_pin;
+ int handled = 0;
+ u32 val;
+ int i;
+
+ chained_irq_enter(chip, desc);
+
+ /*
+ * Each pin have it's own IRQ status register, so use
+ * enabled_irq bitmap to limit the number of reads.
+ */
+ for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
+ g = &pctrl->soc->groups[i];
+ val = readl(pctrl->regs + g->intr_status_reg);
+ if (val & BIT(g->intr_status_bit)) {
+ irq_pin = irq_find_mapping(pctrl->domain, i);
+ generic_handle_irq(irq_pin);
+ handled++;
+ }
+ }
+
+ /* No interrutps where flagged */
+ if (handled == 0)
+ handle_bad_irq(irq, desc);
+
+ chained_irq_exit(chip, desc);
+}
+
+static int msm_gpio_init(struct msm_pinctrl *pctrl)
+{
+ struct gpio_chip *chip;
+ int irq;
+ int ret;
+ int i;
+ int r;
+
+ chip = &pctrl->chip;
+ chip->base = 0;
+ chip->ngpio = pctrl->soc->ngpios;
+ chip->label = dev_name(pctrl->dev);
+ chip->dev = pctrl->dev;
+ chip->owner = THIS_MODULE;
+ chip->of_node = pctrl->dev->of_node;
+
+ pctrl->enabled_irqs = devm_kzalloc(pctrl->dev,
+ sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
+ GFP_KERNEL);
+ if (!pctrl->enabled_irqs) {
+ dev_err(pctrl->dev, "Failed to allocate enabled_irqs bitmap\n");
+ return -ENOMEM;
+ }
+
+ pctrl->dual_edge_irqs = devm_kzalloc(pctrl->dev,
+ sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
+ GFP_KERNEL);
+ if (!pctrl->dual_edge_irqs) {
+ dev_err(pctrl->dev, "Failed to allocate dual_edge_irqs bitmap\n");
+ return -ENOMEM;
+ }
+
+ pctrl->wake_irqs = devm_kzalloc(pctrl->dev,
+ sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
+ GFP_KERNEL);
+ if (!pctrl->wake_irqs) {
+ dev_err(pctrl->dev, "Failed to allocate wake_irqs bitmap\n");
+ return -ENOMEM;
+ }
+
+ ret = gpiochip_add(&pctrl->chip);
+ if (ret) {
+ dev_err(pctrl->dev, "Failed register gpiochip\n");
+ return ret;
+ }
+
+ ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
+ if (ret) {
+ dev_err(pctrl->dev, "Failed to add pin range\n");
+ return ret;
+ }
+
+ pctrl->domain = irq_domain_add_linear(pctrl->dev->of_node, chip->ngpio,
+ &irq_domain_simple_ops, NULL);
+ if (!pctrl->domain) {
+ dev_err(pctrl->dev, "Failed to register irq domain\n");
+ r = gpiochip_remove(&pctrl->chip);
+ return -ENOSYS;
+ }
+
+ for (i = 0; i < chip->ngpio; i++) {
+ irq = irq_create_mapping(pctrl->domain, i);
+ irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
+ irq_set_chip_data(irq, pctrl);
+ }
+
+ irq_set_handler_data(pctrl->irq, pctrl);
+ irq_set_chained_handler(pctrl->irq, msm_gpio_irq_handler);
+
+ return 0;
+}
+
+int msm_pinctrl_probe(struct platform_device *pdev,
+ const struct msm_pinctrl_soc_data *soc_data)
+{
+ struct msm_pinctrl *pctrl;
+ struct resource *res;
+ int ret;
+
+ pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+ if (!pctrl) {
+ dev_err(&pdev->dev, "Can't allocate msm_pinctrl\n");
+ return -ENOMEM;
+ }
+ pctrl->dev = &pdev->dev;
+ pctrl->soc = soc_data;
+ pctrl->chip = msm_gpio_template;
+
+ spin_lock_init(&pctrl->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pctrl->regs))
+ return PTR_ERR(pctrl->regs);
+
+ pctrl->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (pctrl->irq < 0) {
+ dev_err(&pdev->dev, "No interrupt defined for msmgpio\n");
+ return pctrl->irq;
+ }
+
+ msm_pinctrl_desc.name = dev_name(&pdev->dev);
+ msm_pinctrl_desc.pins = pctrl->soc->pins;
+ msm_pinctrl_desc.npins = pctrl->soc->npins;
+ pctrl->pctrl = pinctrl_register(&msm_pinctrl_desc, &pdev->dev, pctrl);
+ if (!pctrl->pctrl) {
+ dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+ return -ENODEV;
+ }
+
+ ret = msm_gpio_init(pctrl);
+ if (ret) {
+ pinctrl_unregister(pctrl->pctrl);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, pctrl);
+
+ dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_pinctrl_probe);
+
+int msm_pinctrl_remove(struct platform_device *pdev)
+{
+ struct msm_pinctrl *pctrl = platform_get_drvdata(pdev);
+ int ret;
+
+ irq_set_chained_handler(pctrl->irq, NULL);
+ irq_domain_remove(pctrl->domain);
+ ret = gpiochip_remove(&pctrl->chip);
+ pinctrl_unregister(pctrl->pctrl);
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_pinctrl_remove);
+
--- /dev/null
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ */
+#ifndef __PINCTRL_MSM_H__
+#define __PINCTRL_MSM_H__
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/machine.h>
+
+/**
+ * struct msm_function - a pinmux function
+ * @name: Name of the pinmux function.
+ * @groups: List of pingroups for this function.
+ * @ngroups: Number of entries in @groups.
+ */
+struct msm_function {
+ const char *name;
+ const char * const *groups;
+ unsigned ngroups;
+};
+
+/**
+ * struct msm_pingroup - Qualcomm pingroup definition
+ * @name: Name of the pingroup.
+ * @pins: A list of pins assigned to this pingroup.
+ * @npins: Number of entries in @pins.
+ * @funcs: A list of pinmux functions that can be selected for
+ * this group. The index of the selected function is used
+ * for programming the function selector.
+ * Entries should be indices into the groups list of the
+ * struct msm_pinctrl_soc_data.
+ * @ctl_reg: Offset of the register holding control bits for this group.
+ * @io_reg: Offset of the register holding input/output bits for this group.
+ * @intr_cfg_reg: Offset of the register holding interrupt configuration bits.
+ * @intr_status_reg: Offset of the register holding the status bits for this group.
+ * @intr_target_reg: Offset of the register specifying routing of the interrupts
+ * from this group.
+ * @mux_bit: Offset in @ctl_reg for the pinmux function selection.
+ * @pull_bit: Offset in @ctl_reg for the bias configuration.
+ * @drv_bit: Offset in @ctl_reg for the drive strength configuration.
+ * @oe_bit: Offset in @ctl_reg for controlling output enable.
+ * @in_bit: Offset in @io_reg for the input bit value.
+ * @out_bit: Offset in @io_reg for the output bit value.
+ * @intr_enable_bit: Offset in @intr_cfg_reg for enabling the interrupt for this group.
+ * @intr_status_bit: Offset in @intr_status_reg for reading and acking the interrupt
+ * status.
+ * @intr_target_bit: Offset in @intr_target_reg for configuring the interrupt routing.
+ * @intr_raw_status_bit: Offset in @intr_cfg_reg for the raw status bit.
+ * @intr_polarity_bit: Offset in @intr_cfg_reg for specifying polarity of the interrupt.
+ * @intr_detection_bit: Offset in @intr_cfg_reg for specifying interrupt type.
+ * @intr_detection_width: Number of bits used for specifying interrupt type,
+ * Should be 2 for SoCs that can detect both edges in hardware,
+ * otherwise 1.
+ */
+struct msm_pingroup {
+ const char *name;
+ const unsigned *pins;
+ unsigned npins;
+
+ unsigned funcs[8];
+
+ s16 ctl_reg;
+ s16 io_reg;
+ s16 intr_cfg_reg;
+ s16 intr_status_reg;
+ s16 intr_target_reg;
+
+ unsigned mux_bit:5;
+
+ unsigned pull_bit:5;
+ unsigned drv_bit:5;
+
+ unsigned oe_bit:5;
+ unsigned in_bit:5;
+ unsigned out_bit:5;
+
+ unsigned intr_enable_bit:5;
+ unsigned intr_status_bit:5;
+
+ unsigned intr_target_bit:5;
+ unsigned intr_raw_status_bit:5;
+ unsigned intr_polarity_bit:5;
+ unsigned intr_detection_bit:5;
+ unsigned intr_detection_width:5;
+};
+
+/**
+ * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
+ * @pins: An array describing all pins the pin controller affects.
+ * @npins: The number of entries in @pins.
+ * @functions: An array describing all mux functions the SoC supports.
+ * @nfunctions: The number of entries in @functions.
+ * @groups: An array describing all pin groups the pin SoC supports.
+ * @ngroups: The numbmer of entries in @groups.
+ * @ngpio: The number of pingroups the driver should expose as GPIOs.
+ */
+struct msm_pinctrl_soc_data {
+ const struct pinctrl_pin_desc *pins;
+ unsigned npins;
+ const struct msm_function *functions;
+ unsigned nfunctions;
+ const struct msm_pingroup *groups;
+ unsigned ngroups;
+ unsigned ngpios;
+};
+
+int msm_pinctrl_probe(struct platform_device *pdev,
+ const struct msm_pinctrl_soc_data *soc_data);
+int msm_pinctrl_remove(struct platform_device *pdev);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc msm8x74_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "GPIO_100"),
+ PINCTRL_PIN(101, "GPIO_101"),
+ PINCTRL_PIN(102, "GPIO_102"),
+ PINCTRL_PIN(103, "GPIO_103"),
+ PINCTRL_PIN(104, "GPIO_104"),
+ PINCTRL_PIN(105, "GPIO_105"),
+ PINCTRL_PIN(106, "GPIO_106"),
+ PINCTRL_PIN(107, "GPIO_107"),
+ PINCTRL_PIN(108, "GPIO_108"),
+ PINCTRL_PIN(109, "GPIO_109"),
+ PINCTRL_PIN(110, "GPIO_110"),
+ PINCTRL_PIN(111, "GPIO_111"),
+ PINCTRL_PIN(112, "GPIO_112"),
+ PINCTRL_PIN(113, "GPIO_113"),
+ PINCTRL_PIN(114, "GPIO_114"),
+ PINCTRL_PIN(115, "GPIO_115"),
+ PINCTRL_PIN(116, "GPIO_116"),
+ PINCTRL_PIN(117, "GPIO_117"),
+ PINCTRL_PIN(118, "GPIO_118"),
+ PINCTRL_PIN(119, "GPIO_119"),
+ PINCTRL_PIN(120, "GPIO_120"),
+ PINCTRL_PIN(121, "GPIO_121"),
+ PINCTRL_PIN(122, "GPIO_122"),
+ PINCTRL_PIN(123, "GPIO_123"),
+ PINCTRL_PIN(124, "GPIO_124"),
+ PINCTRL_PIN(125, "GPIO_125"),
+ PINCTRL_PIN(126, "GPIO_126"),
+ PINCTRL_PIN(127, "GPIO_127"),
+ PINCTRL_PIN(128, "GPIO_128"),
+ PINCTRL_PIN(129, "GPIO_129"),
+ PINCTRL_PIN(130, "GPIO_130"),
+ PINCTRL_PIN(131, "GPIO_131"),
+ PINCTRL_PIN(132, "GPIO_132"),
+ PINCTRL_PIN(133, "GPIO_133"),
+ PINCTRL_PIN(134, "GPIO_134"),
+ PINCTRL_PIN(135, "GPIO_135"),
+ PINCTRL_PIN(136, "GPIO_136"),
+ PINCTRL_PIN(137, "GPIO_137"),
+ PINCTRL_PIN(138, "GPIO_138"),
+ PINCTRL_PIN(139, "GPIO_139"),
+ PINCTRL_PIN(140, "GPIO_140"),
+ PINCTRL_PIN(141, "GPIO_141"),
+ PINCTRL_PIN(142, "GPIO_142"),
+ PINCTRL_PIN(143, "GPIO_143"),
+ PINCTRL_PIN(144, "GPIO_144"),
+ PINCTRL_PIN(145, "GPIO_145"),
+
+ PINCTRL_PIN(146, "SDC1_CLK"),
+ PINCTRL_PIN(147, "SDC1_CMD"),
+ PINCTRL_PIN(148, "SDC1_DATA"),
+ PINCTRL_PIN(149, "SDC2_CLK"),
+ PINCTRL_PIN(150, "SDC2_CMD"),
+ PINCTRL_PIN(151, "SDC2_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+
+static const unsigned int sdc1_clk_pins[] = { 146 };
+static const unsigned int sdc1_cmd_pins[] = { 147 };
+static const unsigned int sdc1_data_pins[] = { 148 };
+static const unsigned int sdc2_clk_pins[] = { 149 };
+static const unsigned int sdc2_cmd_pins[] = { 150 };
+static const unsigned int sdc2_data_pins[] = { 151 };
+
+#define FUNCTION(fname) \
+ [MSM_MUX_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = { \
+ MSM_MUX_NA, /* gpio mode */ \
+ MSM_MUX_##f1, \
+ MSM_MUX_##f2, \
+ MSM_MUX_##f3, \
+ MSM_MUX_##f4, \
+ MSM_MUX_##f5, \
+ MSM_MUX_##f6, \
+ MSM_MUX_##f7 \
+ }, \
+ .ctl_reg = 0x1000 + 0x10 * id , \
+ .io_reg = 0x1004 + 0x10 * id, \
+ .intr_cfg_reg = 0x1008 + 0x10 * id, \
+ .intr_status_reg = 0x100c + 0x10 * id, \
+ .intr_target_reg = 0x1008 + 0x10 * id, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_target_bit = 5, \
+ .intr_raw_status_bit = 4, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 2, \
+ }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+
+/*
+ * TODO: Add the rest of the possible functions and fill out
+ * the pingroup table below.
+ */
+enum msm8x74_functions {
+ MSM_MUX_blsp_i2c2,
+ MSM_MUX_blsp_i2c6,
+ MSM_MUX_blsp_i2c11,
+ MSM_MUX_blsp_spi1,
+ MSM_MUX_blsp_uart2,
+ MSM_MUX_blsp_uart8,
+ MSM_MUX_slimbus,
+ MSM_MUX_NA,
+};
+
+static const char * const blsp_i2c2_groups[] = { "gpio6", "gpio7" };
+static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
+static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
+static const char * const blsp_spi1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" };
+static const char * const blsp_uart2_groups[] = { "gpio4", "gpio5" };
+static const char * const blsp_uart8_groups[] = { "gpio45", "gpio46" };
+static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
+
+static const struct msm_function msm8x74_functions[] = {
+ FUNCTION(blsp_i2c2),
+ FUNCTION(blsp_i2c6),
+ FUNCTION(blsp_i2c11),
+ FUNCTION(blsp_spi1),
+ FUNCTION(blsp_uart2),
+ FUNCTION(blsp_uart8),
+ FUNCTION(slimbus),
+};
+
+static const struct msm_pingroup msm8x74_groups[] = {
+ PINGROUP(0, blsp_spi1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(1, blsp_spi1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(2, blsp_spi1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(3, blsp_spi1, NA, NA, NA, NA, NA, NA),
+ PINGROUP(4, NA, blsp_uart2, NA, NA, NA, NA, NA),
+ PINGROUP(5, NA, blsp_uart2, NA, NA, NA, NA, NA),
+ PINGROUP(6, NA, NA, blsp_i2c2, NA, NA, NA, NA),
+ PINGROUP(7, NA, NA, blsp_i2c2, NA, NA, NA, NA),
+ PINGROUP(8, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(9, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(10, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(11, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(12, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(13, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(14, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(15, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(16, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(17, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(18, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(19, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(20, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(21, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(22, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(23, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(24, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(25, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(26, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(27, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(28, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(29, NA, NA, blsp_i2c6, NA, NA, NA, NA),
+ PINGROUP(30, NA, NA, blsp_i2c6, NA, NA, NA, NA),
+ PINGROUP(31, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(32, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(33, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(34, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(35, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(36, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(37, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(39, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(40, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(41, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(42, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(43, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(44, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, NA, blsp_uart8, NA, NA, NA, NA, NA),
+ PINGROUP(46, NA, blsp_uart8, NA, NA, NA, NA, NA),
+ PINGROUP(47, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(48, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(49, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(51, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(61, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(62, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(63, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(65, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(66, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(67, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(68, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(69, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(70, slimbus, NA, NA, NA, NA, NA, NA),
+ PINGROUP(71, slimbus, NA, NA, NA, NA, NA, NA),
+ PINGROUP(72, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(76, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, NA, NA, blsp_i2c11, NA, NA, NA, NA),
+ PINGROUP(84, NA, NA, blsp_i2c11, NA, NA, NA, NA),
+ PINGROUP(85, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(88, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(89, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(92, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(93, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(100, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(101, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(102, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(103, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(104, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(105, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(106, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(107, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(108, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(109, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(110, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(111, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(112, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(113, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(114, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(115, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(116, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(117, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(118, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(119, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(120, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(121, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(122, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(123, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(124, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(125, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(126, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(127, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(128, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(129, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(130, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(131, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(132, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(133, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(134, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(135, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(136, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(137, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(138, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(139, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(140, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(141, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(143, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(143, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(144, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(145, NA, NA, NA, NA, NA, NA, NA),
+ SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6),
+ SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3),
+ SDC_PINGROUP(sdc1_data, 0x2044, 9, 0),
+ SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
+ SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
+ SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 146
+
+static const struct msm_pinctrl_soc_data msm8x74_pinctrl = {
+ .pins = msm8x74_pins,
+ .npins = ARRAY_SIZE(msm8x74_pins),
+ .functions = msm8x74_functions,
+ .nfunctions = ARRAY_SIZE(msm8x74_functions),
+ .groups = msm8x74_groups,
+ .ngroups = ARRAY_SIZE(msm8x74_groups),
+ .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8x74_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &msm8x74_pinctrl);
+}
+
+static struct of_device_id msm8x74_pinctrl_of_match[] = {
+ { .compatible = "qcom,msm8x74-pinctrl", },
+ { },
+};
+
+static struct platform_driver msm8x74_pinctrl_driver = {
+ .driver = {
+ .name = "msm8x74-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = msm8x74_pinctrl_of_match,
+ },
+ .probe = msm8x74_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8x74_pinctrl_init(void)
+{
+ return platform_driver_register(&msm8x74_pinctrl_driver);
+}
+arch_initcall(msm8x74_pinctrl_init);
+
+static void __exit msm8x74_pinctrl_exit(void)
+{
+ platform_driver_unregister(&msm8x74_pinctrl_driver);
+}
+module_exit(msm8x74_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm MSM8x74 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8x74_pinctrl_of_match);
+
(mode < 0) ? "unknown" : modes[mode],
pull ? "pull" : "none");
- if (label && !is_out) {
- int irq = gpio_to_irq(gpio);
+ if (!is_out) {
+ int irq = gpio_to_irq(gpio);
struct irq_desc *desc = irq_to_desc(irq);
/* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
*/
- if (irq >= 0 && desc->action) {
+ if (irq > 0 && desc && desc->action) {
char *trigger;
u32 bitmask = nmk_gpio_get_bitmask(gpio);
data |= (3 << bit);
break;
default:
+ spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported pull setting %d\n",
pull);
return -EINVAL;
if (ctrl->type == RK3188) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
info->reg_pull = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(info->reg_base))
- return PTR_ERR(info->reg_base);
+ if (IS_ERR(info->reg_pull))
+ return PTR_ERR(info->reg_pull);
}
ret = rockchip_gpiolib_register(pdev, info);
#include "core.h"
-static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev)
+static int sh_pfc_map_resources(struct sh_pfc *pfc,
+ struct platform_device *pdev)
{
+ unsigned int num_windows = 0;
+ unsigned int num_irqs = 0;
+ struct sh_pfc_window *windows;
+ unsigned int *irqs = NULL;
struct resource *res;
- int k;
+ unsigned int i;
+
+ /* Count the MEM and IRQ resources. */
+ for (i = 0; i < pdev->num_resources; ++i) {
+ switch (resource_type(&pdev->resource[i])) {
+ case IORESOURCE_MEM:
+ num_windows++;
+ break;
+
+ case IORESOURCE_IRQ:
+ num_irqs++;
+ break;
+ }
+ }
- if (pdev->num_resources == 0)
+ if (num_windows == 0)
return -EINVAL;
- pfc->window = devm_kzalloc(pfc->dev, pdev->num_resources *
- sizeof(*pfc->window), GFP_NOWAIT);
- if (!pfc->window)
+ /* Allocate memory windows and IRQs arrays. */
+ windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
+ GFP_KERNEL);
+ if (windows == NULL)
return -ENOMEM;
- pfc->num_windows = pdev->num_resources;
+ pfc->num_windows = num_windows;
+ pfc->windows = windows;
- for (k = 0, res = pdev->resource; k < pdev->num_resources; k++, res++) {
- WARN_ON(resource_type(res) != IORESOURCE_MEM);
- pfc->window[k].phys = res->start;
- pfc->window[k].size = resource_size(res);
- pfc->window[k].virt = devm_ioremap_nocache(pfc->dev, res->start,
- resource_size(res));
- if (!pfc->window[k].virt)
+ if (num_irqs) {
+ irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
+ GFP_KERNEL);
+ if (irqs == NULL)
return -ENOMEM;
+
+ pfc->num_irqs = num_irqs;
+ pfc->irqs = irqs;
+ }
+
+ /* Fill them. */
+ for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) {
+ switch (resource_type(res)) {
+ case IORESOURCE_MEM:
+ windows->phys = res->start;
+ windows->size = resource_size(res);
+ windows->virt = devm_ioremap_resource(pfc->dev, res);
+ if (IS_ERR(windows->virt))
+ return -ENOMEM;
+ windows++;
+ break;
+
+ case IORESOURCE_IRQ:
+ *irqs++ = res->start;
+ break;
+ }
}
return 0;
/* scan through physical windows and convert address */
for (i = 0; i < pfc->num_windows; i++) {
- window = pfc->window + i;
+ window = pfc->windows + i;
if (address < window->phys)
continue;
unsigned long *maskp,
unsigned long *posp)
{
- int k;
+ unsigned int k;
*mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
{
const struct pinmux_cfg_reg *config_reg;
unsigned long r_width, f_width, curr_width, ncomb;
- int k, m, n, pos, bit_pos;
+ unsigned int k, m, n, pos, bit_pos;
k = 0;
while (1) {
u16 *enum_idp)
{
const u16 *data = pfc->info->gpio_data;
- int k;
+ unsigned int k;
if (pos) {
*enum_idp = data[pos + 1];
pfc->info = info;
pfc->dev = &pdev->dev;
- ret = sh_pfc_ioremap(pfc, pdev);
+ ret = sh_pfc_map_resources(pfc, pdev);
if (unlikely(ret < 0))
return ret;
spinlock_t lock;
unsigned int num_windows;
- struct sh_pfc_window *window;
+ struct sh_pfc_window *windows;
+ unsigned int num_irqs;
+ unsigned int *irqs;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct sh_pfc *pfc = gpio_to_pfc(gc);
- int i, k;
+ unsigned int i, k;
for (i = 0; i < pfc->info->gpio_irq_size; i++) {
- unsigned short *gpios = pfc->info->gpio_irq[i].gpios;
+ short *gpios = pfc->info->gpio_irq[i].gpios;
- for (k = 0; gpios[k]; k++) {
+ for (k = 0; gpios[k] >= 0; k++) {
if (gpios[k] == offset)
- return pfc->info->gpio_irq[i].irq;
+ goto found;
}
}
return -ENOSYS;
+
+found:
+ if (pfc->num_irqs)
+ return pfc->irqs[i];
+ else
+ return pfc->info->gpio_irq[i].irq;
}
static int gpio_pin_setup(struct sh_pfc_chip *chip)
* GPIOs.
*/
for (i = 0; i < pfc->num_windows; ++i) {
- struct sh_pfc_window *window = &pfc->window[i];
+ struct sh_pfc_window *window = &pfc->windows[i];
if (pfc->info->data_regs[0].reg >= window->phys &&
pfc->info->data_regs[0].reg < window->phys + window->size)
if (i == pfc->num_windows)
return 0;
+ /* If we have IRQ resources make sure their number is correct. */
+ if (pfc->num_irqs && pfc->num_irqs != pfc->info->gpio_irq_size) {
+ dev_err(pfc->dev, "invalid number of IRQ resources\n");
+ return -EINVAL;
+ }
+
/* Register the real GPIOs chip. */
- chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->window[i]);
+ chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->windows[i]);
if (IS_ERR(chip))
return PTR_ERR(chip);
SH_PFC_FUNCTION(sdhi2),
};
-#undef PORTCR
-#define PORTCR(nr, reg) \
- { \
- PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, \
- PORT##nr##_FN2, PORT##nr##_FN3, \
- PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000),
PORTCR(1, 0xe6050001),
{
void __iomem *addr;
- addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
+ addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
switch (ioread8(addr) & PORTCR_PULMD_MASK) {
case PORTCR_PULMD_UP:
void __iomem *addr;
u32 value;
- addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
+ addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
value = ioread8(addr) & ~PORTCR_PULMD_MASK;
switch (bias) {
SH_PFC_FUNCTION(tpu0),
};
-#undef PORTCR
-#define PORTCR(nr, reg) \
- { \
- PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, \
- PORT##nr##_FN2, PORT##nr##_FN3, \
- PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
const struct r8a7740_portcr_group *group =
&r8a7740_portcr_offsets[i];
- if (i <= group->end_pin)
- return pfc->window->virt + group->offset + pin;
+ if (pin <= group->end_pin)
+ return pfc->windows->virt + group->offset + pin;
}
return NULL;
SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15),
};
+/* - AUDIO CLOCK ------------------------------------------------------------ */
+static const unsigned int audio_clk_a_pins[] = {
+ /* CLK A */
+ RCAR_GP_PIN(4, 25),
+};
+static const unsigned int audio_clk_a_mux[] = {
+ AUDIO_CLKA_MARK,
+};
+static const unsigned int audio_clk_b_pins[] = {
+ /* CLK B */
+ RCAR_GP_PIN(4, 26),
+};
+static const unsigned int audio_clk_b_mux[] = {
+ AUDIO_CLKB_MARK,
+};
+static const unsigned int audio_clk_c_pins[] = {
+ /* CLK C */
+ RCAR_GP_PIN(5, 27),
+};
+static const unsigned int audio_clk_c_mux[] = {
+ AUDIO_CLKC_MARK,
+};
+static const unsigned int audio_clkout_pins[] = {
+ /* CLK OUT */
+ RCAR_GP_PIN(5, 16),
+};
+static const unsigned int audio_clkout_mux[] = {
+ AUDIO_CLKOUT_MARK,
+};
+static const unsigned int audio_clkout_b_pins[] = {
+ /* CLK OUT B */
+ RCAR_GP_PIN(0, 23),
+};
+static const unsigned int audio_clkout_b_mux[] = {
+ AUDIO_CLKOUT_B_MARK,
+};
+static const unsigned int audio_clkout_c_pins[] = {
+ /* CLK OUT C */
+ RCAR_GP_PIN(5, 27),
+};
+static const unsigned int audio_clkout_c_mux[] = {
+ AUDIO_CLKOUT_C_MARK,
+};
+static const unsigned int audio_clkout_d_pins[] = {
+ /* CLK OUT D */
+ RCAR_GP_PIN(5, 20),
+};
+static const unsigned int audio_clkout_d_mux[] = {
+ AUDIO_CLKOUT_D_MARK,
+};
/* - DU RGB ----------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
/* R[7:2], G[7:2], B[7:2] */
static const unsigned int sdhi3_wp_mux[] = {
SD3_WP_MARK,
};
+/* - SSI -------------------------------------------------------------------- */
+static const unsigned int ssi0_data_pins[] = {
+ /* SDATA0 */
+ RCAR_GP_PIN(4, 5),
+};
+static const unsigned int ssi0_data_mux[] = {
+ SSI_SDATA0_MARK,
+};
+static const unsigned int ssi0129_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 4),
+};
+static const unsigned int ssi0129_ctrl_mux[] = {
+ SSI_SCK0129_MARK, SSI_WS0129_MARK,
+};
+static const unsigned int ssi1_data_pins[] = {
+ /* SDATA1 */
+ RCAR_GP_PIN(4, 6),
+};
+static const unsigned int ssi1_data_mux[] = {
+ SSI_SDATA1_MARK,
+};
+static const unsigned int ssi1_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(4, 7), RCAR_GP_PIN(4, 24),
+};
+static const unsigned int ssi1_ctrl_mux[] = {
+ SSI_SCK1_MARK, SSI_WS1_MARK,
+};
+static const unsigned int ssi2_data_pins[] = {
+ /* SDATA2 */
+ RCAR_GP_PIN(4, 7),
+};
+static const unsigned int ssi2_data_mux[] = {
+ SSI_SDATA2_MARK,
+};
+static const unsigned int ssi2_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 17),
+};
+static const unsigned int ssi2_ctrl_mux[] = {
+ SSI_SCK2_MARK, SSI_WS2_MARK,
+};
+static const unsigned int ssi3_data_pins[] = {
+ /* SDATA3 */
+ RCAR_GP_PIN(4, 10),
+};
+static const unsigned int ssi3_data_mux[] = {
+ SSI_SDATA3_MARK
+};
+static const unsigned int ssi34_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9),
+};
+static const unsigned int ssi34_ctrl_mux[] = {
+ SSI_SCK34_MARK, SSI_WS34_MARK,
+};
+static const unsigned int ssi4_data_pins[] = {
+ /* SDATA4 */
+ RCAR_GP_PIN(4, 13),
+};
+static const unsigned int ssi4_data_mux[] = {
+ SSI_SDATA4_MARK,
+};
+static const unsigned int ssi4_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(4, 11), RCAR_GP_PIN(4, 12),
+};
+static const unsigned int ssi4_ctrl_mux[] = {
+ SSI_SCK4_MARK, SSI_WS4_MARK,
+};
+static const unsigned int ssi5_pins[] = {
+ /* SDATA5, SCK, WS */
+ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 15),
+};
+static const unsigned int ssi5_mux[] = {
+ SSI_SDATA5_MARK, SSI_SCK5_MARK, SSI_WS5_MARK,
+};
+static const unsigned int ssi5_b_pins[] = {
+ /* SDATA5, SCK, WS */
+ RCAR_GP_PIN(0, 26), RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
+};
+static const unsigned int ssi5_b_mux[] = {
+ SSI_SDATA5_B_MARK, SSI_SCK5_B_MARK, SSI_WS5_B_MARK
+};
+static const unsigned int ssi5_c_pins[] = {
+ /* SDATA5, SCK, WS */
+ RCAR_GP_PIN(4, 24), RCAR_GP_PIN(4, 11), RCAR_GP_PIN(4, 12),
+};
+static const unsigned int ssi5_c_mux[] = {
+ SSI_SDATA5_C_MARK, SSI_SCK5_C_MARK, SSI_WS5_C_MARK,
+};
+static const unsigned int ssi6_pins[] = {
+ /* SDATA6, SCK, WS */
+ RCAR_GP_PIN(4, 19), RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 18),
+};
+static const unsigned int ssi6_mux[] = {
+ SSI_SDATA6_MARK, SSI_SCK6_MARK, SSI_WS6_MARK,
+};
+static const unsigned int ssi6_b_pins[] = {
+ /* SDATA6, SCK, WS */
+ RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 25), RCAR_GP_PIN(1, 27),
+};
+static const unsigned int ssi6_b_mux[] = {
+ SSI_SDATA6_B_MARK, SSI_SCK6_B_MARK, SSI_WS6_B_MARK,
+};
+static const unsigned int ssi7_data_pins[] = {
+ /* SDATA7 */
+ RCAR_GP_PIN(4, 22),
+};
+static const unsigned int ssi7_data_mux[] = {
+ SSI_SDATA7_MARK,
+};
+static const unsigned int ssi7_b_data_pins[] = {
+ /* SDATA7 */
+ RCAR_GP_PIN(4, 22),
+};
+static const unsigned int ssi7_b_data_mux[] = {
+ SSI_SDATA7_B_MARK,
+};
+static const unsigned int ssi7_c_data_pins[] = {
+ /* SDATA7 */
+ RCAR_GP_PIN(1, 26),
+};
+static const unsigned int ssi7_c_data_mux[] = {
+ SSI_SDATA7_C_MARK,
+};
+static const unsigned int ssi78_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(4, 20), RCAR_GP_PIN(4, 21),
+};
+static const unsigned int ssi78_ctrl_mux[] = {
+ SSI_SCK78_MARK, SSI_WS78_MARK,
+};
+static const unsigned int ssi78_b_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 24),
+};
+static const unsigned int ssi78_b_ctrl_mux[] = {
+ SSI_SCK78_B_MARK, SSI_WS78_B_MARK,
+};
+static const unsigned int ssi78_c_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 25),
+};
+static const unsigned int ssi78_c_ctrl_mux[] = {
+ SSI_SCK78_C_MARK, SSI_WS78_C_MARK,
+};
+static const unsigned int ssi8_data_pins[] = {
+ /* SDATA8 */
+ RCAR_GP_PIN(4, 23),
+};
+static const unsigned int ssi8_data_mux[] = {
+ SSI_SDATA8_MARK,
+};
+static const unsigned int ssi8_b_data_pins[] = {
+ /* SDATA8 */
+ RCAR_GP_PIN(4, 23),
+};
+static const unsigned int ssi8_b_data_mux[] = {
+ SSI_SDATA8_B_MARK,
+};
+static const unsigned int ssi8_c_data_pins[] = {
+ /* SDATA8 */
+ RCAR_GP_PIN(1, 27),
+};
+static const unsigned int ssi8_c_data_mux[] = {
+ SSI_SDATA8_C_MARK,
+};
+static const unsigned int ssi9_data_pins[] = {
+ /* SDATA9 */
+ RCAR_GP_PIN(4, 24),
+};
+static const unsigned int ssi9_data_mux[] = {
+ SSI_SDATA9_MARK,
+};
+static const unsigned int ssi9_ctrl_pins[] = {
+ /* SCK, WS */
+ RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 11),
+};
+static const unsigned int ssi9_ctrl_mux[] = {
+ SSI_SCK9_MARK, SSI_WS9_MARK,
+};
/* - TPU0 ------------------------------------------------------------------- */
static const unsigned int tpu0_to0_pins[] = {
/* TO */
static const unsigned int usb2_mux[] = {
USB2_PWEN_MARK, USB2_OVC_MARK,
};
-/* - VIN0 ------------------------------------------------------------------- */
-static const unsigned int vin0_data_g_pins[] = {
- RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10),
- RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
- RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
-};
-static const unsigned int vin0_data_g_mux[] = {
- VI0_G0_MARK, VI0_G1_MARK, VI0_G2_MARK,
- VI0_G3_MARK, VI0_G4_MARK, VI0_G5_MARK,
- VI0_G6_MARK, VI0_G7_MARK,
+
+union vin_data {
+ unsigned int data24[24];
+ unsigned int data20[20];
+ unsigned int data16[16];
+ unsigned int data12[12];
+ unsigned int data10[10];
+ unsigned int data8[8];
+ unsigned int data4[4];
};
-static const unsigned int vin0_data_r_pins[] = {
- RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 6),
- RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
- RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
+
+#define VIN_DATA_PIN_GROUP(n, s) \
+ { \
+ .name = #n#s, \
+ .pins = n##_pins.data##s, \
+ .mux = n##_mux.data##s, \
+ .nr_pins = ARRAY_SIZE(n##_pins.data##s), \
+ }
+
+/* - VIN0 ------------------------------------------------------------------- */
+static const union vin_data vin0_data_pins = {
+ .data24 = {
+ /* B */
+ RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2),
+ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4),
+ RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
+ RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8),
+ /* G */
+ RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9),
+ RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+ RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
+ RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
+ /* R */
+ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
+ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
+ RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
+ RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
+ },
};
-static const unsigned int vin0_data_r_mux[] = {
- VI0_R0_MARK, VI0_R1_MARK, VI0_R2_MARK,
- VI0_R3_MARK, VI0_R4_MARK, VI0_R5_MARK,
- VI0_R6_MARK, VI0_R7_MARK,
+static const union vin_data vin0_data_mux = {
+ .data24 = {
+ /* B */
+ VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK,
+ VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK,
+ VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
+ VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK,
+ /* G */
+ VI0_G0_MARK, VI0_G1_MARK,
+ VI0_G2_MARK, VI0_G3_MARK,
+ VI0_G4_MARK, VI0_G5_MARK,
+ VI0_G6_MARK, VI0_G7_MARK,
+ /* R */
+ VI0_R0_MARK, VI0_R1_MARK,
+ VI0_R2_MARK, VI0_R3_MARK,
+ VI0_R4_MARK, VI0_R5_MARK,
+ VI0_R6_MARK, VI0_R7_MARK,
+ },
};
-static const unsigned int vin0_data_b_pins[] = {
- RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3),
- RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
+static const unsigned int vin0_data18_pins[] = {
+ /* B */
+ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4),
+ RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8),
+ /* G */
+ RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+ RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
+ RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
+ /* R */
+ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
+ RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
+ RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
};
-static const unsigned int vin0_data_b_mux[] = {
- VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK, VI0_DATA2_VI0_B2_MARK,
- VI0_DATA3_VI0_B3_MARK, VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
+static const unsigned int vin0_data18_mux[] = {
+ /* B */
+ VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK,
+ VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK,
+ /* G */
+ VI0_G2_MARK, VI0_G3_MARK,
+ VI0_G4_MARK, VI0_G5_MARK,
+ VI0_G6_MARK, VI0_G7_MARK,
+ /* R */
+ VI0_R2_MARK, VI0_R3_MARK,
+ VI0_R4_MARK, VI0_R5_MARK,
+ VI0_R6_MARK, VI0_R7_MARK,
};
-static const unsigned int vin0_hsync_signal_pins[] = {
- RCAR_GP_PIN(0, 12),
+static const unsigned int vin0_sync_pins[] = {
+ RCAR_GP_PIN(0, 12), /* HSYNC */
+ RCAR_GP_PIN(0, 13), /* VSYNC */
};
-static const unsigned int vin0_hsync_signal_mux[] = {
+static const unsigned int vin0_sync_mux[] = {
VI0_HSYNC_N_MARK,
-};
-static const unsigned int vin0_vsync_signal_pins[] = {
- RCAR_GP_PIN(0, 13),
-};
-static const unsigned int vin0_vsync_signal_mux[] = {
VI0_VSYNC_N_MARK,
};
-static const unsigned int vin0_field_signal_pins[] = {
+static const unsigned int vin0_field_pins[] = {
RCAR_GP_PIN(0, 15),
};
-static const unsigned int vin0_field_signal_mux[] = {
+static const unsigned int vin0_field_mux[] = {
VI0_FIELD_MARK,
};
-static const unsigned int vin0_data_enable_pins[] = {
+static const unsigned int vin0_clkenb_pins[] = {
RCAR_GP_PIN(0, 14),
};
-static const unsigned int vin0_data_enable_mux[] = {
+static const unsigned int vin0_clkenb_mux[] = {
VI0_CLKENB_MARK,
};
static const unsigned int vin0_clk_pins[] = {
VI0_CLK_MARK,
};
/* - VIN1 ------------------------------------------------------------------- */
-static const unsigned int vin1_data_pins[] = {
- RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12),
- RCAR_GP_PIN(2, 13), RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
- RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
+static const union vin_data vin1_data_pins = {
+ .data24 = {
+ /* B */
+ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
+ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
+ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
+ /* G */
+ RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
+ RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 12),
+ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 7),
+ /* R */
+ RCAR_GP_PIN(0, 27), RCAR_GP_PIN(0, 28),
+ RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 4),
+ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
+ RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 8),
+ },
};
-static const unsigned int vin1_data_mux[] = {
- VI1_DATA0_VI1_B0_MARK, VI1_DATA1_VI1_B1_MARK, VI1_DATA2_VI1_B2_MARK,
- VI1_DATA3_VI1_B3_MARK, VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
+static const union vin_data vin1_data_mux = {
+ .data24 = {
+ /* B */
+ VI1_DATA0_VI1_B0_MARK, VI1_DATA1_VI1_B1_MARK,
+ VI1_DATA2_VI1_B2_MARK, VI1_DATA3_VI1_B3_MARK,
+ VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
+ VI1_DATA6_VI1_B6_MARK, VI1_DATA7_VI1_B7_MARK,
+ /* G */
+ VI1_G0_MARK, VI1_G1_MARK,
+ VI1_G2_MARK, VI1_G3_MARK,
+ VI1_G4_MARK, VI1_G5_MARK,
+ VI1_G6_MARK, VI1_G7_MARK,
+ /* R */
+ VI1_R0_MARK, VI1_R1_MARK,
+ VI1_R2_MARK, VI1_R3_MARK,
+ VI1_R4_MARK, VI1_R5_MARK,
+ VI1_R6_MARK, VI1_R7_MARK,
+ },
+};
+static const unsigned int vin1_data18_pins[] = {
+ /* B */
+ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
+ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
+ /* G */
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
+ RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 12),
+ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 7),
+ /* R */
+ RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 4),
+ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
+ RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 8),
+};
+static const unsigned int vin1_data18_mux[] = {
+ /* B */
+ VI1_DATA2_VI1_B2_MARK, VI1_DATA3_VI1_B3_MARK,
+ VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
VI1_DATA6_VI1_B6_MARK, VI1_DATA7_VI1_B7_MARK,
+ /* G */
+ VI1_G2_MARK, VI1_G3_MARK,
+ VI1_G4_MARK, VI1_G5_MARK,
+ VI1_G6_MARK, VI1_G7_MARK,
+ /* R */
+ VI1_R2_MARK, VI1_R3_MARK,
+ VI1_R4_MARK, VI1_R5_MARK,
+ VI1_R6_MARK, VI1_R7_MARK,
+};
+static const unsigned int vin1_sync_pins[] = {
+ RCAR_GP_PIN(1, 24), /* HSYNC */
+ RCAR_GP_PIN(1, 25), /* VSYNC */
+};
+static const unsigned int vin1_sync_mux[] = {
+ VI1_HSYNC_N_MARK,
+ VI1_VSYNC_N_MARK,
+};
+static const unsigned int vin1_field_pins[] = {
+ RCAR_GP_PIN(1, 13),
+};
+static const unsigned int vin1_field_mux[] = {
+ VI1_FIELD_MARK,
+};
+static const unsigned int vin1_clkenb_pins[] = {
+ RCAR_GP_PIN(1, 26),
+};
+static const unsigned int vin1_clkenb_mux[] = {
+ VI1_CLKENB_MARK,
};
static const unsigned int vin1_clk_pins[] = {
RCAR_GP_PIN(2, 9),
static const unsigned int vin1_clk_mux[] = {
VI1_CLK_MARK,
};
+/* - VIN2 ----------------------------------------------------------------- */
+static const union vin_data vin2_data_pins = {
+ .data24 = {
+ /* B */
+ RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9),
+ RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+ RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13),
+ RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
+ /* G */
+ RCAR_GP_PIN(0, 27), RCAR_GP_PIN(0, 28),
+ RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 10),
+ RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5),
+ RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
+ /* R */
+ RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13),
+ RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
+ RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 24),
+ },
+};
+static const union vin_data vin2_data_mux = {
+ .data24 = {
+ /* B */
+ VI2_DATA0_VI2_B0_MARK, VI2_DATA1_VI2_B1_MARK,
+ VI2_DATA2_VI2_B2_MARK, VI2_DATA3_VI2_B3_MARK,
+ VI2_DATA4_VI2_B4_MARK, VI2_DATA5_VI2_B5_MARK,
+ VI2_DATA6_VI2_B6_MARK, VI2_DATA7_VI2_B7_MARK,
+ /* G */
+ VI2_G0_MARK, VI2_G1_MARK,
+ VI2_G2_MARK, VI2_G3_MARK,
+ VI2_G4_MARK, VI2_G5_MARK,
+ VI2_G6_MARK, VI2_G7_MARK,
+ /* R */
+ VI2_R0_MARK, VI2_R1_MARK,
+ VI2_R2_MARK, VI2_R3_MARK,
+ VI2_R4_MARK, VI2_R5_MARK,
+ VI2_R6_MARK, VI2_R7_MARK,
+ },
+};
+static const unsigned int vin2_data18_pins[] = {
+ /* B */
+ RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+ RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13),
+ RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
+ /* G */
+ RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 10),
+ RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5),
+ RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
+ /* R */
+ RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
+ RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 24),
+};
+static const unsigned int vin2_data18_mux[] = {
+ /* B */
+ VI2_DATA2_VI2_B2_MARK, VI2_DATA3_VI2_B3_MARK,
+ VI2_DATA4_VI2_B4_MARK, VI2_DATA5_VI2_B5_MARK,
+ VI2_DATA6_VI2_B6_MARK, VI2_DATA7_VI2_B7_MARK,
+ /* G */
+ VI2_G2_MARK, VI2_G3_MARK,
+ VI2_G4_MARK, VI2_G5_MARK,
+ VI2_G6_MARK, VI2_G7_MARK,
+ /* R */
+ VI2_R2_MARK, VI2_R3_MARK,
+ VI2_R4_MARK, VI2_R5_MARK,
+ VI2_R6_MARK, VI2_R7_MARK,
+};
+static const unsigned int vin2_sync_pins[] = {
+ RCAR_GP_PIN(1, 16), /* HSYNC */
+ RCAR_GP_PIN(1, 21), /* VSYNC */
+};
+static const unsigned int vin2_sync_mux[] = {
+ VI2_HSYNC_N_MARK,
+ VI2_VSYNC_N_MARK,
+};
+static const unsigned int vin2_field_pins[] = {
+ RCAR_GP_PIN(1, 9),
+};
+static const unsigned int vin2_field_mux[] = {
+ VI2_FIELD_MARK,
+};
+static const unsigned int vin2_clkenb_pins[] = {
+ RCAR_GP_PIN(1, 8),
+};
+static const unsigned int vin2_clkenb_mux[] = {
+ VI2_CLKENB_MARK,
+};
+static const unsigned int vin2_clk_pins[] = {
+ RCAR_GP_PIN(1, 11),
+};
+static const unsigned int vin2_clk_mux[] = {
+ VI2_CLK_MARK,
+};
+/* - VIN3 ----------------------------------------------------------------- */
+static const unsigned int vin3_data8_pins[] = {
+ RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
+ RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
+ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
+ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
+};
+static const unsigned int vin3_data8_mux[] = {
+ VI3_DATA0_MARK, VI3_DATA1_MARK,
+ VI3_DATA2_MARK, VI3_DATA3_MARK,
+ VI3_DATA4_MARK, VI3_DATA5_MARK,
+ VI3_DATA6_MARK, VI3_DATA7_MARK,
+};
+static const unsigned int vin3_sync_pins[] = {
+ RCAR_GP_PIN(1, 16), /* HSYNC */
+ RCAR_GP_PIN(1, 17), /* VSYNC */
+};
+static const unsigned int vin3_sync_mux[] = {
+ VI3_HSYNC_N_MARK,
+ VI2_VSYNC_N_MARK,
+};
+static const unsigned int vin3_field_pins[] = {
+ RCAR_GP_PIN(1, 15),
+};
+static const unsigned int vin3_field_mux[] = {
+ VI3_FIELD_MARK,
+};
+static const unsigned int vin3_clkenb_pins[] = {
+ RCAR_GP_PIN(1, 14),
+};
+static const unsigned int vin3_clkenb_mux[] = {
+ VI3_CLKENB_MARK,
+};
+static const unsigned int vin3_clk_pins[] = {
+ RCAR_GP_PIN(1, 23),
+};
+static const unsigned int vin3_clk_mux[] = {
+ VI3_CLK_MARK,
+};
static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(audio_clk_a),
+ SH_PFC_PIN_GROUP(audio_clk_b),
+ SH_PFC_PIN_GROUP(audio_clk_c),
+ SH_PFC_PIN_GROUP(audio_clkout),
+ SH_PFC_PIN_GROUP(audio_clkout_b),
+ SH_PFC_PIN_GROUP(audio_clkout_c),
+ SH_PFC_PIN_GROUP(audio_clkout_d),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
SH_PFC_PIN_GROUP(sdhi3_ctrl),
SH_PFC_PIN_GROUP(sdhi3_cd),
SH_PFC_PIN_GROUP(sdhi3_wp),
+ SH_PFC_PIN_GROUP(ssi0_data),
+ SH_PFC_PIN_GROUP(ssi0129_ctrl),
+ SH_PFC_PIN_GROUP(ssi1_data),
+ SH_PFC_PIN_GROUP(ssi1_ctrl),
+ SH_PFC_PIN_GROUP(ssi2_data),
+ SH_PFC_PIN_GROUP(ssi2_ctrl),
+ SH_PFC_PIN_GROUP(ssi3_data),
+ SH_PFC_PIN_GROUP(ssi34_ctrl),
+ SH_PFC_PIN_GROUP(ssi4_data),
+ SH_PFC_PIN_GROUP(ssi4_ctrl),
+ SH_PFC_PIN_GROUP(ssi5),
+ SH_PFC_PIN_GROUP(ssi5_b),
+ SH_PFC_PIN_GROUP(ssi5_c),
+ SH_PFC_PIN_GROUP(ssi6),
+ SH_PFC_PIN_GROUP(ssi6_b),
+ SH_PFC_PIN_GROUP(ssi7_data),
+ SH_PFC_PIN_GROUP(ssi7_b_data),
+ SH_PFC_PIN_GROUP(ssi7_c_data),
+ SH_PFC_PIN_GROUP(ssi78_ctrl),
+ SH_PFC_PIN_GROUP(ssi78_b_ctrl),
+ SH_PFC_PIN_GROUP(ssi78_c_ctrl),
+ SH_PFC_PIN_GROUP(ssi8_data),
+ SH_PFC_PIN_GROUP(ssi8_b_data),
+ SH_PFC_PIN_GROUP(ssi8_c_data),
+ SH_PFC_PIN_GROUP(ssi9_data),
+ SH_PFC_PIN_GROUP(ssi9_ctrl),
SH_PFC_PIN_GROUP(tpu0_to0),
SH_PFC_PIN_GROUP(tpu0_to1),
SH_PFC_PIN_GROUP(tpu0_to2),
SH_PFC_PIN_GROUP(usb0),
SH_PFC_PIN_GROUP(usb1),
SH_PFC_PIN_GROUP(usb2),
- SH_PFC_PIN_GROUP(vin0_data_g),
- SH_PFC_PIN_GROUP(vin0_data_r),
- SH_PFC_PIN_GROUP(vin0_data_b),
- SH_PFC_PIN_GROUP(vin0_hsync_signal),
- SH_PFC_PIN_GROUP(vin0_vsync_signal),
- SH_PFC_PIN_GROUP(vin0_field_signal),
- SH_PFC_PIN_GROUP(vin0_data_enable),
+ VIN_DATA_PIN_GROUP(vin0_data, 24),
+ VIN_DATA_PIN_GROUP(vin0_data, 20),
+ SH_PFC_PIN_GROUP(vin0_data18),
+ VIN_DATA_PIN_GROUP(vin0_data, 16),
+ VIN_DATA_PIN_GROUP(vin0_data, 12),
+ VIN_DATA_PIN_GROUP(vin0_data, 10),
+ VIN_DATA_PIN_GROUP(vin0_data, 8),
+ VIN_DATA_PIN_GROUP(vin0_data, 4),
+ SH_PFC_PIN_GROUP(vin0_sync),
+ SH_PFC_PIN_GROUP(vin0_field),
+ SH_PFC_PIN_GROUP(vin0_clkenb),
SH_PFC_PIN_GROUP(vin0_clk),
- SH_PFC_PIN_GROUP(vin1_data),
+ VIN_DATA_PIN_GROUP(vin1_data, 24),
+ VIN_DATA_PIN_GROUP(vin1_data, 20),
+ SH_PFC_PIN_GROUP(vin1_data18),
+ VIN_DATA_PIN_GROUP(vin1_data, 16),
+ VIN_DATA_PIN_GROUP(vin1_data, 12),
+ VIN_DATA_PIN_GROUP(vin1_data, 10),
+ VIN_DATA_PIN_GROUP(vin1_data, 8),
+ VIN_DATA_PIN_GROUP(vin1_data, 4),
+ SH_PFC_PIN_GROUP(vin1_sync),
+ SH_PFC_PIN_GROUP(vin1_field),
+ SH_PFC_PIN_GROUP(vin1_clkenb),
SH_PFC_PIN_GROUP(vin1_clk),
+ VIN_DATA_PIN_GROUP(vin2_data, 24),
+ SH_PFC_PIN_GROUP(vin2_data18),
+ VIN_DATA_PIN_GROUP(vin2_data, 16),
+ VIN_DATA_PIN_GROUP(vin2_data, 8),
+ VIN_DATA_PIN_GROUP(vin2_data, 4),
+ SH_PFC_PIN_GROUP(vin2_sync),
+ SH_PFC_PIN_GROUP(vin2_field),
+ SH_PFC_PIN_GROUP(vin2_clkenb),
+ SH_PFC_PIN_GROUP(vin2_clk),
+ SH_PFC_PIN_GROUP(vin3_data8),
+ SH_PFC_PIN_GROUP(vin3_sync),
+ SH_PFC_PIN_GROUP(vin3_field),
+ SH_PFC_PIN_GROUP(vin3_clkenb),
+ SH_PFC_PIN_GROUP(vin3_clk),
+};
+
+static const char * const audio_clk_groups[] = {
+ "audio_clk_a",
+ "audio_clk_b",
+ "audio_clk_c",
+ "audio_clkout",
+ "audio_clkout_b",
+ "audio_clkout_c",
+ "audio_clkout_d",
};
static const char * const du_groups[] = {
"sdhi3_wp",
};
+static const char * const ssi_groups[] = {
+ "ssi0_data",
+ "ssi0129_ctrl",
+ "ssi1_data",
+ "ssi1_ctrl",
+ "ssi2_data",
+ "ssi2_ctrl",
+ "ssi3_data",
+ "ssi34_ctrl",
+ "ssi4_data",
+ "ssi4_ctrl",
+ "ssi5",
+ "ssi5_b",
+ "ssi5_c",
+ "ssi6",
+ "ssi6_b",
+ "ssi7_data",
+ "ssi7_b_data",
+ "ssi7_c_data",
+ "ssi78_ctrl",
+ "ssi78_b_ctrl",
+ "ssi78_c_ctrl",
+ "ssi8_data",
+ "ssi8_b_data",
+ "ssi8_c_data",
+ "ssi9_data",
+ "ssi9_ctrl",
+};
+
static const char * const tpu0_groups[] = {
"tpu0_to0",
"tpu0_to1",
};
static const char * const vin0_groups[] = {
- "vin0_data_g",
- "vin0_data_r",
- "vin0_data_b",
- "vin0_hsync_signal",
- "vin0_vsync_signal",
- "vin0_field_signal",
- "vin0_data_enable",
+ "vin0_data24",
+ "vin0_data20",
+ "vin0_data18",
+ "vin0_data16",
+ "vin0_data12",
+ "vin0_data10",
+ "vin0_data8",
+ "vin0_data4",
+ "vin0_sync",
+ "vin0_field",
+ "vin0_clkenb",
"vin0_clk",
};
static const char * const vin1_groups[] = {
- "vin1_data",
+ "vin1_data24",
+ "vin1_data20",
+ "vin1_data18",
+ "vin1_data16",
+ "vin1_data12",
+ "vin1_data10",
+ "vin1_data8",
+ "vin1_data4",
+ "vin1_sync",
+ "vin1_field",
+ "vin1_clkenb",
"vin1_clk",
};
+static const char * const vin2_groups[] = {
+ "vin2_data24",
+ "vin2_data18",
+ "vin2_data16",
+ "vin2_data8",
+ "vin2_data4",
+ "vin2_sync",
+ "vin2_field",
+ "vin2_clkenb",
+ "vin2_clk",
+};
+
+static const char * const vin3_groups[] = {
+ "vin3_data8",
+ "vin3_sync",
+ "vin3_field",
+ "vin3_clkenb",
+ "vin3_clk",
+};
+
static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1),
SH_PFC_FUNCTION(sdhi1),
SH_PFC_FUNCTION(sdhi2),
SH_PFC_FUNCTION(sdhi3),
+ SH_PFC_FUNCTION(ssi),
SH_PFC_FUNCTION(tpu0),
SH_PFC_FUNCTION(usb0),
SH_PFC_FUNCTION(usb1),
SH_PFC_FUNCTION(usb2),
SH_PFC_FUNCTION(vin0),
SH_PFC_FUNCTION(vin1),
+ SH_PFC_FUNCTION(vin2),
+ SH_PFC_FUNCTION(vin3),
};
static struct pinmux_cfg_reg pinmux_config_regs[] = {
static const unsigned int du_clk_out_1_mux[] = {
DU1_DOTCLKOUT1_MARK
};
-static const unsigned int du_sync_1_pins[] = {
+static const unsigned int du_sync_pins[] = {
/* EXVSYNC/VSYNC, EXHSYNC/HSYNC, EXDISP/EXODDF/EXCDE */
RCAR_GP_PIN(3, 29), RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 27),
};
-static const unsigned int du_sync_1_mux[] = {
+static const unsigned int du_sync_mux[] = {
DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK,
DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK
};
/* CDE DISP */
RCAR_GP_PIN(3, 31), RCAR_GP_PIN(3, 30),
};
+static const unsigned int du_cde_disp_mux[] = {
+ DU1_CDE_MARK, DU1_DISP_MARK
+};
static const unsigned int du0_clk_in_pins[] = {
/* CLKIN */
RCAR_GP_PIN(6, 31),
static const unsigned int du0_clk_in_mux[] = {
DU0_DOTCLKIN_MARK
};
-static const unsigned int du_cde_disp_mux[] = {
- DU1_CDE_MARK, DU1_DISP_MARK
-};
static const unsigned int du1_clk_in_pins[] = {
/* CLKIN */
- RCAR_GP_PIN(7, 20), RCAR_GP_PIN(7, 19), RCAR_GP_PIN(3, 24),
+ RCAR_GP_PIN(3, 24),
};
static const unsigned int du1_clk_in_mux[] = {
- DU1_DOTCLKIN_C_MARK, DU1_DOTCLKIN_B_MARK, DU1_DOTCLKIN_MARK
+ DU1_DOTCLKIN_MARK
+};
+static const unsigned int du1_clk_in_b_pins[] = {
+ /* CLKIN */
+ RCAR_GP_PIN(7, 19),
+};
+static const unsigned int du1_clk_in_b_mux[] = {
+ DU1_DOTCLKIN_B_MARK,
+};
+static const unsigned int du1_clk_in_c_pins[] = {
+ /* CLKIN */
+ RCAR_GP_PIN(7, 20),
+};
+static const unsigned int du1_clk_in_c_mux[] = {
+ DU1_DOTCLKIN_C_MARK,
};
/* - ETH -------------------------------------------------------------------- */
static const unsigned int eth_link_pins[] = {
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
SH_PFC_PIN_GROUP(du_clk_out_1),
- SH_PFC_PIN_GROUP(du_sync_1),
+ SH_PFC_PIN_GROUP(du_sync),
SH_PFC_PIN_GROUP(du_cde_disp),
SH_PFC_PIN_GROUP(du0_clk_in),
SH_PFC_PIN_GROUP(du1_clk_in),
+ SH_PFC_PIN_GROUP(du1_clk_in_b),
+ SH_PFC_PIN_GROUP(du1_clk_in_c),
SH_PFC_PIN_GROUP(eth_link),
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
"du_rgb888",
"du_clk_out_0",
"du_clk_out_1",
- "du_sync_1",
+ "du_sync",
"du_cde_disp",
};
static const char * const du1_groups[] = {
"du1_clk_in",
+ "du1_clk_in_b",
+ "du1_clk_in_c",
};
static const char * const eth_groups[] = {
static const char * const msiof0_groups[] = {
"msiof0_clk",
- "msiof0_ctrl",
- "msiof0_data",
+ "msiof0_sync",
+ "msiof0_ss1",
+ "msiof0_ss2",
+ "msiof0_rx",
+ "msiof0_tx",
};
static const char * const msiof1_groups[] = {
"msiof1_clk",
- "msiof1_ctrl",
- "msiof1_data",
+ "msiof1_sync",
+ "msiof1_ss1",
+ "msiof1_ss2",
+ "msiof1_rx",
+ "msiof1_tx",
};
static const char * const msiof2_groups[] = {
"msiof2_clk",
- "msiof2_ctrl",
- "msiof2_data",
+ "msiof2_sync",
+ "msiof2_ss1",
+ "msiof2_ss2",
+ "msiof2_rx",
+ "msiof2_tx",
};
static const char * const scif0_groups[] = {
SH_PFC_FUNCTION(usb1),
};
-#undef PORTCR
-#define PORTCR(nr, reg) \
- { \
- PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, \
- PORT##nr##_FN2, PORT##nr##_FN3, \
- PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
-
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xE6051000), /* PORT0CR */
PORTCR(1, 0xE6051001), /* PORT1CR */
const struct sh7372_portcr_group *group =
&sh7372_portcr_offsets[i];
- if (i <= group->end_pin)
- return pfc->window->virt + group->offset + pin;
+ if (pin <= group->end_pin)
+ return pfc->windows->virt + group->offset + pin;
}
return NULL;
SH_PFC_FUNCTION(usb),
};
-#undef PORTCR
-#define PORTCR(nr, reg) \
- { \
- PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
- PORT##nr##_FN0, PORT##nr##_FN1, \
- PORT##nr##_FN2, PORT##nr##_FN3, \
- PORT##nr##_FN4, PORT##nr##_FN5, \
- PORT##nr##_FN6, PORT##nr##_FN7 } \
- }
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
};
static const struct pinmux_irq pinmux_irqs[] = {
- PINMUX_IRQ(irq_pin(19), 9),
- PINMUX_IRQ(irq_pin(1), 10),
PINMUX_IRQ(irq_pin(0), 11),
+ PINMUX_IRQ(irq_pin(1), 10),
+ PINMUX_IRQ(irq_pin(2), 149),
+ PINMUX_IRQ(irq_pin(3), 224),
+ PINMUX_IRQ(irq_pin(4), 159),
+ PINMUX_IRQ(irq_pin(5), 227),
+ PINMUX_IRQ(irq_pin(6), 147),
+ PINMUX_IRQ(irq_pin(7), 150),
+ PINMUX_IRQ(irq_pin(8), 223),
+ PINMUX_IRQ(irq_pin(9), 56, 308),
+ PINMUX_IRQ(irq_pin(10), 54),
+ PINMUX_IRQ(irq_pin(11), 238),
+ PINMUX_IRQ(irq_pin(12), 156),
+ PINMUX_IRQ(irq_pin(13), 239),
+ PINMUX_IRQ(irq_pin(14), 251),
+ PINMUX_IRQ(irq_pin(15), 0),
+ PINMUX_IRQ(irq_pin(16), 249),
+ PINMUX_IRQ(irq_pin(17), 234),
PINMUX_IRQ(irq_pin(18), 13),
+ PINMUX_IRQ(irq_pin(19), 9),
PINMUX_IRQ(irq_pin(20), 14),
PINMUX_IRQ(irq_pin(21), 15),
- PINMUX_IRQ(irq_pin(31), 26),
- PINMUX_IRQ(irq_pin(30), 27),
- PINMUX_IRQ(irq_pin(29), 28),
PINMUX_IRQ(irq_pin(22), 40),
PINMUX_IRQ(irq_pin(23), 53),
- PINMUX_IRQ(irq_pin(10), 54),
- PINMUX_IRQ(irq_pin(9), 56),
+ PINMUX_IRQ(irq_pin(24), 118),
+ PINMUX_IRQ(irq_pin(25), 164),
PINMUX_IRQ(irq_pin(26), 115),
PINMUX_IRQ(irq_pin(27), 116),
PINMUX_IRQ(irq_pin(28), 117),
- PINMUX_IRQ(irq_pin(24), 118),
- PINMUX_IRQ(irq_pin(6), 147),
- PINMUX_IRQ(irq_pin(2), 149),
- PINMUX_IRQ(irq_pin(7), 150),
- PINMUX_IRQ(irq_pin(12), 156),
- PINMUX_IRQ(irq_pin(4), 159),
- PINMUX_IRQ(irq_pin(25), 164),
- PINMUX_IRQ(irq_pin(8), 223),
- PINMUX_IRQ(irq_pin(3), 224),
- PINMUX_IRQ(irq_pin(5), 227),
- PINMUX_IRQ(irq_pin(17), 234),
- PINMUX_IRQ(irq_pin(11), 238),
- PINMUX_IRQ(irq_pin(13), 239),
- PINMUX_IRQ(irq_pin(16), 249),
- PINMUX_IRQ(irq_pin(14), 251),
- PINMUX_IRQ(irq_pin(9), 308),
+ PINMUX_IRQ(irq_pin(29), 28),
+ PINMUX_IRQ(irq_pin(30), 27),
+ PINMUX_IRQ(irq_pin(31), 26),
};
/* -----------------------------------------------------------------------------
static void sh73a0_vccq_mc0_endisable(struct regulator_dev *reg, bool enable)
{
struct sh_pfc *pfc = reg->reg_data;
- void __iomem *addr = pfc->window[1].virt + 4;
+ void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
static int sh73a0_vccq_mc0_is_enabled(struct regulator_dev *reg)
{
struct sh_pfc *pfc = reg->reg_data;
- void __iomem *addr = pfc->window[1].virt + 4;
+ void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
{
- void __iomem *addr = pfc->window->virt
+ void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & PORTnCR_PULMD_MASK;
static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias)
{
- void __iomem *addr = pfc->window->virt
+ void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK;
struct pinmux_irq {
int irq;
- unsigned short *gpios;
+ short *gpios;
};
#define PINMUX_IRQ(irq_nr, ids...) \
- { .irq = irq_nr, .gpios = (unsigned short []) { ids, 0 } } \
+ { .irq = irq_nr, .gpios = (short []) { ids, -1 } }
struct pinmux_range {
u16 begin;
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
- _PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
- PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
source "drivers/platform/goldfish/Kconfig"
endif
+source "drivers/platform/chrome/Kconfig"
obj-$(CONFIG_X86) += x86/
obj-$(CONFIG_OLPC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/
+obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
--- /dev/null
+#
+# Platform support for Chrome OS hardware (Chromebooks and Chromeboxes)
+#
+
+menuconfig CHROME_PLATFORMS
+ bool "Platform support for Chrome hardware"
+ depends on X86
+ ---help---
+ Say Y here to get to see options for platform support for
+ various Chromebooks and Chromeboxes. This option alone does
+ not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if CHROME_PLATFORMS
+
+config CHROMEOS_LAPTOP
+ tristate "Chrome OS Laptop"
+ depends on I2C
+ depends on DMI
+ ---help---
+ This driver instantiates i2c and smbus devices such as
+ light sensors and touchpads.
+
+ If you have a supported Chromebook, choose Y or M here.
+ The module will be called chromeos_laptop.
+
+endif # CHROMEOS_PLATFORMS
--- /dev/null
+
+obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
If you have an ACPI-compatible ASUS laptop, say Y or M here.
-config CHROMEOS_LAPTOP
- tristate "Chrome OS Laptop"
- depends on I2C
- depends on DMI
- ---help---
- This driver instantiates i2c and smbus devices such as
- light sensors and touchpads.
-
- If you have a supported Chromebook, choose Y or M here.
- The module will be called chromeos_laptop.
-
config DELL_LAPTOP
tristate "Dell Laptop Extras"
depends on X86
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
-obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
obj-$(CONFIG_INTEL_RST) += intel-rst.o
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
int error;
input = input_allocate_device();
- if (!input) {
- pr_warn("Unable to allocate input device\n");
+ if (!input)
return -ENOMEM;
- }
+
input->name = "Asus Laptop extra buttons";
input->phys = ASUS_LAPTOP_FILE "/input0";
input->id.bustype = BUS_HOST;
#include <linux/err.h>
#include <linux/dmi.h>
#include <linux/io.h>
+#include <linux/rfkill.h>
#include <linux/power_supply.h>
#include <linux/acpi.h>
#include <linux/mm.h>
static struct platform_device *platform_device;
static struct backlight_device *dell_backlight_device;
+static struct rfkill *wifi_rfkill;
+static struct rfkill *bluetooth_rfkill;
+static struct rfkill *wwan_rfkill;
+static bool force_rfkill;
+
+module_param(force_rfkill, bool, 0444);
+MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
static const struct dmi_system_id dell_device_table[] __initconst = {
{
return buffer;
}
+/* Derived from information in DellWirelessCtl.cpp:
+ Class 17, select 11 is radio control. It returns an array of 32-bit values.
+
+ Input byte 0 = 0: Wireless information
+
+ result[0]: return code
+ result[1]:
+ Bit 0: Hardware switch supported
+ Bit 1: Wifi locator supported
+ Bit 2: Wifi is supported
+ Bit 3: Bluetooth is supported
+ Bit 4: WWAN is supported
+ Bit 5: Wireless keyboard supported
+ Bits 6-7: Reserved
+ Bit 8: Wifi is installed
+ Bit 9: Bluetooth is installed
+ Bit 10: WWAN is installed
+ Bits 11-15: Reserved
+ Bit 16: Hardware switch is on
+ Bit 17: Wifi is blocked
+ Bit 18: Bluetooth is blocked
+ Bit 19: WWAN is blocked
+ Bits 20-31: Reserved
+ result[2]: NVRAM size in bytes
+ result[3]: NVRAM format version number
+
+ Input byte 0 = 2: Wireless switch configuration
+ result[0]: return code
+ result[1]:
+ Bit 0: Wifi controlled by switch
+ Bit 1: Bluetooth controlled by switch
+ Bit 2: WWAN controlled by switch
+ Bits 3-6: Reserved
+ Bit 7: Wireless switch config locked
+ Bit 8: Wifi locator enabled
+ Bits 9-14: Reserved
+ Bit 15: Wifi locator setting locked
+ Bits 16-31: Reserved
+*/
+
+static int dell_rfkill_set(void *data, bool blocked)
+{
+ int disable = blocked ? 1 : 0;
+ unsigned long radio = (unsigned long)data;
+ int hwswitch_bit = (unsigned long)data - 1;
+
+ get_buffer();
+ dell_send_request(buffer, 17, 11);
+
+ /* If the hardware switch controls this radio, and the hardware
+ switch is disabled, always disable the radio */
+ if ((hwswitch_state & BIT(hwswitch_bit)) &&
+ !(buffer->output[1] & BIT(16)))
+ disable = 1;
+
+ buffer->input[0] = (1 | (radio<<8) | (disable << 16));
+ dell_send_request(buffer, 17, 11);
+
+ release_buffer();
+ return 0;
+}
+
+/* Must be called with the buffer held */
+static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
+ int status)
+{
+ if (status & BIT(0)) {
+ /* Has hw-switch, sync sw_state to BIOS */
+ int block = rfkill_blocked(rfkill);
+ buffer->input[0] = (1 | (radio << 8) | (block << 16));
+ dell_send_request(buffer, 17, 11);
+ } else {
+ /* No hw-switch, sync BIOS state to sw_state */
+ rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
+ }
+}
+
+static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
+ int status)
+{
+ if (hwswitch_state & (BIT(radio - 1)))
+ rfkill_set_hw_state(rfkill, !(status & BIT(16)));
+}
+
+static void dell_rfkill_query(struct rfkill *rfkill, void *data)
+{
+ int status;
+
+ get_buffer();
+ dell_send_request(buffer, 17, 11);
+ status = buffer->output[1];
+
+ dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status);
+
+ release_buffer();
+}
+
+static const struct rfkill_ops dell_rfkill_ops = {
+ .set_block = dell_rfkill_set,
+ .query = dell_rfkill_query,
+};
+
static struct dentry *dell_laptop_dir;
static int dell_debugfs_show(struct seq_file *s, void *data)
.release = single_release,
};
+static void dell_update_rfkill(struct work_struct *ignored)
+{
+ int status;
+
+ get_buffer();
+ dell_send_request(buffer, 17, 11);
+ status = buffer->output[1];
+
+ if (wifi_rfkill) {
+ dell_rfkill_update_hw_state(wifi_rfkill, 1, status);
+ dell_rfkill_update_sw_state(wifi_rfkill, 1, status);
+ }
+ if (bluetooth_rfkill) {
+ dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status);
+ dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status);
+ }
+ if (wwan_rfkill) {
+ dell_rfkill_update_hw_state(wwan_rfkill, 3, status);
+ dell_rfkill_update_sw_state(wwan_rfkill, 3, status);
+ }
+
+ release_buffer();
+}
+static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
+
+
+static int __init dell_setup_rfkill(void)
+{
+ int status;
+ int ret;
+ const char *product;
+
+ /*
+ * rfkill causes trouble on various non Latitudes, according to Dell
+ * actually testing the rfkill functionality is only done on Latitudes.
+ */
+ product = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (!force_rfkill && (!product || strncmp(product, "Latitude", 8)))
+ return 0;
+
+ get_buffer();
+ dell_send_request(buffer, 17, 11);
+ status = buffer->output[1];
+ buffer->input[0] = 0x2;
+ dell_send_request(buffer, 17, 11);
+ hwswitch_state = buffer->output[1];
+ release_buffer();
+
+ if (!(status & BIT(0))) {
+ if (force_rfkill) {
+ /* No hwsitch, clear all hw-controlled bits */
+ hwswitch_state &= ~7;
+ } else {
+ /* rfkill is only tested on laptops with a hwswitch */
+ return 0;
+ }
+ }
+
+ if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
+ wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
+ RFKILL_TYPE_WLAN,
+ &dell_rfkill_ops, (void *) 1);
+ if (!wifi_rfkill) {
+ ret = -ENOMEM;
+ goto err_wifi;
+ }
+ ret = rfkill_register(wifi_rfkill);
+ if (ret)
+ goto err_wifi;
+ }
+
+ if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
+ bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
+ &platform_device->dev,
+ RFKILL_TYPE_BLUETOOTH,
+ &dell_rfkill_ops, (void *) 2);
+ if (!bluetooth_rfkill) {
+ ret = -ENOMEM;
+ goto err_bluetooth;
+ }
+ ret = rfkill_register(bluetooth_rfkill);
+ if (ret)
+ goto err_bluetooth;
+ }
+
+ if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
+ wwan_rfkill = rfkill_alloc("dell-wwan",
+ &platform_device->dev,
+ RFKILL_TYPE_WWAN,
+ &dell_rfkill_ops, (void *) 3);
+ if (!wwan_rfkill) {
+ ret = -ENOMEM;
+ goto err_wwan;
+ }
+ ret = rfkill_register(wwan_rfkill);
+ if (ret)
+ goto err_wwan;
+ }
+
+ return 0;
+err_wwan:
+ rfkill_destroy(wwan_rfkill);
+ if (bluetooth_rfkill)
+ rfkill_unregister(bluetooth_rfkill);
+err_bluetooth:
+ rfkill_destroy(bluetooth_rfkill);
+ if (wifi_rfkill)
+ rfkill_unregister(wifi_rfkill);
+err_wifi:
+ rfkill_destroy(wifi_rfkill);
+
+ return ret;
+}
+
+static void dell_cleanup_rfkill(void)
+{
+ if (wifi_rfkill) {
+ rfkill_unregister(wifi_rfkill);
+ rfkill_destroy(wifi_rfkill);
+ }
+ if (bluetooth_rfkill) {
+ rfkill_unregister(bluetooth_rfkill);
+ rfkill_destroy(bluetooth_rfkill);
+ }
+ if (wwan_rfkill) {
+ rfkill_unregister(wwan_rfkill);
+ rfkill_destroy(wwan_rfkill);
+ }
+}
+
static int dell_send_intensity(struct backlight_device *bd)
{
int ret = 0;
led_classdev_unregister(&touchpad_led);
}
+static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
+ struct serio *port)
+{
+ static bool extended;
+
+ if (str & 0x20)
+ return false;
+
+ if (unlikely(data == 0xe0)) {
+ extended = true;
+ return false;
+ } else if (unlikely(extended)) {
+ switch (data) {
+ case 0x8:
+ schedule_delayed_work(&dell_rfkill_work,
+ round_jiffies_relative(HZ / 4));
+ break;
+ }
+ extended = false;
+ }
+
+ return false;
+}
+
static int __init dell_init(void)
{
int max_intensity = 0;
}
buffer = page_address(bufferpage);
+ ret = dell_setup_rfkill();
+
+ if (ret) {
+ pr_warn("Unable to setup rfkill\n");
+ goto fail_rfkill;
+ }
+
+ ret = i8042_install_filter(dell_laptop_i8042_filter);
+ if (ret) {
+ pr_warn("Unable to install key filter\n");
+ goto fail_filter;
+ }
+
if (quirks && quirks->touchpad_led)
touchpad_led_init(&platform_device->dev);
dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
+ if (dell_laptop_dir != NULL)
+ debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
+ &dell_debugfs_fops);
#ifdef CONFIG_ACPI
/* In the event of an ACPI backlight being available, don't
return 0;
fail_backlight:
+ i8042_remove_filter(dell_laptop_i8042_filter);
+ cancel_delayed_work_sync(&dell_rfkill_work);
+fail_filter:
+ dell_cleanup_rfkill();
+fail_rfkill:
free_page((unsigned long)bufferpage);
fail_buffer:
platform_device_del(platform_device);
debugfs_remove_recursive(dell_laptop_dir);
if (quirks && quirks->touchpad_led)
touchpad_led_exit();
+ i8042_remove_filter(dell_laptop_i8042_filter);
+ cancel_delayed_work_sync(&dell_rfkill_work);
backlight_device_unregister(dell_backlight_device);
+ dell_cleanup_rfkill();
if (platform_device) {
platform_device_unregister(platform_device);
platform_driver_unregister(&platform_driver);
KEY_BRIGHTNESSUP, KEY_UNKNOWN, KEY_KBDILLUMTOGGLE,
KEY_UNKNOWN, KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN, KEY_PROG2,
- KEY_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_MICMUTE,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- KEY_PROG3
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PROG3
};
static struct input_dev *dell_wmi_input_dev;
int error;
input = input_allocate_device();
- if (!input) {
- pr_info("Unable to allocate input device\n");
+ if (!input)
return -ENOMEM;
- }
input->name = "Asus EeePC extra buttons";
input->phys = EEEPC_LAPTOP_FILE "/input0";
#define HPWMI_HARDWARE_QUERY 0x4
#define HPWMI_WIRELESS_QUERY 0x5
#define HPWMI_HOTKEY_QUERY 0xc
+#define HPWMI_FEATURE_QUERY 0xd
#define HPWMI_WIRELESS2_QUERY 0x1b
#define HPWMI_POSTCODEERROR_QUERY 0x2a
return (state & 0x4) ? 1 : 0;
}
+static int hp_wmi_bios_2009_later(void)
+{
+ int state = 0;
+ int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state,
+ sizeof(state), sizeof(state));
+ if (ret)
+ return ret;
+
+ return (state & 0x10) ? 1 : 0;
+}
+
static int hp_wmi_set_block(void *data, bool blocked)
{
enum hp_wmi_radio r = (enum hp_wmi_radio) data;
gps_rfkill = NULL;
rfkill2_count = 0;
- if (hp_wmi_rfkill_setup(device))
+ if (hp_wmi_bios_2009_later() || hp_wmi_rfkill_setup(device))
hp_wmi_rfkill2_setup(device);
err = device_create_file(&device->dev, &dev_attr_display);
int error;
inputdev = input_allocate_device();
- if (!inputdev) {
- pr_info("Unable to allocate input device\n");
+ if (!inputdev)
return -ENOMEM;
- }
inputdev->name = "Ideapad extra buttons";
inputdev->phys = "ideapad/input0";
return -EINVAL;
input = input_allocate_device();
- if (!input) {
- dev_err(&pdev->dev, "Input device allocation error\n");
+ if (!input)
return -ENOMEM;
- }
input->name = pdev->name;
input->phys = "power-button/input0";
* message handler is called within firmware.
*/
-#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */
-#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */
#define IPC_WWBUF_SIZE 20 /* IPC Write buffer Size */
#define IPC_RWBUF_SIZE 20 /* IPC Read buffer Size */
-#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */
-#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */
+#define IPC_IOC 0x100 /* IPC command register IOC bit */
+
+enum {
+ SCU_IPC_LINCROFT,
+ SCU_IPC_PENWELL,
+ SCU_IPC_CLOVERVIEW,
+ SCU_IPC_TANGIER,
+};
+
+/* intel scu ipc driver data*/
+struct intel_scu_ipc_pdata_t {
+ u32 ipc_base;
+ u32 i2c_base;
+ u32 ipc_len;
+ u32 i2c_len;
+ u8 irq_mode;
+};
+
+static struct intel_scu_ipc_pdata_t intel_scu_ipc_pdata[] = {
+ [SCU_IPC_LINCROFT] = {
+ .ipc_base = 0xff11c000,
+ .i2c_base = 0xff12b000,
+ .ipc_len = 0x100,
+ .i2c_len = 0x10,
+ .irq_mode = 0,
+ },
+ [SCU_IPC_PENWELL] = {
+ .ipc_base = 0xff11c000,
+ .i2c_base = 0xff12b000,
+ .ipc_len = 0x100,
+ .i2c_len = 0x10,
+ .irq_mode = 1,
+ },
+ [SCU_IPC_CLOVERVIEW] = {
+ .ipc_base = 0xff11c000,
+ .i2c_base = 0xff12b000,
+ .ipc_len = 0x100,
+ .i2c_len = 0x10,
+ .irq_mode = 1,
+ },
+ [SCU_IPC_TANGIER] = {
+ .ipc_base = 0xff009000,
+ .i2c_base = 0xff00d000,
+ .ipc_len = 0x100,
+ .i2c_len = 0x10,
+ .irq_mode = 0,
+ },
+};
static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
static void ipc_remove(struct pci_dev *pdev);
struct pci_dev *pdev;
void __iomem *ipc_base;
void __iomem *i2c_base;
+ struct completion cmd_complete;
+ u8 irq_mode;
};
static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
*/
static inline void ipc_command(u32 cmd) /* Send ipc command */
{
+ if (ipcdev.irq_mode) {
+ reinit_completion(&ipcdev.cmd_complete);
+ writel(cmd | IPC_IOC, ipcdev.ipc_base);
+ }
writel(cmd, ipcdev.ipc_base);
}
return 0;
}
+/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
+static inline int ipc_wait_for_interrupt(void)
+{
+ int status;
+
+ if (!wait_for_completion_timeout(&ipcdev.cmd_complete, 3 * HZ)) {
+ struct device *dev = &ipcdev.pdev->dev;
+ dev_err(dev, "IPC timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ status = ipc_read_status();
+
+ if ((status >> 1) & 1)
+ return -EIO;
+
+ return 0;
+}
+
+int intel_scu_ipc_check_status(void)
+{
+ return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop();
+}
+
/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
{
ipc_command(4 << 16 | id << 12 | 0 << 8 | op);
}
- err = busy_loop();
- if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
+ err = intel_scu_ipc_check_status();
+ if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
/* Workaround: values are read as 0 without memcpy_fromio */
memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16);
for (nc = 0; nc < count; nc++)
return -ENODEV;
}
ipc_command(sub << 12 | cmd);
- err = busy_loop();
+ err = intel_scu_ipc_check_status();
mutex_unlock(&ipclock);
return err;
}
ipc_data_writel(*in++, 4 * i);
ipc_command((inlen << 16) | (sub << 12) | cmd);
- err = busy_loop();
+ err = intel_scu_ipc_check_status();
- for (i = 0; i < outlen; i++)
- *out++ = ipc_data_readl(4 * i);
+ if (!err) {
+ for (i = 0; i < outlen; i++)
+ *out++ = ipc_data_readl(4 * i);
+ }
mutex_unlock(&ipclock);
return err;
*/
static irqreturn_t ioc(int irq, void *dev_id)
{
+ if (ipcdev.irq_mode)
+ complete(&ipcdev.cmd_complete);
+
return IRQ_HANDLED;
}
*/
static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- int err;
+ int err, pid;
+ struct intel_scu_ipc_pdata_t *pdata;
resource_size_t pci_resource;
if (ipcdev.pdev) /* We support only one SCU */
return -EBUSY;
+ pid = id->driver_data;
+ pdata = &intel_scu_ipc_pdata[pid];
+
ipcdev.pdev = pci_dev_get(dev);
+ ipcdev.irq_mode = pdata->irq_mode;
err = pci_enable_device(dev);
if (err)
if (!pci_resource)
return -ENOMEM;
+ init_completion(&ipcdev.cmd_complete);
+
if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev))
return -EBUSY;
- ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR);
+ ipcdev.ipc_base = ioremap_nocache(pdata->ipc_base, pdata->ipc_len);
if (!ipcdev.ipc_base)
return -ENOMEM;
- ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR);
+ ipcdev.i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
if (!ipcdev.i2c_base) {
iounmap(ipcdev.ipc_base);
return -ENOMEM;
}
static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)},
+ {PCI_VDEVICE(INTEL, 0x082a), SCU_IPC_LINCROFT},
+ {PCI_VDEVICE(INTEL, 0x080e), SCU_IPC_PENWELL},
+ {PCI_VDEVICE(INTEL, 0x08ea), SCU_IPC_CLOVERVIEW},
+ {PCI_VDEVICE(INTEL, 0x11a0), SCU_IPC_TANGIER},
{ 0,}
};
MODULE_DEVICE_TABLE(pci, pci_ids);
int error;
input_dev = input_allocate_device();
- if (!input_dev) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Couldn't allocate input device for hotkey"));
+ if (!input_dev)
return -ENOMEM;
- }
input_dev->name = ACPI_PCC_DRIVER_NAME;
input_dev->phys = ACPI_PCC_INPUT_PHYS;
"on the model (default: no change from current value)");
#ifdef CONFIG_PM_SLEEP
-static void sony_nc_kbd_backlight_resume(void);
static void sony_nc_thermal_resume(void);
#endif
static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
unsigned int handle);
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd);
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+ unsigned int handle);
static int sony_nc_battery_care_setup(struct platform_device *pd,
unsigned int handle);
KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */
KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */
KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */
- KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */
- KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */
+ KEY_FN_1, /* 17 SONYPI_EVENT_FNKEY_1 */
+ KEY_FN_2, /* 18 SONYPI_EVENT_FNKEY_2 */
KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */
KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */
KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */
case 0x014b:
case 0x014c:
case 0x0163:
- sony_nc_kbd_backlight_cleanup(pd);
+ sony_nc_kbd_backlight_cleanup(pd, handle);
break;
default:
continue;
case 0x0135:
sony_nc_rfkill_update();
break;
- case 0x0137:
- case 0x0143:
- case 0x014b:
- case 0x014c:
- case 0x0163:
- sony_nc_kbd_backlight_resume();
- break;
default:
continue;
}
int result;
int ret = 0;
+ if (kbdbl_ctl) {
+ pr_warn("handle 0x%.4x: keyboard backlight setup already done for 0x%.4x\n",
+ handle, kbdbl_ctl->handle);
+ return -EBUSY;
+ }
+
/* verify the kbd backlight presence, these handles are not used for
* keyboard backlight only
*/
return ret;
}
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+ unsigned int handle)
{
- if (kbdbl_ctl) {
+ if (kbdbl_ctl && handle == kbdbl_ctl->handle) {
device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr);
device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr);
kfree(kbdbl_ctl);
}
}
-#ifdef CONFIG_PM_SLEEP
-static void sony_nc_kbd_backlight_resume(void)
-{
- int ignore = 0;
-
- if (!kbdbl_ctl)
- return;
-
- if (kbdbl_ctl->mode == 0)
- sony_call_snc_handle(kbdbl_ctl->handle, kbdbl_ctl->base,
- &ignore);
-
- if (kbdbl_ctl->timeout != 0)
- sony_call_snc_handle(kbdbl_ctl->handle,
- (kbdbl_ctl->base + 0x200) |
- (kbdbl_ctl->timeout << 0x10), &ignore);
-}
-#endif
-
struct battery_care_control {
struct device_attribute attrs[2];
unsigned int handle;
#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
-static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
+#if SNDRV_CARDS <= 32
+#define DEFAULT_ALSA_IDX ~((1 << (SNDRV_CARDS - 3)) - 1)
+#else
+#define DEFAULT_ALSA_IDX ~((1 << (32 - 3)) - 1)
+#endif
+static int alsa_index = DEFAULT_ALSA_IDX; /* last three slots */
static char *alsa_id = "ThinkPadEC";
static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;
mutex_init(&tpacpi_inputdev_send_mutex);
tpacpi_inputdev = input_allocate_device();
if (!tpacpi_inputdev) {
- pr_err("unable to allocate input device\n");
thinkpad_acpi_module_exit();
return -ENOMEM;
} else {
int error;
input = input_allocate_device();
- if (!input) {
- pr_err("Unable to allocate input device\n");
+ if (!input)
return -ENOMEM;
- }
input->name = "Topstar Laptop extra buttons";
input->phys = "topstar/input0";
u32 hci_result;
dev->hotkey_dev = input_allocate_device();
- if (!dev->hotkey_dev) {
- pr_info("Unable to register input device\n");
+ if (!dev->hotkey_dev)
return -ENOMEM;
- }
dev->hotkey_dev->name = "Toshiba input device";
dev->hotkey_dev->phys = "toshiba_acpi/input0";
struct wmi_block *wblock;
wblock = dev_get_drvdata(dev);
- if (!wblock)
- return -ENOMEM;
+ if (!wblock) {
+ strcat(buf, "\n");
+ return strlen(buf);
+ }
wmi_gtoa(wblock->gblock.guid, guid_string);
return __pnp_bus_suspend(dev, PMSG_FREEZE);
}
+static int pnp_bus_poweroff(struct device *dev)
+{
+ return __pnp_bus_suspend(dev, PMSG_HIBERNATE);
+}
+
static int pnp_bus_resume(struct device *dev)
{
struct pnp_dev *pnp_dev = to_pnp_dev(dev);
}
static const struct dev_pm_ops pnp_bus_dev_pm_ops = {
+ /* Suspend callbacks */
.suspend = pnp_bus_suspend,
- .freeze = pnp_bus_freeze,
.resume = pnp_bus_resume,
+ /* Hibernate callbacks */
+ .freeze = pnp_bus_freeze,
+ .thaw = pnp_bus_resume,
+ .poweroff = pnp_bus_poweroff,
+ .restore = pnp_bus_resume,
};
struct bus_type pnp_bus_type = {
if (power_zone->ops->get_max_energy_range_uj)
power_zone->zone_dev_attrs[count++] =
&dev_attr_max_energy_range_uj.attr;
- if (power_zone->ops->get_energy_uj)
+ if (power_zone->ops->get_energy_uj) {
+ if (power_zone->ops->reset_energy_uj)
+ dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO;
+ else
+ dev_attr_energy_uj.attr.mode = S_IRUGO;
power_zone->zone_dev_attrs[count++] =
&dev_attr_energy_uj.attr;
+ }
if (power_zone->ops->get_power_uw)
power_zone->zone_dev_attrs[count++] =
&dev_attr_power_uw.attr;
.owner = THIS_MODULE,
};
+static const struct regulator_linear_range arizona_micsupp_ext_ranges[] = {
+ REGULATOR_LINEAR_RANGE(900000, 0, 0x14, 25000),
+ REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
+};
+
+static const struct regulator_desc arizona_micsupp_ext = {
+ .name = "MICVDD",
+ .supply_name = "CPVDD",
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 40,
+ .ops = &arizona_micsupp_ops,
+
+ .vsel_reg = ARIZONA_LDO2_CONTROL_1,
+ .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
+ .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+ .enable_mask = ARIZONA_CPMIC_ENA,
+ .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+ .bypass_mask = ARIZONA_CPMIC_BYPASS,
+
+ .linear_ranges = arizona_micsupp_ext_ranges,
+ .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
+
+ .enable_time = 3000,
+
+ .owner = THIS_MODULE,
+};
+
static const struct regulator_init_data arizona_micsupp_default = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS |
.num_consumer_supplies = 1,
};
+static const struct regulator_init_data arizona_micsupp_ext_default = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_BYPASS,
+ .min_uV = 900000,
+ .max_uV = 3300000,
+ },
+
+ .num_consumer_supplies = 1,
+};
+
static int arizona_micsupp_probe(struct platform_device *pdev)
{
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+ const struct regulator_desc *desc;
struct regulator_config config = { };
struct arizona_micsupp *micsupp;
int ret;
* default init_data for it. This will be overridden with
* platform data if provided.
*/
- micsupp->init_data = arizona_micsupp_default;
+ switch (arizona->type) {
+ case WM5110:
+ desc = &arizona_micsupp_ext;
+ micsupp->init_data = arizona_micsupp_ext_default;
+ break;
+ default:
+ desc = &arizona_micsupp;
+ micsupp->init_data = arizona_micsupp_default;
+ break;
+ }
+
micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.supply = "MICVDD";
micsupp->supply.dev_name = dev_name(arizona->dev);
ARIZONA_CPMIC_BYPASS, 0);
micsupp->regulator = devm_regulator_register(&pdev->dev,
- &arizona_micsupp,
+ desc,
&config);
if (IS_ERR(micsupp->regulator)) {
ret = PTR_ERR(micsupp->regulator);
struct regulator_ops *ops = rdev->desc->ops;
int ret;
+ if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)
+ return rdev->desc->fixed_uV;
+
if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
return -EINVAL;
struct property *prop;
const char *regtype;
int proplen, gpio, i;
+ int ret;
config = devm_kzalloc(dev,
sizeof(struct gpio_regulator_config),
}
config->nr_states = i;
- of_property_read_string(np, "regulator-type", ®type);
+ ret = of_property_read_string(np, "regulator-type", ®type);
+ if (ret < 0) {
+ dev_err(dev, "Missing 'regulator-type' property\n");
+ return ERR_PTR(-EINVAL);
+ }
if (!strncmp("voltage", regtype, 7))
config->type = REGULATOR_VOLTAGE;
if (ret)
return ret;
- if (value & 0x0f) {
- dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
- return -ENODEV;
+ switch (value & 0x0f) {
+ /* Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 as ID=8 */
+ case 0x8:
+ dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
+ case 0x0:
+ break;
+ default:
+ dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
+ return -ENODEV;
}
ret = regmap_read(pfuze_chip->regmap, PFUZE100_REVID, &value);
fcx_multitrack = private->features.feature[40] & 0x20;
data_size = blk_rq_bytes(req);
+ if (data_size % blksize)
+ return ERR_PTR(-EINVAL);
/* tpm write request add CBC data on each track boundary */
if (rq_data_dir(req) == WRITE)
data_size += (last_trk - first_trk) * 4;
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twa_host_attrs,
- .emulated = 1
+ .emulated = 1,
+ .no_write_same = 1,
};
/* This function will probe and initialize a card */
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twl_host_attrs,
- .emulated = 1
+ .emulated = 1,
+ .no_write_same = 1,
};
/* This function will probe and initialize a card */
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = tw_host_attrs,
- .emulated = 1
+ .emulated = 1,
+ .no_write_same = 1,
};
/* This function will probe and initialize a card */
#endif
.use_clustering = ENABLE_CLUSTERING,
.emulated = 1,
+ .no_write_same = 1,
};
static void __aac_shutdown(struct aac_dev * aac)
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = arcmsr_host_attrs,
+ .no_write_same = 1,
};
static struct pci_device_id arcmsr_device_id_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
struct bfa_fcs_lport_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs,
u16 vf_id, wwn_t lpwwn);
+void bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, char *symname);
void bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
struct bfa_lport_info_s *port_info);
void bfa_fcs_lport_get_attr(struct bfa_fcs_lport_s *port,
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
}
+void
+bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port,
+ char *symname)
+{
+ strcpy(port->port_cfg.sym_name.symname, symname);
+
+ if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
+ bfa_fcs_lport_ns_util_send_rspn_id(
+ BFA_FCS_GET_NS_FROM_PORT(port), NULL);
+}
+
/*
* fcs_lport_api
*/
u8 *psymbl = &symbl[0];
int len;
- if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
- return;
-
/* Avoid sending RSPN in the following states. */
if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
return;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- if (strlen(sym_name) > 0) {
- strcpy(fcs_vport->lport.port_cfg.sym_name.symname, sym_name);
- bfa_fcs_lport_ns_util_send_rspn_id(
- BFA_FCS_GET_NS_FROM_PORT((&fcs_vport->lport)), NULL);
- }
+ if (strlen(sym_name) > 0)
+ bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
}
.cmd_per_lun = GDTH_MAXC_P_L,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .no_write_same = 1,
};
#ifdef CONFIG_ISA
shost->use_clustering = sht->use_clustering;
shost->ordered_tag = sht->ordered_tag;
shost->eh_deadline = shost_eh_deadline * HZ;
+ shost->no_write_same = sht->no_write_same;
if (sht->supported_mode == MODE_UNKNOWN)
/* means we didn't set it ... default to INITIATOR */
.sdev_attrs = hpsa_sdev_attrs,
.shost_attrs = hpsa_shost_attrs,
.max_sectors = 8192,
+ .no_write_same = 1,
};
"has check condition: aborted command: "
"ASC: 0x%x, ASCQ: 0x%x\n",
cp, asc, ascq);
- cmd->result = DID_SOFT_ERROR << 16;
+ cmd->result |= DID_SOFT_ERROR << 16;
break;
}
/* Must be some other type of check condition */
hpsa_hba_inquiry(h);
hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
start_controller_lockup_detector(h);
- return 1;
+ return 0;
clean4:
hpsa_free_sg_chain_blocks(h);
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ipr_ioa_attrs,
.sdev_attrs = ipr_dev_attrs,
- .proc_name = IPR_NAME
+ .proc_name = IPR_NAME,
+ .no_write_same = 1,
};
/**
.sg_tablesize = IPS_MAX_SG,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .no_write_same = 1,
};
qc->tf.nsect = 0;
}
- ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
+ ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis);
task->uldd_task = qc;
if (ata_is_atapi(qc->tf.protocol)) {
memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
.eh_device_reset_handler = megaraid_reset,
.eh_bus_reset_handler = megaraid_reset,
.eh_host_reset_handler = megaraid_reset,
+ .no_write_same = 1,
};
static int
.eh_host_reset_handler = megaraid_reset_handler,
.change_queue_depth = megaraid_change_queue_depth,
.use_clustering = ENABLE_CLUSTERING,
+ .no_write_same = 1,
.sdev_attrs = megaraid_sdev_attrs,
.shost_attrs = megaraid_shost_attrs,
};
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
.change_queue_depth = megasas_change_queue_depth,
+ .no_write_same = 1,
};
/**
unsigned long flags;
u8 deviceType = pPayload->sas_identify.dev_type;
port->port_state = portstate;
+ phy->phy_state = PHY_STATE_LINK_UP_SPC;
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n",
port_id, phy_id));
pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d,"
" phy id = %d\n", port_id, phy_id));
port->port_state = portstate;
+ phy->phy_state = PHY_STATE_LINK_UP_SPC;
port->port_attached = 1;
pm8001_get_lrate_mode(phy, link_rate);
phy->phy_type |= PORT_TYPE_SATA;
#define LINKRATE_30 (0x02 << 8)
#define LINKRATE_60 (0x04 << 8)
+/* for phy state */
+
+#define PHY_STATE_LINK_UP_SPC 0x1
+
/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
#define GSM_SM_BASE 0x4F0000
struct mpi_msg_hdr{
static void pm8001_tasklet(unsigned long opaque)
{
struct pm8001_hba_info *pm8001_ha;
- u32 vec;
- pm8001_ha = (struct pm8001_hba_info *)opaque;
+ struct isr_param *irq_vector;
+
+ irq_vector = (struct isr_param *)opaque;
+ pm8001_ha = irq_vector->drv_inst;
if (unlikely(!pm8001_ha))
BUG_ON(1);
- vec = pm8001_ha->int_vector;
- PM8001_CHIP_DISP->isr(pm8001_ha, vec);
+ PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id);
}
#endif
-static struct pm8001_hba_info *outq_to_hba(u8 *outq)
-{
- return container_of((outq - *outq), struct pm8001_hba_info, outq[0]);
-}
-
/**
* pm8001_interrupt_handler_msix - main MSIX interrupt handler.
* It obtains the vector number and calls the equivalent bottom
*/
static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque)
{
- struct pm8001_hba_info *pm8001_ha = outq_to_hba(opaque);
- u8 outq = *(u8 *)opaque;
+ struct isr_param *irq_vector;
+ struct pm8001_hba_info *pm8001_ha;
irqreturn_t ret = IRQ_HANDLED;
+ irq_vector = (struct isr_param *)opaque;
+ pm8001_ha = irq_vector->drv_inst;
+
if (unlikely(!pm8001_ha))
return IRQ_NONE;
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
return IRQ_NONE;
- pm8001_ha->int_vector = outq;
#ifdef PM8001_USE_TASKLET
- tasklet_schedule(&pm8001_ha->tasklet);
+ tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]);
#else
- ret = PM8001_CHIP_DISP->isr(pm8001_ha, outq);
+ ret = PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id);
#endif
return ret;
}
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
return IRQ_NONE;
- pm8001_ha->int_vector = 0;
#ifdef PM8001_USE_TASKLET
- tasklet_schedule(&pm8001_ha->tasklet);
+ tasklet_schedule(&pm8001_ha->tasklet[0]);
#else
ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0);
#endif
{
struct pm8001_hba_info *pm8001_ha;
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
-
+ int j;
pm8001_ha = sha->lldd_ha;
if (!pm8001_ha)
pm8001_ha->iomb_size = IOMB_SIZE_SPC;
#ifdef PM8001_USE_TASKLET
- /**
- * default tasklet for non msi-x interrupt handler/first msi-x
- * interrupt handler
- **/
- tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
- (unsigned long)pm8001_ha);
+ /* Tasklet for non msi-x interrupt handler */
+ if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+ tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
+ (unsigned long)&(pm8001_ha->irq_vector[0]));
+ else
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
+ tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
+ (unsigned long)&(pm8001_ha->irq_vector[j]));
#endif
pm8001_ioremap(pm8001_ha);
if (!pm8001_alloc(pm8001_ha, ent))
"pci_enable_msix request ret:%d no of intr %d\n",
rc, pm8001_ha->number_of_intr));
- for (i = 0; i < number_of_intr; i++)
- pm8001_ha->outq[i] = i;
for (i = 0; i < number_of_intr; i++) {
snprintf(intr_drvname[i], sizeof(intr_drvname[0]),
DRV_NAME"%d", i);
+ pm8001_ha->irq_vector[i].irq_id = i;
+ pm8001_ha->irq_vector[i].drv_inst = pm8001_ha;
+
if (request_irq(pm8001_ha->msix_entries[i].vector,
pm8001_interrupt_handler_msix, flag,
- intr_drvname[i], &pm8001_ha->outq[i])) {
+ intr_drvname[i], &(pm8001_ha->irq_vector[i]))) {
for (j = 0; j < i; j++)
free_irq(
pm8001_ha->msix_entries[j].vector,
- &pm8001_ha->outq[j]);
+ &(pm8001_ha->irq_vector[i]));
pci_disable_msix(pm8001_ha->pdev);
break;
}
{
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
struct pm8001_hba_info *pm8001_ha;
- int i;
+ int i, j;
pm8001_ha = sha->lldd_ha;
sas_unregister_ha(sha);
sas_remove_host(pm8001_ha->shost);
synchronize_irq(pm8001_ha->msix_entries[i].vector);
for (i = 0; i < pm8001_ha->number_of_intr; i++)
free_irq(pm8001_ha->msix_entries[i].vector,
- &pm8001_ha->outq[i]);
+ &(pm8001_ha->irq_vector[i]));
pci_disable_msix(pdev);
#else
free_irq(pm8001_ha->irq, sha);
#endif
#ifdef PM8001_USE_TASKLET
- tasklet_kill(&pm8001_ha->tasklet);
+ /* For non-msix and msix interrupts */
+ if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+ tasklet_kill(&pm8001_ha->tasklet[0]);
+ else
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
+ tasklet_kill(&pm8001_ha->tasklet[j]);
#endif
pm8001_free(pm8001_ha);
kfree(sha->sas_phy);
{
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
struct pm8001_hba_info *pm8001_ha;
- int i;
+ int i, j;
u32 device_state;
pm8001_ha = sha->lldd_ha;
flush_workqueue(pm8001_wq);
synchronize_irq(pm8001_ha->msix_entries[i].vector);
for (i = 0; i < pm8001_ha->number_of_intr; i++)
free_irq(pm8001_ha->msix_entries[i].vector,
- &pm8001_ha->outq[i]);
+ &(pm8001_ha->irq_vector[i]));
pci_disable_msix(pdev);
#else
free_irq(pm8001_ha->irq, sha);
#endif
#ifdef PM8001_USE_TASKLET
- tasklet_kill(&pm8001_ha->tasklet);
+ /* For non-msix and msix interrupts */
+ if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+ tasklet_kill(&pm8001_ha->tasklet[0]);
+ else
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
+ tasklet_kill(&pm8001_ha->tasklet[j]);
#endif
device_state = pci_choose_state(pdev, state);
pm8001_printk("pdev=0x%p, slot=%s, entering "
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
struct pm8001_hba_info *pm8001_ha;
int rc;
- u8 i = 0;
+ u8 i = 0, j;
u32 device_state;
pm8001_ha = sha->lldd_ha;
device_state = pdev->current_state;
if (rc)
goto err_out_disable;
#ifdef PM8001_USE_TASKLET
- /* default tasklet for non msi-x interrupt handler/first msi-x
- * interrupt handler */
- tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
- (unsigned long)pm8001_ha);
+ /* Tasklet for non msi-x interrupt handler */
+ if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+ tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
+ (unsigned long)&(pm8001_ha->irq_vector[0]));
+ else
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
+ tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
+ (unsigned long)&(pm8001_ha->irq_vector[j]));
#endif
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
if (pm8001_ha->chip_id != chip_8001) {
MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>");
MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>");
MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>");
+MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>");
MODULE_DESCRIPTION(
"PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 "
"SAS/SATA controller driver");
struct pm8001_tmf_task tmf_task;
struct pm8001_device *pm8001_dev = dev->lldd_dev;
struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
+ DECLARE_COMPLETION_ONSTACK(completion_setstate);
if (dev_is_sata(dev)) {
struct sas_phy *phy = sas_get_local_phy(dev);
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
dev, 1, 0);
rc = sas_phy_reset(phy, 1);
sas_put_local_phy(phy);
+ pm8001_dev->setds_completion = &completion_setstate;
rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
pm8001_dev, 0x01);
- msleep(2000);
+ wait_for_completion(&completion_setstate);
} else {
tmf_task.tmf = TMF_LU_RESET;
rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
u64 membase;
u32 memsize;
};
+struct isr_param {
+ struct pm8001_hba_info *drv_inst;
+ u32 irq_id;
+};
struct pm8001_hba_info {
char name[PM8001_NAME_LENGTH];
struct list_head list;
int number_of_intr;/*will be used in remove()*/
#endif
#ifdef PM8001_USE_TASKLET
- struct tasklet_struct tasklet;
+ struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC];
#endif
u32 logging_level;
u32 fw_status;
u32 smp_exp_mode;
- u32 int_vector;
const struct firmware *fw_image;
- u8 outq[PM8001_MAX_MSIX_VEC];
+ struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
};
struct pm8001_work {
unsigned long flags;
u8 deviceType = pPayload->sas_identify.dev_type;
port->port_state = portstate;
+ phy->phy_state = PHY_STATE_LINK_UP_SPCV;
PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
"portid:%d; phyid:%d; linkrate:%d; "
"portstate:%x; devicetype:%x\n",
port_id, phy_id, link_rate, portstate));
port->port_state = portstate;
+ phy->phy_state = PHY_STATE_LINK_UP_SPCV;
port->port_attached = 1;
pm8001_get_lrate_mode(phy, link_rate);
phy->phy_type |= PORT_TYPE_SATA;
#define SAS_DOPNRJT_RTRY_TMO 128
#define SAS_COPNRJT_RTRY_TMO 128
+/* for phy state */
+#define PHY_STATE_LINK_UP_SPCV 0x2
/*
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
};
#define PMCRAID_AEN_CMD_MAX (__PMCRAID_AEN_CMD_MAX - 1)
+static struct genl_multicast_group pmcraid_mcgrps[] = {
+ { .name = "events", /* not really used - see ID discussion below */ },
+};
+
static struct genl_family pmcraid_event_family = {
- .id = GENL_ID_GENERATE,
+ /*
+ * Due to prior multicast group abuse (the code having assumed that
+ * the family ID can be used as a multicast group ID) we need to
+ * statically allocate a family (and thus group) ID.
+ */
+ .id = GENL_ID_PMCRAID,
.name = "pmcraid",
.version = 1,
- .maxattr = PMCRAID_AEN_ATTR_MAX
+ .maxattr = PMCRAID_AEN_ATTR_MAX,
+ .mcgrps = pmcraid_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(pmcraid_mcgrps),
};
/**
return result;
}
- result =
- genlmsg_multicast(&pmcraid_event_family, skb, 0,
- pmcraid_event_family.id, GFP_ATOMIC);
+ result = genlmsg_multicast(&pmcraid_event_family, skb,
+ 0, 0, GFP_ATOMIC);
/* If there are no listeners, genlmsg_multicast may return non-zero
* value.
.this_id = -1,
.sg_tablesize = PMCRAID_MAX_IOADLS,
.max_sectors = PMCRAID_IOA_MAX_SECTORS,
+ .no_write_same = 1,
.cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = pmcraid_host_attrs,
{
struct scsi_device *sdev = sdkp->device;
+ if (sdev->host->no_write_same) {
+ sdev->no_write_same = 1;
+
+ return;
+ }
+
if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
/* too large values might cause issues with arcmsr */
int vpd_buf_len = 64;
.use_clustering = DISABLE_CLUSTERING,
/* Make sure we dont get a sg segment crosses a page boundary */
.dma_boundary = PAGE_SIZE-1,
+ .no_write_same = 1,
};
enum {
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
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
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.
static int bcm2835_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+ struct spi_master *master = platform_get_drvdata(pdev);
struct bcm2835_spi *bs = spi_master_get_devdata(master);
free_irq(bs->irq, master);
static int bcm63xx_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+ struct spi_master *master = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
/* reset spi block */
static int mpc512x_psc_spi_do_remove(struct device *dev)
{
- struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+ struct spi_master *master = dev_get_drvdata(dev);
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
clk_disable_unprepare(mps->clk_mclk);
struct mxs_spi *spi;
struct mxs_ssp *ssp;
- master = spi_master_get(platform_get_drvdata(pdev));
+ master = platform_get_drvdata(pdev);
spi = spi_master_get_devdata(master);
ssp = &spi->ssp;
static struct acpi_device_id pxa2xx_spi_acpi_match[] = {
{ "INT33C0", 0 },
{ "INT33C1", 0 },
+ { "INT3430", 0 },
+ { "INT3431", 0 },
{ "80860F0E", 0 },
{ },
};
/* Enable the SSP clock */
clk_prepare_enable(ssp->clk);
+ /* Restore LPSS private register bits */
+ lpss_ssp_setup(drv_data);
+
/* Start the queue running */
status = spi_master_resume(drv_data->master);
if (status != 0) {
static int rspi_remove(struct platform_device *pdev)
{
- struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev));
+ struct rspi_data *rspi = platform_get_drvdata(pdev);
spi_unregister_master(rspi->master);
rspi_release_dma(rspi);
free_irq(platform_get_irq(pdev, 0), rspi);
clk_put(rspi->clk);
iounmap(rspi->addr);
- spi_master_put(rspi->master);
return 0;
}
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#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
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;
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,
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;
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;
}
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;
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))
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);
#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)
spinlock_t lock;
struct clk *clk;
+ struct reset_control *rst;
void __iomem *base;
unsigned irq;
u32 spi_max_frequency;
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;
}
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)) {
}
/* 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);
#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)
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;
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,
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;
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;
}
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;
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))
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);
qspi->spi_max_frequency, clk_div);
ret = pm_runtime_get_sync(qspi->dev);
- if (ret) {
+ if (ret < 0) {
dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
return ret;
}
if (!of_property_read_u32(np, "num-cs", &num_cs))
master->num_chipselect = num_cs;
- platform_set_drvdata(pdev, master);
-
qspi = spi_master_get_devdata(master);
qspi->master = master;
qspi->dev = &pdev->dev;
+ platform_set_drvdata(pdev, qspi);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
static int ti_qspi_remove(struct platform_device *pdev)
{
- struct ti_qspi *qspi = platform_get_drvdata(pdev);
+ struct spi_master *master;
+ struct ti_qspi *qspi;
+ int ret;
+
+ master = platform_get_drvdata(pdev);
+ qspi = spi_master_get_devdata(master);
+
+ ret = pm_runtime_get_sync(qspi->dev);
+ if (ret < 0) {
+ dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
+ return ret;
+ }
ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
+ pm_runtime_put(qspi->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ spi_unregister_master(master);
+
return 0;
}
static int txx9spi_remove(struct platform_device *dev)
{
- struct spi_master *master = spi_master_get(platform_get_drvdata(dev));
+ struct spi_master *master = platform_get_drvdata(dev);
struct txx9spi *c = spi_master_get_devdata(master);
destroy_workqueue(c->workqueue);
return -ENOMEM;
ret = spi_register_master(master);
- if (ret != 0) {
+ if (!ret) {
*ptr = master;
devres_add(dev, ptr);
} else {
kfree_skb(skb);
}
-static int btmtk_usb_send_frame(struct sk_buff *skb)
+static int btmtk_usb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_dev *hdev = (struct hci_dev *)skb->dev;
struct btmtk_usb_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
if (mask) {
if (mask & 0x00ff)
outb(s->state & 0xff, dev->iobase + reg);
- if ((mask & 0xff00) & (s->n_chan > 8))
+ if ((mask & 0xff00) && (s->n_chan > 8))
outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
- if ((mask & 0xff0000) & (s->n_chan > 16))
+ if ((mask & 0xff0000) && (s->n_chan > 16))
outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
- if ((mask & 0xff000000) & (s->n_chan > 24))
+ if ((mask & 0xff000000) && (s->n_chan > 24))
outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
}
* Private helper function: Write setpoint to an application DAC channel.
*/
static void s626_set_dac(struct comedi_device *dev, uint16_t chan,
- unsigned short dacdata)
+ int16_t dacdata)
{
struct s626_private *devpriv = dev->private;
uint16_t signmask;
unsigned char *rx_buf = devpriv->usb_rx_buf;
unsigned char *tx_buf = devpriv->usb_tx_buf;
int reg, cmd;
- int ret;
+ int ret = 0;
if (devpriv->model == VMK8061_MODEL) {
reg = VMK8061_DO_REG;
u8 **c_file, const u8 *endpoint, bool boot_case)
{
long word_length;
- int status;
+ int status = 0;
/*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/
word_length = get_request_value(ft1000dev);
return status;
}
-
config SENSORS_HMC5843
tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o
obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/
-obj-$(CONFIG_DRM_IMX_IPUV3) += ipuv3-crtc.o ipuv3-plane.o
+
+imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o
+obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o
{
return crtc->pipe;
}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_id);
static void imx_drm_driver_lastclose(struct drm_device *drm)
{
struct l_wait_info lwi = { 0 };
int rc = 0;
- if (!thread_is_init(&pinger_thread) &&
- !thread_is_stopped(&pinger_thread))
+ if (thread_is_init(&pinger_thread) ||
+ thread_is_stopped(&pinger_thread))
return -EALREADY;
ptlrpc_pinger_remove_timeouts();
* Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
if (usb->board->flags & GO7007_USB_EZUSB) {
/* Reset buffer in EZ-USB */
- dev_dbg(go->dev, "resetting EZ-USB buffers\n");
+ pr_debug("resetting EZ-USB buffers\n");
if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
return -1;
u16 status_reg = 0;
int timeout = 500;
- dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
+ pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
for (i = 0; i < 100; ++i) {
r = usb_control_msg(usb->usbdev,
int r;
int timeout = 500;
- dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
+ pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
go->usb_buf[0] = data & 0xff;
go->usb_buf[1] = data >> 8;
go->interrupt_available = 1;
go->interrupt_data = __le16_to_cpu(regs[0]);
go->interrupt_value = __le16_to_cpu(regs[1]);
- dev_dbg(go->dev, "ReadInterrupt: %04x %04x\n",
+ pr_debug("ReadInterrupt: %04x %04x\n",
go->interrupt_value, go->interrupt_data);
}
int transferred, pipe;
int timeout = 500;
- dev_dbg(go->dev, "DownloadBuffer sending %d bytes\n", len);
+ pr_debug("DownloadBuffer sending %d bytes\n", len);
if (usb->board->flags & GO7007_USB_EZUSB)
pipe = usb_sndbulkpipe(usb->usbdev, 2);
!(msgs[i].flags & I2C_M_RD) &&
(msgs[i + 1].flags & I2C_M_RD)) {
#ifdef GO7007_I2C_DEBUG
- dev_dbg(go->dev, "i2c write/read %d/%d bytes on %02x\n",
+ pr_debug("i2c write/read %d/%d bytes on %02x\n",
msgs[i].len, msgs[i + 1].len, msgs[i].addr);
#endif
buf[0] = 0x01;
buf[buf_len++] = msgs[++i].len;
} else if (msgs[i].flags & I2C_M_RD) {
#ifdef GO7007_I2C_DEBUG
- dev_dbg(go->dev, "i2c read %d bytes on %02x\n",
+ pr_debug("i2c read %d bytes on %02x\n",
msgs[i].len, msgs[i].addr);
#endif
buf[0] = 0x01;
buf_len = 4;
} else {
#ifdef GO7007_I2C_DEBUG
- dev_dbg(go->dev, "i2c write %d bytes on %02x\n",
+ pr_debug("i2c write %d bytes on %02x\n",
msgs[i].len, msgs[i].addr);
#endif
buf[0] = 0x00;
char *name;
int video_pipe, i, v_urb_len;
- dev_dbg(go->dev, "probing new GO7007 USB board\n");
+ pr_debug("probing new GO7007 USB board\n");
switch (id->driver_info) {
case GO7007_BOARDID_MATRIX_II:
board = &board_px_tv402u;
break;
case GO7007_BOARDID_LIFEVIEW_LR192:
- dev_err(go->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
+ dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
return -ENODEV;
name = "Lifeview TV Walker Ultra";
board = &board_lifeview_lr192;
break;
case GO7007_BOARDID_SENSORAY_2250:
- dev_info(go->dev, "Sensoray 2250 found\n");
+ dev_info(&intf->dev, "Sensoray 2250 found\n");
name = "Sensoray 2250/2251";
board = &board_sensoray_2250;
break;
board = &board_ads_usbav_709;
break;
default:
- dev_err(go->dev, "unknown board ID %d!\n",
+ dev_err(&intf->dev, "unknown board ID %d!\n",
(unsigned int)id->driver_info);
return -ENODEV;
}
sizeof(go->name));
break;
default:
- dev_dbg(go->dev, "unable to detect tuner type!\n");
+ pr_debug("unable to detect tuner type!\n");
break;
}
/* Configure tuner mode selection inputs connected
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
-#include <linux/clk/tegra.h>
#include "nvec.h"
dev_err(nvec->dev,
"RX buffer overflow on %p: "
"Trying to write byte %u of %u\n",
- nvec->rx, nvec->rx->pos, NVEC_MSG_SIZE);
+ nvec->rx, nvec->rx ? nvec->rx->pos : 0,
+ NVEC_MSG_SIZE);
break;
default:
nvec->state = 0;
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);
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;
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
+#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
* @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
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;
return _FAIL;
}
+ /* fix bug of flush_cam_entry at STOP AP mode */
+ psta->state |= WIFI_AP_STATE;
+ rtw_indicate_connect(padapter);
pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
return ret;
}
menuconfig TIDSPBRIDGE
tristate "DSP Bridge driver"
- depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM
+ depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN
select MAILBOX
select OMAP2PLUS_MBOX
help
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
pDevice->dev->name, pDevice->apdev->name);
}
- free_netdev(pDevice->apdev);
+ if (pDevice->apdev)
+ free_netdev(pDevice->apdev);
pDevice->apdev = NULL;
pDevice->bEnable8021x = false;
pDevice->bEnableHostWEP = false;
u8 * pbyAgc;
u16 wLengthAgc;
u8 abyArray[256];
+ u8 data;
ntStatus = CONTROLnsRequestIn(pDevice,
MESSAGE_TYPE_READ,
ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01);
RFbRFTableDownload(pDevice);
+
+ /* Fix for TX USB resets from vendors driver */
+ CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, USB_REG4,
+ MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
+ data |= 0x2;
+
+ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, USB_REG4,
+ MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
return true;//ntStatus;
}
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
pDevice->dev->name, pDevice->apdev->name);
}
- free_netdev(pDevice->apdev);
+ if (pDevice->apdev)
+ free_netdev(pDevice->apdev);
pDevice->apdev = NULL;
pDevice->bEnable8021x = false;
pDevice->bEnableHostWEP = false;
#define VIAUSB20_PACKET_HEADER 0x04
+#define USB_REG4 0x604
+
typedef struct _CMD_MESSAGE
{
u8 byData[256];
return -ENOMEM;
/* Do not reset an active device! */
- if (bdev->bd_holders)
- return -EBUSY;
+ if (bdev->bd_holders) {
+ ret = -EBUSY;
+ goto out;
+ }
ret = kstrtou16(buf, 10, &do_reset);
if (ret)
- return ret;
+ goto out;
- if (!do_reset)
- return -EINVAL;
+ if (!do_reset) {
+ ret = -EINVAL;
+ goto out;
+ }
/* Make sure all pending I/O is finished */
fsync_bdev(bdev);
+ bdput(bdev);
zram_reset_device(zram, true);
return len;
+
+out:
+ bdput(bdev);
+ return ret;
}
static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
return next;
}
-/* Encode <page, obj_idx> as a single handle value */
+/*
+ * Encode <page, obj_idx> as a single handle value.
+ * On hardware platforms with physical memory starting at 0x0 the pfn
+ * could be 0 so we ensure that the handle will never be 0 by adjusting the
+ * encoded obj_idx value before encoding.
+ */
static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
{
unsigned long handle;
}
handle = page_to_pfn(page) << OBJ_INDEX_BITS;
- handle |= (obj_idx & OBJ_INDEX_MASK);
+ handle |= ((obj_idx + 1) & OBJ_INDEX_MASK);
return (void *)handle;
}
-/* Decode <page, obj_idx> pair from the given object handle */
+/*
+ * Decode <page, obj_idx> pair from the given object handle. We adjust the
+ * decoded obj_idx back to its original value since it was adjusted in
+ * obj_location_to_handle().
+ */
static void obj_handle_to_location(unsigned long handle, struct page **page,
unsigned long *obj_idx)
{
*page = pfn_to_page(handle >> OBJ_INDEX_BITS);
- *obj_idx = handle & OBJ_INDEX_MASK;
+ *obj_idx = (handle & OBJ_INDEX_MASK) - 1;
}
static unsigned long obj_idx_to_offset(struct page *page,
*/
static int __init amiserial_console_init(void)
{
+ if (!MACH_IS_AMIGA)
+ return -ENODEV;
+
register_console(&sercons);
return 0;
}
* data at the tail to prevent a subsequent overrun */
while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
if (echo_buf(ldata, tail) == ECHO_OP_START) {
- if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB)
+ if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB)
tail += 3;
else
tail += 2;
found = 1;
size = N_TTY_BUF_SIZE - tail;
- n = (found + eol + size) & (N_TTY_BUF_SIZE - 1);
+ n = eol - tail;
+ if (n > 4096)
+ n += 4096;
+ n += found;
c = n;
if (found && read_buf(ldata, eol) == __DISABLED_CHAR) {
if (time)
timeout = time;
}
- mutex_unlock(&ldata->atomic_read_lock);
- remove_wait_queue(&tty->read_wait, &wait);
+ n_tty_set_room(tty);
+ up_read(&tty->termios_rwsem);
+ remove_wait_queue(&tty->read_wait, &wait);
if (!waitqueue_active(&tty->read_wait))
ldata->minimum_to_wake = minimum;
+ mutex_unlock(&ldata->atomic_read_lock);
+
__set_current_state(TASK_RUNNING);
if (b - buf)
retval = b - buf;
- n_tty_set_room(tty);
- up_read(&tty->termios_rwsem);
return retval;
}
accept kernel parameters in both forms like 8250_core.nr_uarts=4 and
8250.nr_uarts=4. We now renamed the module back to 8250, but if
anybody noticed in 3.7 and changed their userspace we still have to
- keep the 8350_core.* options around until they revert the changes
+ keep the 8250_core.* options around until they revert the changes
they already did.
If 8250 is built as a module, this adds 8250_core alias instead.
/* Probe ports */
pmz_probe();
+ if (pmz_ports_count == 0)
+ return -ENODEV;
+
/* TODO: Autoprobe console based on OF */
/* pmz_console.index = i; */
register_console(&pmz_console);
#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>
#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)
const struct tegra_uart_chip_data *cdata;
struct clk *uart_clk;
+ struct reset_control *rst;
unsigned int current_baud;
/* Register shadow */
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;
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;
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) {
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;
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);
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;
pm_runtime_get_sync(sci_port->port.dev);
- clk_enable(sci_port->iclk);
+ clk_prepare_enable(sci_port->iclk);
sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
- clk_enable(sci_port->fclk);
+ clk_prepare_enable(sci_port->fclk);
}
static void sci_port_disable(struct sci_port *sci_port)
if (!sci_port->port.dev)
return;
- clk_disable(sci_port->fclk);
- clk_disable(sci_port->iclk);
+ /* Cancel the break timer to ensure that the timer handler will not try
+ * to access the hardware with clocks and power disabled. Reset the
+ * break flag to make the break debouncing state machine ready for the
+ * next break.
+ */
+ del_timer_sync(&sci_port->break_timer);
+ sci_port->break_flag = 0;
+
+ clk_disable_unprepare(sci_port->fclk);
+ clk_disable_unprepare(sci_port->iclk);
pm_runtime_put_sync(sci_port->port.dev);
}
return 1;
/* Cast for ARM damage */
- return !!__raw_readb((void __iomem *)s->cfg->port_reg);
+ return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg);
}
/* ********************************************************************** *
{
struct sci_port *port = (struct sci_port *)data;
- sci_port_enable(port);
-
if (sci_rxd_in(&port->port) == 0) {
port->break_flag = 1;
sci_schedule_break_timer(port);
sci_schedule_break_timer(port);
} else
port->break_flag = 0;
-
- sci_port_disable(port);
}
static int sci_handle_errors(struct uart_port *port)
}
if (room < count)
- dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
+ dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
count - room);
if (!room)
return room;
int count;
chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
- dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
+ dev_dbg(port->dev, "Read %zu bytes with cookie %d\n",
sh_desc->partial, sh_desc->cookie);
spin_lock_irqsave(&port->lock, flags);
s->chan_tx = chan;
sg_init_table(&s->sg_tx, 1);
/* UART circular tx buffer is an aligned page. */
- BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
+ BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
- UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
+ UART_XMIT_SIZE,
+ (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
if (!nent)
sci_tx_dma_release(s, false);
else
- dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
- sg_dma_len(&s->sg_tx),
- port->state->xmit.buf, sg_dma_address(&s->sg_tx));
+ dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
+ sg_dma_len(&s->sg_tx), port->state->xmit.buf,
+ &sg_dma_address(&s->sg_tx));
s->sg_len_tx = nent;
sg_init_table(sg, 1);
sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
- (int)buf[i] & ~PAGE_MASK);
+ (uintptr_t)buf[i] & ~PAGE_MASK);
sg_dma_address(sg) = dma[i];
}
filp->f_op = &tty_fops;
goto retry_open;
}
+ clear_bit(TTY_HUPPED, &tty->flags);
tty_unlock(tty);
return -EINVAL;
mem = idev->info->mem + mi;
+ if (mem->addr & ~PAGE_MASK)
+ return -ENODEV;
if (vma->vm_end - vma->vm_start > mem->size)
return -EINVAL;
#if defined(CONFIG_ARCH_AT91SAM9RL)
-#include <mach/at91_pmc.h>
+#include <linux/clk/at91_pmc.h>
static void toggle_bias(int is_on)
{
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/gpio.h>
#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>
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;
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)) {
/* terminator */
}
};
+MODULE_DEVICE_TABLE(platform, atmel_lcdfb_devtypes);
static struct atmel_lcdfb_config *
atmel_lcdfb_get_config(struct platform_device *pdev)
return -EINVAL;
}
case KYRO_IOCTL_UVSTRIDE:
- if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long)))
+ if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride)))
return -EFAULT;
break;
case KYRO_IOCTL_STRIDE:
- if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long)))
+ if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride)))
return -EFAULT;
break;
case KYRO_IOCTL_OVERLAY_OFFSET:
- if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long)))
+ if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset)))
return -EFAULT;
break;
}
struct omap_dss_device *in = ddata->in;
int r;
+ mutex_lock(&ddata->mutex);
+
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
in->ops.sdi->set_timings(in, &ddata->videomode);
if (omapdss_device_is_enabled(dssdev))
return 0;
- mutex_lock(&ddata->mutex);
r = acx565akm_panel_power_on(dssdev);
- mutex_unlock(&ddata->mutex);
-
if (r)
return r;
* Power management
*/
+#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
static int sh_mobile_meram_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
meram_write_reg(priv->base, common_regs[i], priv->regs[i]);
return 0;
}
+#endif /* CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME */
static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops,
sh_mobile_meram_suspend,
+ sizeof(u32) * 16, GFP_KERNEL);
if (!fbi) {
dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
- ret = -ENOMEM;
- goto failed;
+ return -ENOMEM;
}
strcpy(fbi->fb.fix.id, "VT8500 LCD");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no I/O memory resource defined\n");
- ret = -ENODEV;
- goto failed_fbi;
+ return -ENODEV;
}
res = request_mem_region(res->start, resource_size(res), "vt8500lcd");
if (res == NULL) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
- ret = -EBUSY;
- goto failed_fbi;
+ return -EBUSY;
}
fbi->regbase = ioremap(res->start, resource_size(res));
}
disp_timing = of_get_display_timings(pdev->dev.of_node);
- if (!disp_timing)
- return -EINVAL;
+ if (!disp_timing) {
+ ret = -EINVAL;
+ goto failed_free_io;
+ }
ret = of_get_fb_videomode(pdev->dev.of_node, &of_mode,
OF_USE_NATIVE_MODE);
if (ret)
- return ret;
+ goto failed_free_io;
ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);
if (ret)
- return ret;
+ goto failed_free_io;
/* try allocating the framebuffer */
fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
GFP_KERNEL);
if (!fb_mem_virt) {
pr_err("%s: Failed to allocate framebuffer\n", __func__);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto failed_free_io;
}
fbi->fb.fix.smem_start = fb_mem_phys;
iounmap(fbi->regbase);
failed_free_res:
release_mem_region(res->start, resource_size(res));
-failed_fbi:
- kfree(fbi);
-failed:
return ret;
}
ret = m2p_add_override(mfn, pages[i], kmap_ops ?
&kmap_ops[i] : NULL);
if (ret)
- return ret;
+ goto out;
}
+ out:
if (lazy)
arch_leave_lazy_mmu_mode();
ret = m2p_remove_override(pages[i], kmap_ops ?
&kmap_ops[i] : NULL);
if (ret)
- return ret;
+ goto out;
}
+ out:
if (lazy)
arch_leave_lazy_mmu_mode();
sg_dma_len(sgl) = 0;
return 0;
}
+ xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT),
+ map & ~PAGE_MASK,
+ sg->length,
+ dir,
+ attrs);
sg->dma_address = xen_phys_to_bus(map);
} else {
/* we are not interested in the dma_addr returned by
Version 3.11
------------
-- Converted to use 2.3.x page cache [Dave Jones <dave@powertweak.com>]
+- Converted to use 2.3.x page cache [Dave Jones]
- Corruption in truncate() bugfix [Ken Tyler <kent@werple.net.au>]
Version 3.10
if (nr_pages > AIO_RING_PAGES) {
ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
GFP_KERNEL);
- if (!ctx->ring_pages)
+ if (!ctx->ring_pages) {
+ put_aio_ring_file(ctx);
return -ENOMEM;
+ }
}
ctx->mmap_size = nr_pages * PAGE_SIZE;
aio_nr + nr_events < aio_nr) {
spin_unlock(&aio_nr_lock);
err = -EAGAIN;
- goto err;
+ goto err_ctx;
}
aio_nr += ctx->max_reqs;
spin_unlock(&aio_nr_lock);
err_cleanup:
aio_nr_sub(ctx->max_reqs);
+err_ctx:
+ aio_free_ring(ctx);
err:
free_percpu(ctx->cpu);
free_percpu(ctx->reqs.pcpu_count);
static int btrfsic_read_block(struct btrfsic_state *state,
struct btrfsic_block_data_ctx *block_ctx);
static void btrfsic_dump_database(struct btrfsic_state *state);
-static void btrfsic_complete_bio_end_io(struct bio *bio, int err);
static int btrfsic_test_for_metadata(struct btrfsic_state *state,
char **datav, unsigned int num_pages);
static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state,
for (i = 0; i < num_pages;) {
struct bio *bio;
unsigned int j;
- DECLARE_COMPLETION_ONSTACK(complete);
bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i);
if (!bio) {
}
bio->bi_bdev = block_ctx->dev->bdev;
bio->bi_sector = dev_bytenr >> 9;
- bio->bi_end_io = btrfsic_complete_bio_end_io;
- bio->bi_private = &complete;
for (j = i; j < num_pages; j++) {
ret = bio_add_page(bio, block_ctx->pagev[j],
"btrfsic: error, failed to add a single page!\n");
return -1;
}
- submit_bio(READ, bio);
-
- /* this will also unplug the queue */
- wait_for_completion(&complete);
-
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+ if (submit_bio_wait(READ, bio)) {
printk(KERN_INFO
"btrfsic: read error at logical %llu dev %s!\n",
block_ctx->start, block_ctx->dev->name);
return block_ctx->len;
}
-static void btrfsic_complete_bio_end_io(struct bio *bio, int err)
-{
- complete((struct completion *)bio->bi_private);
-}
-
static void btrfsic_dump_database(struct btrfsic_state *state)
{
struct list_head *elem_all;
return submit_bh(rw, bh);
}
-void btrfsic_submit_bio(int rw, struct bio *bio)
+static void __btrfsic_submit_bio(int rw, struct bio *bio)
{
struct btrfsic_dev_state *dev_state;
- if (!btrfsic_is_initialized) {
- submit_bio(rw, bio);
+ if (!btrfsic_is_initialized)
return;
- }
mutex_lock(&btrfsic_mutex);
/* since btrfsic_submit_bio() is also called before
}
leave:
mutex_unlock(&btrfsic_mutex);
+}
+void btrfsic_submit_bio(int rw, struct bio *bio)
+{
+ __btrfsic_submit_bio(rw, bio);
submit_bio(rw, bio);
}
+int btrfsic_submit_bio_wait(int rw, struct bio *bio)
+{
+ __btrfsic_submit_bio(rw, bio);
+ return submit_bio_wait(rw, bio);
+}
+
int btrfsic_mount(struct btrfs_root *root,
struct btrfs_fs_devices *fs_devices,
int including_extent_data, u32 print_mask)
#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
int btrfsic_submit_bh(int rw, struct buffer_head *bh);
void btrfsic_submit_bio(int rw, struct bio *bio);
+int btrfsic_submit_bio_wait(int rw, struct bio *bio);
#else
#define btrfsic_submit_bh submit_bh
#define btrfsic_submit_bio submit_bio
+#define btrfsic_submit_bio_wait submit_bio_wait
#endif
int btrfsic_mount(struct btrfs_root *root,
return err;
}
-static void repair_io_failure_callback(struct bio *bio, int err)
-{
- complete(bio->bi_private);
-}
-
/*
* this bypasses the standard btrfs submit functions deliberately, as
* the standard behavior is to write all copies in a raid setup. here we only
{
struct bio *bio;
struct btrfs_device *dev;
- DECLARE_COMPLETION_ONSTACK(compl);
u64 map_length = 0;
u64 sector;
struct btrfs_bio *bbio = NULL;
bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
if (!bio)
return -EIO;
- bio->bi_private = &compl;
- bio->bi_end_io = repair_io_failure_callback;
bio->bi_size = 0;
map_length = length;
}
bio->bi_bdev = dev->bdev;
bio_add_page(bio, page, length, start - page_offset(page));
- btrfsic_submit_bio(WRITE_SYNC, bio);
- wait_for_completion(&compl);
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+ if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) {
/* try to remap that extent elsewhere? */
bio_put(bio);
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
int is_metadata, int have_csum,
const u8 *csum, u64 generation,
u16 csum_size);
-static void scrub_complete_bio_end_io(struct bio *bio, int err);
static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
struct scrub_block *sblock_good,
int force_write);
for (page_num = 0; page_num < sblock->page_count; page_num++) {
struct bio *bio;
struct scrub_page *page = sblock->pagev[page_num];
- DECLARE_COMPLETION_ONSTACK(complete);
if (page->dev->bdev == NULL) {
page->io_error = 1;
}
bio->bi_bdev = page->dev->bdev;
bio->bi_sector = page->physical >> 9;
- bio->bi_end_io = scrub_complete_bio_end_io;
- bio->bi_private = &complete;
bio_add_page(bio, page->page, PAGE_SIZE, 0);
- btrfsic_submit_bio(READ, bio);
-
- /* this will also unplug the queue */
- wait_for_completion(&complete);
-
- page->io_error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ if (btrfsic_submit_bio_wait(READ, bio))
sblock->no_io_error_seen = 0;
+
bio_put(bio);
}
sblock->checksum_error = 1;
}
-static void scrub_complete_bio_end_io(struct bio *bio, int err)
-{
- complete((struct completion *)bio->bi_private);
-}
-
static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
struct scrub_block *sblock_good,
int force_write)
sblock_bad->checksum_error || page_bad->io_error) {
struct bio *bio;
int ret;
- DECLARE_COMPLETION_ONSTACK(complete);
if (!page_bad->dev->bdev) {
printk_ratelimited(KERN_WARNING
return -EIO;
bio->bi_bdev = page_bad->dev->bdev;
bio->bi_sector = page_bad->physical >> 9;
- bio->bi_end_io = scrub_complete_bio_end_io;
- bio->bi_private = &complete;
ret = bio_add_page(bio, page_good->page, PAGE_SIZE, 0);
if (PAGE_SIZE != ret) {
bio_put(bio);
return -EIO;
}
- btrfsic_submit_bio(WRITE, bio);
- /* this will also unplug the queue */
- wait_for_completion(&complete);
- if (!bio_flagged(bio, BIO_UPTODATE)) {
+ if (btrfsic_submit_bio_wait(WRITE, bio)) {
btrfs_dev_stat_inc_and_print(page_bad->dev,
BTRFS_DEV_STAT_WRITE_ERRS);
btrfs_dev_replace_stats_inc(
struct bio *bio;
struct btrfs_device *dev;
int ret;
- DECLARE_COMPLETION_ONSTACK(compl);
dev = sctx->wr_ctx.tgtdev;
if (!dev)
spin_unlock(&sctx->stat_lock);
return -ENOMEM;
}
- bio->bi_private = &compl;
- bio->bi_end_io = scrub_complete_bio_end_io;
bio->bi_size = 0;
bio->bi_sector = physical_for_dev_replace >> 9;
bio->bi_bdev = dev->bdev;
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
return -EIO;
}
- btrfsic_submit_bio(WRITE_SYNC, bio);
- wait_for_completion(&compl);
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ if (btrfsic_submit_bio_wait(WRITE_SYNC, bio))
goto leave_with_eio;
bio_put(bio);
}
SetPageUptodate(page);
- if (err == 0)
+ if (err >= 0)
ceph_readpage_to_fscache(inode, page);
out:
{
struct ceph_inode_info *ci = ceph_inode(inode);
+ if (!PageFsCache(page))
+ return;
+
fscache_wait_on_page_write(ci->fscache, page);
fscache_uncache_page(ci->fscache, page);
}
* caller should hold i_ceph_lock.
* caller will not hold session s_mutex if called from destroy_inode.
*/
-void __ceph_remove_cap(struct ceph_cap *cap)
+void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
{
struct ceph_mds_session *session = cap->session;
struct ceph_inode_info *ci = cap->ci;
/* remove from session list */
spin_lock(&session->s_cap_lock);
+ /*
+ * s_cap_reconnect is protected by s_cap_lock. no one changes
+ * s_cap_gen while session is in the reconnect state.
+ */
+ if (queue_release &&
+ (!session->s_cap_reconnect ||
+ cap->cap_gen == session->s_cap_gen))
+ __queue_cap_release(session, ci->i_vino.ino, cap->cap_id,
+ cap->mseq, cap->issue_seq);
+
if (session->s_cap_iterator == cap) {
/* not yet, we are iterating over this very cap */
dout("__ceph_remove_cap delaying %p removal from session %p\n",
struct ceph_mds_cap_release *head;
struct ceph_mds_cap_item *item;
- spin_lock(&session->s_cap_lock);
BUG_ON(!session->s_num_cap_releases);
msg = list_first_entry(&session->s_cap_releases,
struct ceph_msg, list_head);
(int)CEPH_CAPS_PER_RELEASE,
(int)msg->front.iov_len);
}
- spin_unlock(&session->s_cap_lock);
}
/*
p = rb_first(&ci->i_caps);
while (p) {
struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
- struct ceph_mds_session *session = cap->session;
-
- __queue_cap_release(session, ceph_ino(inode), cap->cap_id,
- cap->mseq, cap->issue_seq);
p = rb_next(p);
- __ceph_remove_cap(cap);
+ __ceph_remove_cap(cap, true);
}
}
}
spin_unlock(&mdsc->cap_dirty_lock);
}
- __ceph_remove_cap(cap);
+ __ceph_remove_cap(cap, false);
}
/* else, we already released it */
if (!inode) {
dout(" i don't have ino %llx\n", vino.ino);
- if (op == CEPH_CAP_OP_IMPORT)
+ if (op == CEPH_CAP_OP_IMPORT) {
+ spin_lock(&session->s_cap_lock);
__queue_cap_release(session, vino.ino, cap_id,
mseq, seq);
+ spin_unlock(&session->s_cap_lock);
+ }
goto flush_cap_releases;
}
}
/* note next offset and last dentry name */
+ rinfo = &req->r_reply_info;
+ if (le32_to_cpu(rinfo->dir_dir->frag) != frag) {
+ frag = le32_to_cpu(rinfo->dir_dir->frag);
+ if (ceph_frag_is_leftmost(frag))
+ fi->next_offset = 2;
+ else
+ fi->next_offset = 0;
+ off = fi->next_offset;
+ }
fi->offset = fi->next_offset;
fi->last_readdir = req;
+ fi->frag = frag;
if (req->r_reply_info.dir_end) {
kfree(fi->last_name);
else
fi->next_offset = 0;
} else {
- rinfo = &req->r_reply_info;
err = note_last_dentry(fi,
rinfo->dir_dname[rinfo->dir_nr-1],
rinfo->dir_dname_len[rinfo->dir_nr-1]);
int issued = 0, implemented;
struct timespec mtime, atime, ctime;
u32 nsplits;
+ struct ceph_inode_frag *frag;
+ struct rb_node *rb_node;
struct ceph_buffer *xattr_blob = NULL;
int err = 0;
int queue_trunc = 0;
/* FIXME: move me up, if/when version reflects fragtree changes */
nsplits = le32_to_cpu(info->fragtree.nsplits);
mutex_lock(&ci->i_fragtree_mutex);
+ rb_node = rb_first(&ci->i_fragtree);
for (i = 0; i < nsplits; i++) {
u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
- struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
-
- if (IS_ERR(frag))
- continue;
+ frag = NULL;
+ while (rb_node) {
+ frag = rb_entry(rb_node, struct ceph_inode_frag, node);
+ if (ceph_frag_compare(frag->frag, id) >= 0) {
+ if (frag->frag != id)
+ frag = NULL;
+ else
+ rb_node = rb_next(rb_node);
+ break;
+ }
+ rb_node = rb_next(rb_node);
+ rb_erase(&frag->node, &ci->i_fragtree);
+ kfree(frag);
+ frag = NULL;
+ }
+ if (!frag) {
+ frag = __get_or_create_frag(ci, id);
+ if (IS_ERR(frag))
+ continue;
+ }
frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
dout(" frag %x split by %d\n", frag->frag, frag->split_by);
}
+ while (rb_node) {
+ frag = rb_entry(rb_node, struct ceph_inode_frag, node);
+ rb_node = rb_next(rb_node);
+ rb_erase(&frag->node, &ci->i_fragtree);
+ kfree(frag);
+ }
mutex_unlock(&ci->i_fragtree_mutex);
/* were we issued a capability? */
int err = 0, i;
struct inode *snapdir = NULL;
struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
- u64 frag = le32_to_cpu(rhead->args.readdir.frag);
struct ceph_dentry_info *di;
+ u64 r_readdir_offset = req->r_readdir_offset;
+ u32 frag = le32_to_cpu(rhead->args.readdir.frag);
+
+ if (rinfo->dir_dir &&
+ le32_to_cpu(rinfo->dir_dir->frag) != frag) {
+ dout("readdir_prepopulate got new frag %x -> %x\n",
+ frag, le32_to_cpu(rinfo->dir_dir->frag));
+ frag = le32_to_cpu(rinfo->dir_dir->frag);
+ if (ceph_frag_is_leftmost(frag))
+ r_readdir_offset = 2;
+ else
+ r_readdir_offset = 0;
+ }
if (req->r_aborted)
return readdir_prepopulate_inodes_only(req, session);
}
di = dn->d_fsdata;
- di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
+ di->offset = ceph_make_fpos(frag, i + r_readdir_offset);
/* inode */
if (dn->d_inode) {
*/
struct ceph_reconnect_state {
+ int nr_caps;
struct ceph_pagelist *pagelist;
bool flock;
};
INIT_LIST_HEAD(&s->s_waiting);
INIT_LIST_HEAD(&s->s_unsafe);
s->s_num_cap_releases = 0;
+ s->s_cap_reconnect = 0;
s->s_cap_iterator = NULL;
INIT_LIST_HEAD(&s->s_cap_releases);
INIT_LIST_HEAD(&s->s_cap_releases_done);
req->r_unsafe_dir = NULL;
}
+ complete_all(&req->r_safe_completion);
+
ceph_mdsc_put_request(req);
}
dout("removing cap %p, ci is %p, inode is %p\n",
cap, ci, &ci->vfs_inode);
spin_lock(&ci->i_ceph_lock);
- __ceph_remove_cap(cap);
+ __ceph_remove_cap(cap, false);
if (!__ceph_is_any_real_caps(ci)) {
struct ceph_mds_client *mdsc =
ceph_sb_to_client(inode->i_sb)->mdsc;
session->s_trim_caps--;
if (oissued) {
/* we aren't the only cap.. just remove us */
- __queue_cap_release(session, ceph_ino(inode), cap->cap_id,
- cap->mseq, cap->issue_seq);
- __ceph_remove_cap(cap);
+ __ceph_remove_cap(cap, true);
} else {
/* try to drop referring dentries */
spin_unlock(&ci->i_ceph_lock);
unsigned num;
dout("discard_cap_releases mds%d\n", session->s_mds);
- spin_lock(&session->s_cap_lock);
/* zero out the in-progress message */
msg = list_first_entry(&session->s_cap_releases,
msg->front.iov_len = sizeof(*head);
list_add(&msg->list_head, &session->s_cap_releases);
}
-
- spin_unlock(&session->s_cap_lock);
}
/*
int mds = -1;
int err = -EAGAIN;
- if (req->r_err || req->r_got_result)
+ if (req->r_err || req->r_got_result) {
+ if (req->r_aborted)
+ __unregister_request(mdsc, req);
goto out;
+ }
if (req->r_timeout &&
time_after_eq(jiffies, req->r_started + req->r_timeout)) {
if (head->safe) {
req->r_got_safe = true;
__unregister_request(mdsc, req);
- complete_all(&req->r_safe_completion);
if (req->r_got_unsafe) {
/*
err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
if (err == 0) {
if (result == 0 && (req->r_op == CEPH_MDS_OP_READDIR ||
- req->r_op == CEPH_MDS_OP_LSSNAP) &&
- rinfo->dir_nr)
+ req->r_op == CEPH_MDS_OP_LSSNAP))
ceph_readdir_prepopulate(req, req->r_session);
ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
}
cap->seq = 0; /* reset cap seq */
cap->issue_seq = 0; /* and issue_seq */
cap->mseq = 0; /* and migrate_seq */
+ cap->cap_gen = cap->session->s_cap_gen;
if (recon_state->flock) {
rec.v2.cap_id = cpu_to_le64(cap->cap_id);
} else {
err = ceph_pagelist_append(pagelist, &rec, reclen);
}
+
+ recon_state->nr_caps++;
out_free:
kfree(path);
out_dput:
struct rb_node *p;
int mds = session->s_mds;
int err = -ENOMEM;
+ int s_nr_caps;
struct ceph_pagelist *pagelist;
struct ceph_reconnect_state recon_state;
dout("session %p state %s\n", session,
session_state_name(session->s_state));
+ spin_lock(&session->s_gen_ttl_lock);
+ session->s_cap_gen++;
+ spin_unlock(&session->s_gen_ttl_lock);
+
+ spin_lock(&session->s_cap_lock);
+ /*
+ * notify __ceph_remove_cap() that we are composing cap reconnect.
+ * If a cap get released before being added to the cap reconnect,
+ * __ceph_remove_cap() should skip queuing cap release.
+ */
+ session->s_cap_reconnect = 1;
/* drop old cap expires; we're about to reestablish that state */
discard_cap_releases(mdsc, session);
+ spin_unlock(&session->s_cap_lock);
/* traverse this session's caps */
- err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
+ s_nr_caps = session->s_nr_caps;
+ err = ceph_pagelist_encode_32(pagelist, s_nr_caps);
if (err)
goto fail;
+ recon_state.nr_caps = 0;
recon_state.pagelist = pagelist;
recon_state.flock = session->s_con.peer_features & CEPH_FEATURE_FLOCK;
err = iterate_session_caps(session, encode_caps_cb, &recon_state);
if (err < 0)
goto fail;
+ spin_lock(&session->s_cap_lock);
+ session->s_cap_reconnect = 0;
+ spin_unlock(&session->s_cap_lock);
+
/*
* snaprealms. we provide mds with the ino, seq (version), and
* parent for all of our realms. If the mds has any newer info,
if (recon_state.flock)
reply->hdr.version = cpu_to_le16(2);
- if (pagelist->length) {
- /* set up outbound data if we have any */
- reply->hdr.data_len = cpu_to_le32(pagelist->length);
- ceph_msg_data_add_pagelist(reply, pagelist);
+
+ /* raced with cap release? */
+ if (s_nr_caps != recon_state.nr_caps) {
+ struct page *page = list_first_entry(&pagelist->head,
+ struct page, lru);
+ __le32 *addr = kmap_atomic(page);
+ *addr = cpu_to_le32(recon_state.nr_caps);
+ kunmap_atomic(addr);
}
+
+ reply->hdr.data_len = cpu_to_le32(pagelist->length);
+ ceph_msg_data_add_pagelist(reply, pagelist);
ceph_con_send(&session->s_con, reply);
mutex_unlock(&session->s_mutex);
struct list_head s_caps; /* all caps issued by this session */
int s_nr_caps, s_trim_caps;
int s_num_cap_releases;
+ int s_cap_reconnect;
struct list_head s_cap_releases; /* waiting cap_release messages */
struct list_head s_cap_releases_done; /* ready to send */
struct ceph_cap *s_cap_iterator;
int fmode, unsigned issued, unsigned wanted,
unsigned cap, unsigned seq, u64 realmino, int flags,
struct ceph_cap_reservation *caps_reservation);
-extern void __ceph_remove_cap(struct ceph_cap *cap);
-static inline void ceph_remove_cap(struct ceph_cap *cap)
-{
- spin_lock(&cap->ci->i_ceph_lock);
- __ceph_remove_cap(cap);
- spin_unlock(&cap->ci->i_ceph_lock);
-}
+extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release);
extern void ceph_put_cap(struct ceph_mds_client *mdsc,
struct ceph_cap *cap);
int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file,
struct cifsFileInfo *target_file, u64 src_off, u64 len,
u64 dest_off);
+ int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
};
struct smb_version_values {
#include <linux/mount.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/btrfs.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifsfs.h"
+#define CIFS_IOCTL_MAGIC 0xCF
+#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
+
static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
unsigned long srcfd, u64 off, u64 len, u64 destoff)
{
cifs_dbg(FYI, "set compress flag rc %d\n", rc);
}
break;
- case BTRFS_IOC_CLONE:
+ case CIFS_IOC_COPYCHUNK_FILE:
rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0);
break;
default:
int rc;
unsigned int ret_data_len;
struct copychunk_ioctl *pcchunk;
- char *retbuf = NULL;
+ struct copychunk_ioctl_rsp *retbuf = NULL;
+ struct cifs_tcon *tcon;
+ int chunks_copied = 0;
+ bool chunk_sizes_updated = false;
pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
/* Note: request_res_key sets res_key null only if rc !=0 */
if (rc)
- return rc;
+ goto cchunk_out;
/* For now array only one chunk long, will make more flexible later */
pcchunk->ChunkCount = __constant_cpu_to_le32(1);
pcchunk->Reserved = 0;
- pcchunk->SourceOffset = cpu_to_le64(src_off);
- pcchunk->TargetOffset = cpu_to_le64(dest_off);
- pcchunk->Length = cpu_to_le32(len);
pcchunk->Reserved2 = 0;
- /* Request that server copy to target from src file identified by key */
- rc = SMB2_ioctl(xid, tlink_tcon(trgtfile->tlink),
- trgtfile->fid.persistent_fid,
- trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
- true /* is_fsctl */, (char *)pcchunk,
- sizeof(struct copychunk_ioctl), &retbuf, &ret_data_len);
+ tcon = tlink_tcon(trgtfile->tlink);
- /* BB need to special case rc = EINVAL to alter chunk size */
+ while (len > 0) {
+ pcchunk->SourceOffset = cpu_to_le64(src_off);
+ pcchunk->TargetOffset = cpu_to_le64(dest_off);
+ pcchunk->Length =
+ cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
- cifs_dbg(FYI, "rc %d data length out %d\n", rc, ret_data_len);
+ /* Request server copy to target from src identified by key */
+ rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
+ trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
+ true /* is_fsctl */, (char *)pcchunk,
+ sizeof(struct copychunk_ioctl), (char **)&retbuf,
+ &ret_data_len);
+ if (rc == 0) {
+ if (ret_data_len !=
+ sizeof(struct copychunk_ioctl_rsp)) {
+ cifs_dbg(VFS, "invalid cchunk response size\n");
+ rc = -EIO;
+ goto cchunk_out;
+ }
+ if (retbuf->TotalBytesWritten == 0) {
+ cifs_dbg(FYI, "no bytes copied\n");
+ rc = -EIO;
+ goto cchunk_out;
+ }
+ /*
+ * Check if server claimed to write more than we asked
+ */
+ if (le32_to_cpu(retbuf->TotalBytesWritten) >
+ le32_to_cpu(pcchunk->Length)) {
+ cifs_dbg(VFS, "invalid copy chunk response\n");
+ rc = -EIO;
+ goto cchunk_out;
+ }
+ if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
+ cifs_dbg(VFS, "invalid num chunks written\n");
+ rc = -EIO;
+ goto cchunk_out;
+ }
+ chunks_copied++;
+
+ src_off += le32_to_cpu(retbuf->TotalBytesWritten);
+ dest_off += le32_to_cpu(retbuf->TotalBytesWritten);
+ len -= le32_to_cpu(retbuf->TotalBytesWritten);
+
+ cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n",
+ le32_to_cpu(retbuf->ChunksWritten),
+ le32_to_cpu(retbuf->ChunkBytesWritten),
+ le32_to_cpu(retbuf->TotalBytesWritten));
+ } else if (rc == -EINVAL) {
+ if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
+ goto cchunk_out;
+
+ cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
+ le32_to_cpu(retbuf->ChunksWritten),
+ le32_to_cpu(retbuf->ChunkBytesWritten),
+ le32_to_cpu(retbuf->TotalBytesWritten));
+
+ /*
+ * Check if this is the first request using these sizes,
+ * (ie check if copy succeed once with original sizes
+ * and check if the server gave us different sizes after
+ * we already updated max sizes on previous request).
+ * if not then why is the server returning an error now
+ */
+ if ((chunks_copied != 0) || chunk_sizes_updated)
+ goto cchunk_out;
+
+ /* Check that server is not asking us to grow size */
+ if (le32_to_cpu(retbuf->ChunkBytesWritten) <
+ tcon->max_bytes_chunk)
+ tcon->max_bytes_chunk =
+ le32_to_cpu(retbuf->ChunkBytesWritten);
+ else
+ goto cchunk_out; /* server gave us bogus size */
+
+ /* No need to change MaxChunks since already set to 1 */
+ chunk_sizes_updated = true;
+ }
+ }
+cchunk_out:
kfree(pcchunk);
return rc;
}
.create_lease_buf = smb3_create_lease_buf,
.parse_lease_buf = smb3_parse_lease_buf,
.clone_range = smb2_clone_range,
+ .validate_negotiate = smb3_validate_negotiate,
};
struct smb_version_values smb20_values = {
return rc;
}
+int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+{
+ int rc = 0;
+ struct validate_negotiate_info_req vneg_inbuf;
+ struct validate_negotiate_info_rsp *pneg_rsp;
+ u32 rsplen;
+
+ cifs_dbg(FYI, "validate negotiate\n");
+
+ /*
+ * validation ioctl must be signed, so no point sending this if we
+ * can not sign it. We could eventually change this to selectively
+ * sign just this, the first and only signed request on a connection.
+ * This is good enough for now since a user who wants better security
+ * would also enable signing on the mount. Having validation of
+ * negotiate info for signed connections helps reduce attack vectors
+ */
+ if (tcon->ses->server->sign == false)
+ return 0; /* validation requires signing */
+
+ vneg_inbuf.Capabilities =
+ cpu_to_le32(tcon->ses->server->vals->req_capabilities);
+ memcpy(vneg_inbuf.Guid, cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
+
+ if (tcon->ses->sign)
+ vneg_inbuf.SecurityMode =
+ cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
+ else if (global_secflags & CIFSSEC_MAY_SIGN)
+ vneg_inbuf.SecurityMode =
+ cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
+ else
+ vneg_inbuf.SecurityMode = 0;
+
+ vneg_inbuf.DialectCount = cpu_to_le16(1);
+ vneg_inbuf.Dialects[0] =
+ cpu_to_le16(tcon->ses->server->vals->protocol_id);
+
+ rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+ FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
+ (char *)&vneg_inbuf, sizeof(struct validate_negotiate_info_req),
+ (char **)&pneg_rsp, &rsplen);
+
+ if (rc != 0) {
+ cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
+ return -EIO;
+ }
+
+ if (rsplen != sizeof(struct validate_negotiate_info_rsp)) {
+ cifs_dbg(VFS, "invalid size of protocol negotiate response\n");
+ return -EIO;
+ }
+
+ /* check validate negotiate info response matches what we got earlier */
+ if (pneg_rsp->Dialect !=
+ cpu_to_le16(tcon->ses->server->vals->protocol_id))
+ goto vneg_out;
+
+ if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode))
+ goto vneg_out;
+
+ /* do not validate server guid because not saved at negprot time yet */
+
+ if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
+ SMB2_LARGE_FILES) != tcon->ses->server->capabilities)
+ goto vneg_out;
+
+ /* validate negotiate successful */
+ cifs_dbg(FYI, "validate negotiate info successful\n");
+ return 0;
+
+vneg_out:
+ cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
+ return -EIO;
+}
+
int
SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
init_copy_chunk_defaults(tcon);
+ if (tcon->ses->server->ops->validate_negotiate)
+ rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
tcon_exit:
free_rsp_buf(resp_buftype, rsp);
kfree(unc_path);
rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
- if (rc != 0) {
+ if ((rc != 0) && (rc != -EINVAL)) {
if (tcon)
cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
goto ioctl_exit;
+ } else if (rc == -EINVAL) {
+ if ((opcode != FSCTL_SRV_COPYCHUNK_WRITE) &&
+ (opcode != FSCTL_SRV_COPYCHUNK)) {
+ if (tcon)
+ cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
+ goto ioctl_exit;
+ }
}
/* check if caller wants to look at return data or just return rc */
rc = SendReceive2(xid, ses, iov, num, &resp_buftype, 0);
rsp = (struct smb2_set_info_rsp *)iov[0].iov_base;
- if (rc != 0) {
+ if (rc != 0)
cifs_stats_fail_inc(tcon, SMB2_SET_INFO_HE);
- goto out;
- }
-out:
+
free_rsp_buf(resp_buftype, rsp);
kfree(iov);
return rc;
__le32 TotalBytesWritten;
} __packed;
-/* Response and Request are the same format */
-struct validate_negotiate_info {
+struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
- __le16 Dialect[1];
+ __le16 Dialects[1]; /* dialect (someday maybe list) client asked for */
+} __packed;
+
+struct validate_negotiate_info_rsp {
+ __le32 Capabilities;
+ __u8 Guid[SMB2_CLIENT_GUID_SIZE];
+ __le16 SecurityMode;
+ __le16 Dialect; /* Dialect in use for the connection */
} __packed;
#define RSS_CAPABLE 0x00000001
struct smb2_lock_element *buf);
extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
__u8 *lease_key, const __le32 lease_state);
+extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
#endif /* _SMB2PROTO_H */
#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4 /* BB add struct */
#define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
#define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */
-#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204 /* BB add struct */
+#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
/* Perform server-side data movement */
#define FSCTL_SRV_COPYCHUNK 0x001440F2
#define FSCTL_SRV_COPYCHUNK_WRITE 0x001480F2
goto error_tgt_fput;
/* Check if EPOLLWAKEUP is allowed */
- if ((epds.events & EPOLLWAKEUP) && !capable(CAP_BLOCK_SUSPEND))
- epds.events &= ~EPOLLWAKEUP;
+ ep_take_care_of_epollwakeup(&epds);
/*
* We have to check that the file structure underneath the file descriptor
u16 embed_count;
};
-static void hfsplus_end_io_sync(struct bio *bio, int err)
-{
- if (err)
- clear_bit(BIO_UPTODATE, &bio->bi_flags);
- complete(bio->bi_private);
-}
-
/*
* hfsplus_submit_bio - Perfrom block I/O
* @sb: super block of volume for I/O
int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
void *buf, void **data, int rw)
{
- DECLARE_COMPLETION_ONSTACK(wait);
struct bio *bio;
int ret = 0;
u64 io_size;
bio = bio_alloc(GFP_NOIO, 1);
bio->bi_sector = sector;
bio->bi_bdev = sb->s_bdev;
- bio->bi_end_io = hfsplus_end_io_sync;
- bio->bi_private = &wait;
if (!(rw & WRITE) && data)
*data = (u8 *)buf + offset;
buf = (u8 *)buf + len;
}
- submit_bio(rw, bio);
- wait_for_completion(&wait);
-
- if (!bio_flagged(bio, BIO_UPTODATE))
- ret = -EIO;
-
+ ret = submit_bio_wait(rw, bio);
out:
bio_put(bio);
return ret < 0 ? ret : 0;
#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
-static void request_complete(struct bio *bio, int err)
-{
- complete((struct completion *)bio->bi_private);
-}
-
static int sync_request(struct page *page, struct block_device *bdev, int rw)
{
struct bio bio;
struct bio_vec bio_vec;
- struct completion complete;
bio_init(&bio);
bio.bi_max_vecs = 1;
bio.bi_size = PAGE_SIZE;
bio.bi_bdev = bdev;
bio.bi_sector = page->index * (PAGE_SIZE >> 9);
- init_completion(&complete);
- bio.bi_private = &complete;
- bio.bi_end_io = request_complete;
- submit_bio(rw, &bio);
- wait_for_completion(&complete);
- return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO;
+ return submit_bio_wait(rw, &bio);
}
static int bdev_readpage(void *_sb, struct page *page)
if (!lockref_get_not_dead(&parent->d_lockref)) {
nd->path.dentry = NULL;
- rcu_read_unlock();
- return -ECHILD;
+ goto out;
}
/*
#include <linux/nfs_fs.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
+#include "../nfs4_fs.h"
#include "../pnfs.h"
#include "../netns.h"
static inline sector_t normalize(sector_t s, int base)
{
sector_t tmp = s; /* Since do_div modifies its argument */
- return s - do_div(tmp, base);
+ return s - sector_div(tmp, base);
}
static inline sector_t normalize_up(sector_t s, int base)
#include <linux/sunrpc/cache.h>
#include <linux/sunrpc/svcauth.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
+#include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
#include "dns_resolve.h"
#include "cache_lib.h"
#include "netns.h"
}
EXPORT_SYMBOL_GPL(nfs4_label_alloc);
#else
-void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
+void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
struct nfs4_label *label)
{
}
extern struct rpc_procinfo nfs4_procedures[];
#endif
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
+static inline void nfs4_label_free(struct nfs4_label *label)
+{
+ if (label) {
+ kfree(label->label);
+ kfree(label);
+ }
+ return;
+}
+#else
+static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
+static inline void nfs4_label_free(void *label) {}
+#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
+
/* proc.c */
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
#ifndef __LINUX_FS_NFS_NFS4_FS_H
#define __LINUX_FS_NFS_NFS4_FS_H
+#if defined(CONFIG_NFS_V4_2)
+#define NFS4_MAX_MINOR_VERSION 2
+#elif defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MINOR_VERSION 1
+#else
+#define NFS4_MAX_MINOR_VERSION 0
+#endif
+
#if IS_ENABLED(CONFIG_NFS_V4)
#define NFS4_MAX_LOOP_ON_RECOVER (10)
calldata->roc_barrier);
nfs_set_open_stateid(state, &calldata->res.stateid, 0);
renew_lease(server, calldata->timestamp);
- nfs4_close_clear_stateid_flags(state,
- calldata->arg.fmode);
break;
+ case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_OLD_STATEID:
case -NFS4ERR_BAD_STATEID:
if (calldata->arg.fmode == 0)
break;
default:
- if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
+ if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
rpc_restart_call_prepare(task);
+ goto out_release;
+ }
}
+ nfs4_close_clear_stateid_flags(state, calldata->arg.fmode);
+out_release:
nfs_release_seqid(calldata->arg.seqid);
nfs_refresh_inode(calldata->inode, calldata->res.fattr);
dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
dprintk("%s ERROR %d, Reset session\n", __func__,
task->tk_status);
nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
- goto restart_call;
+ goto wait_on_recovery;
#endif /* CONFIG_NFS_V4_1 */
case -NFS4ERR_DELAY:
nfs_inc_server_stats(server, NFSIOS_DELAY);
trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
switch (task->tk_status) {
- case -NFS4ERR_STALE_STATEID:
- case -NFS4ERR_EXPIRED:
case 0:
renew_lease(data->res.server, data->timestamp);
break;
+ case -NFS4ERR_ADMIN_REVOKED:
+ case -NFS4ERR_DELEG_REVOKED:
+ case -NFS4ERR_BAD_STATEID:
+ case -NFS4ERR_OLD_STATEID:
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_EXPIRED:
+ task->tk_status = 0;
+ break;
default:
if (nfs4_async_handle_error(task, data->res.server, NULL) ==
-EAGAIN) {
return;
server = NFS_SERVER(lrp->args.inode);
- if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
+ switch (task->tk_status) {
+ default:
+ task->tk_status = 0;
+ case 0:
+ break;
+ case -NFS4ERR_DELAY:
+ if (nfs4_async_handle_error(task, server, NULL) != -EAGAIN)
+ break;
rpc_restart_call_prepare(task);
return;
}
return mask;
}
+static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
+{
+ int kill = 0;
+
+ spin_lock(&inode->i_lock);
+ if (!--pipe->files) {
+ inode->i_pipe = NULL;
+ kill = 1;
+ }
+ spin_unlock(&inode->i_lock);
+
+ if (kill)
+ free_pipe_info(pipe);
+}
+
static int
pipe_release(struct inode *inode, struct file *file)
{
- struct pipe_inode_info *pipe = inode->i_pipe;
- int kill = 0;
+ struct pipe_inode_info *pipe = file->private_data;
__pipe_lock(pipe);
if (file->f_mode & FMODE_READ)
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
}
- spin_lock(&inode->i_lock);
- if (!--pipe->files) {
- inode->i_pipe = NULL;
- kill = 1;
- }
- spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
- if (kill)
- free_pipe_info(pipe);
-
+ put_pipe_info(inode, pipe);
return 0;
}
{
struct pipe_inode_info *pipe;
bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
- int kill = 0;
int ret;
filp->f_version = 0;
goto err;
err:
- spin_lock(&inode->i_lock);
- if (!--pipe->files) {
- inode->i_pipe = NULL;
- kill = 1;
- }
- spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
- if (kill)
- free_pipe_info(pipe);
+
+ put_pipe_info(inode, pipe);
return ret;
}
*/
res = squashfs_read_cache(target_page, block, bsize, pages,
page);
+ if (res < 0)
+ goto mark_errored;
+
goto out;
}
* dealt with by the caller
*/
for (i = 0; i < pages; i++) {
- if (page[i] == target_page)
+ if (page[i] == NULL || page[i] == target_page)
continue;
flush_dcache_page(page[i]);
SetPageError(page[i]);
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
struct sysfs_open_file *of;
- bool has_read, has_write;
+ bool has_read, has_write, has_mmap;
int error = -EACCES;
/* need attr_sd for attr and ops, its parent for kobj */
has_read = battr->read || battr->mmap;
has_write = battr->write || battr->mmap;
+ has_mmap = battr->mmap;
} else {
const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
has_read = ops->show;
has_write = ops->store;
+ has_mmap = false;
}
/* check perms and supported operations */
if (!of)
goto err_out;
- mutex_init(&of->mutex);
+ /*
+ * The following is done to give a different lockdep key to
+ * @of->mutex for files which implement mmap. This is a rather
+ * crude way to avoid false positive lockdep warning around
+ * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and
+ * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under
+ * which mm->mmap_sem nests, while holding @of->mutex. As each
+ * open file has a separate mutex, it's okay as long as those don't
+ * happen on the same file. At this point, we can't easily give
+ * each file a separate locking class. Let's differentiate on
+ * whether the file has mmap or not for now.
+ */
+ if (has_mmap)
+ mutex_init(&of->mutex);
+ else
+ mutex_init(&of->mutex);
+
of->sd = attr_sd;
of->file = file;
* Should the subsystem abort the loading of an ACPI table if the
* table checksum is incorrect?
*/
+#ifndef ACPI_CHECKSUM_ABORT
#define ACPI_CHECKSUM_ABORT FALSE
+#endif
/*
* Generate a version of ACPICA that only supports "reduced hardware"
struct acpi_hotplug_profile {
struct kobject kobj;
bool enabled:1;
+ bool ignore:1;
enum acpi_hotplug_mode mode;
};
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20130927
+#define ACPI_CA_VERSION 0x20131115
#include <acpi/acconfig.h>
#include <acpi/actypes.h>
--- /dev/null
+
+#include <linux/hardirq.h>
+
+/*
+ * may_use_simd - whether it is allowable at this time to issue SIMD
+ * instructions or access the SIMD register file
+ *
+ * As architectures typically don't preserve the SIMD register file when
+ * taking an interrupt, !in_interrupt() should be a reasonable default.
+ */
+static __must_check inline bool may_use_simd(void)
+{
+ return !in_interrupt();
+}
return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC;
}
-#endif /* _CRYPTO_ALGAPI_H */
+noinline unsigned long __crypto_memneq(const void *a, const void *b, size_t size);
+
+/**
+ * crypto_memneq - Compare two areas of memory without leaking
+ * timing information.
+ *
+ * @a: One area of memory
+ * @b: Another area of memory
+ * @size: The size of the area.
+ *
+ * Returns 0 when data is equal, 1 otherwise.
+ */
+static inline int crypto_memneq(const void *a, const void *b, size_t size)
+{
+ return __crypto_memneq(a, b, size) != 0UL ? 1 : 0;
+}
+#endif /* _CRYPTO_ALGAPI_H */
__be32 enckeylen;
};
-#endif /* _CRYPTO_AUTHENC_H */
+struct crypto_authenc_keys {
+ const u8 *authkey;
+ const u8 *enckey;
+
+ unsigned int authkeylen;
+ unsigned int enckeylen;
+};
+int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
+ unsigned int keylen);
+
+#endif /* _CRYPTO_AUTHENC_H */
{
sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
sg1[num - 1].page_link &= ~0x02;
+ sg1[num - 1].page_link |= 0x01;
}
static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
--- /dev/null
+/*
+ * This header provides constants for AT91 pmc status.
+ *
+ * The constants defined in this header are being used in dts.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef _DT_BINDINGS_CLK_AT91_H
+#define _DT_BINDINGS_CLK_AT91_H
+
+#define AT91_PMC_MOSCS 0 /* MOSCS Flag */
+#define AT91_PMC_LOCKA 1 /* PLLA Lock */
+#define AT91_PMC_LOCKB 2 /* PLLB Lock */
+#define AT91_PMC_MCKRDY 3 /* Master Clock */
+#define AT91_PMC_LOCKU 6 /* UPLL Lock */
+#define AT91_PMC_PCKRDY(id) (8 + (id)) /* Programmable Clock */
+#define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */
+#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */
+#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */
+
+#endif
--- /dev/null
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7790_H__
+#define __DT_BINDINGS_CLOCK_R8A7790_H__
+
+/* CPG */
+#define R8A7790_CLK_MAIN 0
+#define R8A7790_CLK_PLL0 1
+#define R8A7790_CLK_PLL1 2
+#define R8A7790_CLK_PLL3 3
+#define R8A7790_CLK_LB 4
+#define R8A7790_CLK_QSPI 5
+#define R8A7790_CLK_SDH 6
+#define R8A7790_CLK_SD0 7
+#define R8A7790_CLK_SD1 8
+#define R8A7790_CLK_Z 9
+
+/* MSTP0 */
+#define R8A7790_CLK_MSIOF0 0
+
+/* MSTP1 */
+#define R8A7790_CLK_TMU1 11
+#define R8A7790_CLK_TMU3 21
+#define R8A7790_CLK_TMU2 22
+#define R8A7790_CLK_CMT0 24
+#define R8A7790_CLK_TMU0 25
+#define R8A7790_CLK_VSP1_DU1 27
+#define R8A7790_CLK_VSP1_DU0 28
+#define R8A7790_CLK_VSP1_RT 30
+#define R8A7790_CLK_VSP1_SY 31
+
+/* MSTP2 */
+#define R8A7790_CLK_SCIFA2 2
+#define R8A7790_CLK_SCIFA1 3
+#define R8A7790_CLK_SCIFA0 4
+#define R8A7790_CLK_MSIOF2 5
+#define R8A7790_CLK_SCIFB0 6
+#define R8A7790_CLK_SCIFB1 7
+#define R8A7790_CLK_MSIOF1 8
+#define R8A7790_CLK_MSIOF3 15
+#define R8A7790_CLK_SCIFB2 16
+#define R8A7790_CLK_SYS_DMAC0 18
+#define R8A7790_CLK_SYS_DMAC1 19
+
+/* MSTP3 */
+#define R8A7790_CLK_TPU0 4
+#define R8A7790_CLK_MMCIF1 5
+#define R8A7790_CLK_SDHI3 11
+#define R8A7790_CLK_SDHI2 12
+#define R8A7790_CLK_SDHI1 13
+#define R8A7790_CLK_SDHI0 14
+#define R8A7790_CLK_MMCIF0 15
+#define R8A7790_CLK_SSUSB 28
+#define R8A7790_CLK_CMT1 29
+#define R8A7790_CLK_USBDMAC0 30
+#define R8A7790_CLK_USBDMAC1 31
+
+/* MSTP5 */
+#define R8A7790_CLK_THERMAL 22
+#define R8A7790_CLK_PWM 23
+
+/* MSTP7 */
+#define R8A7790_CLK_EHCI 3
+#define R8A7790_CLK_HSUSB 4
+#define R8A7790_CLK_HSCIF1 16
+#define R8A7790_CLK_HSCIF0 17
+#define R8A7790_CLK_SCIF1 20
+#define R8A7790_CLK_SCIF0 21
+#define R8A7790_CLK_DU2 22
+#define R8A7790_CLK_DU1 23
+#define R8A7790_CLK_DU0 24
+#define R8A7790_CLK_LVDS1 25
+#define R8A7790_CLK_LVDS0 26
+
+/* MSTP8 */
+#define R8A7790_CLK_VIN3 8
+#define R8A7790_CLK_VIN2 9
+#define R8A7790_CLK_VIN1 10
+#define R8A7790_CLK_VIN0 11
+#define R8A7790_CLK_ETHER 13
+#define R8A7790_CLK_SATA1 14
+#define R8A7790_CLK_SATA0 15
+
+/* MSTP9 */
+#define R8A7790_CLK_GPIO5 7
+#define R8A7790_CLK_GPIO4 8
+#define R8A7790_CLK_GPIO3 9
+#define R8A7790_CLK_GPIO2 10
+#define R8A7790_CLK_GPIO1 11
+#define R8A7790_CLK_GPIO0 12
+#define R8A7790_CLK_RCAN1 15
+#define R8A7790_CLK_RCAN0 16
+#define R8A7790_CLK_QSPI_MOD 17
+#define R8A7790_CLK_IICDVFS 26
+#define R8A7790_CLK_I2C3 28
+#define R8A7790_CLK_I2C2 29
+#define R8A7790_CLK_I2C1 30
+#define R8A7790_CLK_I2C0 31
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7790_H__ */
--- /dev/null
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7791_H__
+#define __DT_BINDINGS_CLOCK_R8A7791_H__
+
+/* CPG */
+#define R8A7791_CLK_MAIN 0
+#define R8A7791_CLK_PLL0 1
+#define R8A7791_CLK_PLL1 2
+#define R8A7791_CLK_PLL3 3
+#define R8A7791_CLK_LB 4
+#define R8A7791_CLK_QSPI 5
+#define R8A7791_CLK_SDH 6
+#define R8A7791_CLK_SD0 7
+#define R8A7791_CLK_Z 8
+
+/* MSTP0 */
+#define R8A7791_CLK_MSIOF0 0
+
+/* MSTP1 */
+#define R8A7791_CLK_TMU1 11
+#define R8A7791_CLK_TMU3 21
+#define R8A7791_CLK_TMU2 22
+#define R8A7791_CLK_CMT0 24
+#define R8A7791_CLK_TMU0 25
+#define R8A7791_CLK_VSP1_DU1 27
+#define R8A7791_CLK_VSP1_DU0 28
+#define R8A7791_CLK_VSP1_SY 31
+
+/* MSTP2 */
+#define R8A7791_CLK_SCIFA2 2
+#define R8A7791_CLK_SCIFA1 3
+#define R8A7791_CLK_SCIFA0 4
+#define R8A7791_CLK_MSIOF2 5
+#define R8A7791_CLK_SCIFB0 6
+#define R8A7791_CLK_SCIFB1 7
+#define R8A7791_CLK_MSIOF1 8
+#define R8A7791_CLK_SCIFB2 16
+#define R8A7791_CLK_DMAC 18
+
+/* MSTP3 */
+#define R8A7791_CLK_TPU0 4
+#define R8A7791_CLK_SDHI2 11
+#define R8A7791_CLK_SDHI1 12
+#define R8A7791_CLK_SDHI0 14
+#define R8A7791_CLK_MMCIF0 15
+#define R8A7791_CLK_SSUSB 28
+#define R8A7791_CLK_CMT1 29
+#define R8A7791_CLK_USBDMAC0 30
+#define R8A7791_CLK_USBDMAC1 31
+
+/* MSTP5 */
+#define R8A7791_CLK_THERMAL 22
+#define R8A7791_CLK_PWM 23
+
+/* MSTP7 */
+#define R8A7791_CLK_HSUSB 4
+#define R8A7791_CLK_HSCIF2 13
+#define R8A7791_CLK_SCIF5 14
+#define R8A7791_CLK_SCIF4 15
+#define R8A7791_CLK_HSCIF1 16
+#define R8A7791_CLK_HSCIF0 17
+#define R8A7791_CLK_SCIF3 18
+#define R8A7791_CLK_SCIF2 19
+#define R8A7791_CLK_SCIF1 20
+#define R8A7791_CLK_SCIF0 21
+#define R8A7791_CLK_DU1 23
+#define R8A7791_CLK_DU0 24
+#define R8A7791_CLK_LVDS0 26
+
+/* MSTP8 */
+#define R8A7791_CLK_VIN2 9
+#define R8A7791_CLK_VIN1 10
+#define R8A7791_CLK_VIN0 11
+#define R8A7791_CLK_ETHER 13
+#define R8A7791_CLK_SATA1 14
+#define R8A7791_CLK_SATA0 15
+
+/* MSTP9 */
+#define R8A7791_CLK_GPIO7 4
+#define R8A7791_CLK_GPIO6 5
+#define R8A7791_CLK_GPIO5 7
+#define R8A7791_CLK_GPIO4 8
+#define R8A7791_CLK_GPIO3 9
+#define R8A7791_CLK_GPIO2 10
+#define R8A7791_CLK_GPIO1 11
+#define R8A7791_CLK_GPIO0 12
+#define R8A7791_CLK_RCAN1 15
+#define R8A7791_CLK_RCAN0 16
+#define R8A7791_CLK_QSPI_MOD 17
+#define R8A7791_CLK_I2C5 25
+#define R8A7791_CLK_IICDVFS 26
+#define R8A7791_CLK_I2C4 27
+#define R8A7791_CLK_I2C3 28
+#define R8A7791_CLK_I2C2 29
+#define R8A7791_CLK_I2C1 30
+#define R8A7791_CLK_I2C0 31
+
+/* MSTP11 */
+#define R8A7791_CLK_SCIFA3 6
+#define R8A7791_CLK_SCIFA4 7
+#define R8A7791_CLK_SCIFA5 8
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7791_H__ */
#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
#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 */
--- /dev/null
+/*
+ * 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 */
#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 */
#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 */
/* 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 */
#define TEGRA_GPIO_BANK_ID_CC 28
#define TEGRA_GPIO_BANK_ID_DD 29
#define TEGRA_GPIO_BANK_ID_EE 30
+#define TEGRA_GPIO_BANK_ID_FF 31
#define TEGRA_GPIO(bank, offset) \
((TEGRA_GPIO_BANK_ID_##bank * 8) + offset)
--- /dev/null
+/*
+ * This header provides constants for Tegra pinctrl bindings.
+ *
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_TEGRA_H
+#define _DT_BINDINGS_PINCTRL_TEGRA_H
+
+/*
+ * Enable/disable for diffeent dt properties. This is applicable for
+ * properties nvidia,enable-input, nvidia,tristate, nvidia,open-drain,
+ * nvidia,lock, nvidia,rcv-sel, nvidia,high-speed-mode, nvidia,schmitt.
+ */
+#define TEGRA_PIN_DISABLE 0
+#define TEGRA_PIN_ENABLE 1
+
+#define TEGRA_PIN_PULL_NONE 0
+#define TEGRA_PIN_PULL_DOWN 1
+#define TEGRA_PIN_PULL_UP 2
+
+/* Low power mode driver */
+#define TEGRA_PIN_LP_DRIVE_DIV_8 0
+#define TEGRA_PIN_LP_DRIVE_DIV_4 1
+#define TEGRA_PIN_LP_DRIVE_DIV_2 2
+#define TEGRA_PIN_LP_DRIVE_DIV_1 3
+
+/* Rising/Falling slew rate */
+#define TEGRA_PIN_SLEW_RATE_FASTEST 0
+#define TEGRA_PIN_SLEW_RATE_FAST 1
+#define TEGRA_PIN_SLEW_RATE_SLOW 2
+#define TEGRA_PIN_SLEW_RATE_SLOWEST 3
+
+#endif
/*
- * arch/arm/mach-at91/include/mach/at91_pmc.h
+ * include/linux/clk/at91_pmc.h
*
* Copyright (C) 2005 Ivan Kokshaysky
* Copyright (C) SAN People
#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */
+#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */
+
#define AT91_PMC_PROT 0xe4 /* Write Protect Mode Register [some SAM9] */
#define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */
#define AT91_PMC_WPKEY (0xffffff << 8) /* Write Protect Key */
--- /dev/null
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_CLK_SHMOBILE_H_
+#define __LINUX_CLK_SHMOBILE_H_
+
+#include <linux/types.h>
+
+void rcar_gen2_clocks_init(u32 mode);
+
+#endif
}
#endif
-#ifdef CONFIG_ARCH_TEGRA
-void tegra_periph_reset_deassert(struct clk *c);
-void tegra_periph_reset_assert(struct clk *c);
-#else
-static inline void tegra_periph_reset_deassert(struct clk *c) {}
-static inline void tegra_periph_reset_assert(struct clk *c) {}
-#endif
void tegra_clocks_apply_init_table(void);
#endif /* __LINUX_CLK_TEGRA_H_ */
policy->cpuinfo.max_freq);
}
+#ifdef CONFIG_CPU_FREQ
+void cpufreq_suspend(void);
+void cpufreq_resume(void);
+#else
+static inline void cpufreq_suspend(void) {}
+static inline void cpufreq_resume(void) {}
+#endif
+
/*********************************************************************
* CPUFREQ NOTIFIER INTERFACE *
*********************************************************************/
#define LINUX_DMAENGINE_H
#include <linux/device.h>
+#include <linux/err.h>
#include <linux/uio.h>
#include <linux/bug.h>
#include <linux/scatterlist.h>
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
{
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)
{
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) \
struct efi_variable var;
struct list_head list;
struct kobject kobj;
+ bool scanning;
+ bool deleting;
};
#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
int efivars_sysfs_init(void);
+#define EFIVARS_DATA_SIZE_MAX 1024
+
#endif /* CONFIG_EFI_VARS */
#endif /* _LINUX_EFI_H */
#ifdef CONFIG_PERF_EVENTS
int perf_refcount;
struct hlist_head __percpu *perf_events;
+
+ int (*perf_perm)(struct ftrace_event_call *,
+ struct perf_event *);
#endif
};
} \
early_initcall(trace_init_flags_##name);
+#define __TRACE_EVENT_PERF_PERM(name, expr...) \
+ static int perf_perm_##name(struct ftrace_event_call *tp_event, \
+ struct perf_event *p_event) \
+ { \
+ return ({ expr; }); \
+ } \
+ static int __init trace_init_perf_perm_##name(void) \
+ { \
+ event_##name.perf_perm = &perf_perm_##name; \
+ return 0; \
+ } \
+ early_initcall(trace_init_perf_perm_##name);
+
#define PERF_MAX_TRACE_SIZE 2048
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
#define __LINUX_GPIO_DRIVER_H
#include <linux/types.h>
+#include <linux/module.h>
struct device;
struct gpio_desc;
+struct of_phandle_args;
+struct device_node;
struct seq_file;
/**
int gpiod_lock_as_irq(struct gpio_desc *desc);
void gpiod_unlock_as_irq(struct gpio_desc *desc);
+enum gpio_lookup_flags {
+ GPIO_ACTIVE_HIGH = (0 << 0),
+ GPIO_ACTIVE_LOW = (1 << 0),
+ GPIO_OPEN_DRAIN = (1 << 1),
+ GPIO_OPEN_SOURCE = (1 << 2),
+};
+
/**
* Lookup table for associating GPIOs to specific devices and functions using
* platform data.
*/
unsigned int idx;
/*
- * mask of GPIOF_* values
+ * mask of GPIO_* values
*/
- unsigned long flags;
+ enum gpio_lookup_flags flags;
};
/*
#include <linux/hid.h>
#include <linux/hid-sensor-ids.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
/**
* struct hid_sensor_hub_attribute_info - Attribute info
struct platform_device *pdev;
unsigned usage_id;
bool data_ready;
+ struct iio_trigger *trigger;
struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state;
struct hid_sensor_hub_attribute_info power_state;
};
typedef enum irqreturn irqreturn_t;
-#define IRQ_RETVAL(x) ((x) != IRQ_NONE)
+#define IRQ_RETVAL(x) ((x) ? IRQ_HANDLED : IRQ_NONE)
#endif
#define NFS4_VERSION 4
#define NFS4_MINOR_VERSION 0
-#if defined(CONFIG_NFS_V4_2)
-#define NFS4_MAX_MINOR_VERSION 2
-#else
-#if defined(CONFIG_NFS_V4_1)
-#define NFS4_MAX_MINOR_VERSION 1
-#else
-#define NFS4_MAX_MINOR_VERSION 0
-#endif /* CONFIG_NFS_V4_1 */
-#endif /* CONFIG_NFS_V4_2 */
-
#define NFS4_DEBUG 1
/* Index of predefined Linux client operations */
extern int nfs_mountpoint_expiry_timeout;
extern void nfs_release_automount_timer(void);
-/*
- * linux/fs/nfs/nfs4proc.c
- */
-#ifdef CONFIG_NFS_V4_SECURITY_LABEL
-extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
-static inline void nfs4_label_free(struct nfs4_label *label)
-{
- if (label) {
- kfree(label->label);
- kfree(label);
- }
- return;
-}
-#else
-static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
-static inline void nfs4_label_free(void *label) {}
-#endif
-
/*
* linux/fs/nfs/unlink.c
*/
struct padata_serial_queue __percpu *squeue;
atomic_t reorder_objects;
atomic_t refcnt;
+ atomic_t seq_nr;
struct padata_cpumask cpumask;
spinlock_t lock ____cacheline_aligned;
- spinlock_t seq_lock;
- unsigned int seq_nr;
unsigned int processed;
struct timer_list timer;
};
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
- * @PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
- * 1 to indicate high level, argument 0 to indicate low level.
+ * @PIN_CONFIG_OUTPUT: this will configure the pin as an output. Use argument
+ * 1 to indicate high level, argument 0 to indicate low level. (Please
+ * see Documentation/pinctrl.txt, section "GPIO mode pitfalls" for a
+ * discussion around this parameter.)
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
unsigned int balance_interval; /* initialise to 1. units in ms. */
unsigned int nr_balance_failed; /* initialise to 0 */
- u64 last_update;
-
/* idle_balance() stats */
u64 max_newidle_lb_cost;
unsigned long next_decay_max_lb_cost;
/**
* kmalloc - allocate memory
* @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate (see kcalloc).
+ * @flags: the type of memory to allocate.
*
* kmalloc is the normal method of allocating memory
* for objects smaller than page size in the kernel.
+ *
+ * The @flags argument may be one of:
+ *
+ * %GFP_USER - Allocate memory on behalf of user. May sleep.
+ *
+ * %GFP_KERNEL - Allocate normal kernel ram. May sleep.
+ *
+ * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools.
+ * For example, use this inside interrupt handlers.
+ *
+ * %GFP_HIGHUSER - Allocate pages from high memory.
+ *
+ * %GFP_NOIO - Do not do any I/O at all while trying to get memory.
+ *
+ * %GFP_NOFS - Do not make any fs calls while trying to get memory.
+ *
+ * %GFP_NOWAIT - Allocation will not sleep.
+ *
+ * %GFP_THISNODE - Allocate node-local memory only.
+ *
+ * %GFP_DMA - Allocation suitable for DMA.
+ * Should only be used for kmalloc() caches. Otherwise, use a
+ * slab created with SLAB_DMA.
+ *
+ * Also it is possible to set different flags by OR'ing
+ * in one or more of the following additional @flags:
+ *
+ * %__GFP_COLD - Request cache-cold pages instead of
+ * trying to return cache-warm pages.
+ *
+ * %__GFP_HIGH - This allocation has high priority and may use emergency pools.
+ *
+ * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
+ * (think twice before using).
+ *
+ * %__GFP_NORETRY - If memory is not immediately available,
+ * then give up at once.
+ *
+ * %__GFP_NOWARN - If allocation fails, don't issue any warnings.
+ *
+ * %__GFP_REPEAT - If allocation fails initially, try once more before failing.
+ *
+ * There are other flags available as well, but these are not intended
+ * for general use, and so are not documented here. For a full list of
+ * potential flags, always refer to linux/gfp.h.
*/
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
int cache_show(struct kmem_cache *s, struct seq_file *m);
void print_slabinfo_header(struct seq_file *m);
-/**
- * kmalloc - allocate memory
- * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- *
- * The @flags argument may be one of:
- *
- * %GFP_USER - Allocate memory on behalf of user. May sleep.
- *
- * %GFP_KERNEL - Allocate normal kernel ram. May sleep.
- *
- * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools.
- * For example, use this inside interrupt handlers.
- *
- * %GFP_HIGHUSER - Allocate pages from high memory.
- *
- * %GFP_NOIO - Do not do any I/O at all while trying to get memory.
- *
- * %GFP_NOFS - Do not make any fs calls while trying to get memory.
- *
- * %GFP_NOWAIT - Allocation will not sleep.
- *
- * %GFP_THISNODE - Allocate node-local memory only.
- *
- * %GFP_DMA - Allocation suitable for DMA.
- * Should only be used for kmalloc() caches. Otherwise, use a
- * slab created with SLAB_DMA.
- *
- * Also it is possible to set different flags by OR'ing
- * in one or more of the following additional @flags:
- *
- * %__GFP_COLD - Request cache-cold pages instead of
- * trying to return cache-warm pages.
- *
- * %__GFP_HIGH - This allocation has high priority and may use emergency pools.
- *
- * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
- * (think twice before using).
- *
- * %__GFP_NORETRY - If memory is not immediately available,
- * then give up at once.
- *
- * %__GFP_NOWARN - If allocation fails, don't issue any warnings.
- *
- * %__GFP_REPEAT - If allocation fails initially, try once more before failing.
- *
- * There are other flags available as well, but these are not intended
- * for general use, and so are not documented here. For a full list of
- * potential flags, always refer to linux/gfp.h.
- *
- * kmalloc is the normal method of allocating memory
- * in the kernel.
- */
-static __always_inline void *kmalloc(size_t size, gfp_t flags);
-
/**
* kmalloc_array - allocate memory for an array.
* @n: number of elements.
#define _MACH_TEGRA_POWERGATE_H_
struct clk;
+struct reset_control;
#define TEGRA_POWERGATE_CPU 0
#define TEGRA_POWERGATE_3D 1
#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
+#ifdef CONFIG_ARCH_TEGRA
int tegra_powergate_is_powered(int id);
int tegra_powergate_power_on(int id);
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)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_powergate_power_on(int id)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_powergate_power_off(int id)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_powergate_remove_clamping(int id)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+ struct reset_control *rst);
+{
+ return -ENOSYS;
+}
+#endif
#endif /* _MACH_TEGRA_POWERGATE_H_ */
#define TRACE_EVENT_FLAGS(event, flag)
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
#endif /* DECLARE_TRACE */
#ifndef TRACE_EVENT
#define TRACE_EVENT_FLAGS(event, flag)
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
#endif /* ifdef TRACE_EVENT (see note above) */
int ip_ra_control(struct sock *sk, unsigned char on,
void (*destructor)(struct sock *));
-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
u32 info, u8 *payload);
void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+ int *addr_len);
+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+ int *addr_len);
void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
u32 info, u8 *payload);
void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
/* Compatibility glue so we can support IPv6 when it's compiled as a module */
struct pingv6_ops {
- int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
+ int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
+ int *addr_len);
int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
struct sk_buff *skb);
int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
#define SCTP_NEED_FRTX 0x1
#define SCTP_DONT_FRTX 0x2
__u16 rtt_in_progress:1, /* This chunk used for RTT calc? */
+ resent:1, /* Has this chunk ever been resent. */
has_tsn:1, /* Does this chunk have a TSN yet? */
has_ssn:1, /* Does this chunk have a SSN yet? */
singleton:1, /* Only chunk in the packet? */
*/
unsigned ordered_tag:1;
+ /* True if the controller does not support WRITE SAME */
+ unsigned no_write_same:1;
+
/*
* Countdown for host blocking with no commands outstanding.
*/
/* Don't resume host in EH */
unsigned eh_noresume:1;
+ /* The controller does not support WRITE SAME */
+ unsigned no_write_same:1;
+
/*
* Optional work queue to be utilized by the transport
*/
* @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.
*
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;
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);
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
-{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, \
+{ .id = snd_soc_dapm_mux, .name = wname, \
+ SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_virt_mux, .name = wname, \
#define TRACE_EVENT_FLAGS(name, value) \
__TRACE_EVENT_FLAGS(name, value)
+#undef TRACE_EVENT_PERF_PERM
+#define TRACE_EVENT_PERF_PERM(name, expr...) \
+ __TRACE_EVENT_PERF_PERM(name, expr)
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#undef TRACE_EVENT_FLAGS
#define TRACE_EVENT_FLAGS(event, flag)
+#undef TRACE_EVENT_PERF_PERM
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
/*
__data_size += (len) * sizeof(type);
#undef __string
-#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
+#define __string(item, src) __dynamic_array(char, item, \
+ strlen((src) ? (const char *)(src) : "(null)") + 1)
#undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
#undef __assign_str
#define __assign_str(dst, src) \
- strcpy(__get_str(dst), src);
+ strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
#undef TP_fast_assign
#define TP_fast_assign(args...) args
__u64 data;
} EPOLL_PACKED;
-
+#ifdef CONFIG_PM_SLEEP
+static inline void ep_take_care_of_epollwakeup(struct epoll_event *epev)
+{
+ if ((epev->events & EPOLLWAKEUP) && !capable(CAP_BLOCK_SUSPEND))
+ epev->events &= ~EPOLLWAKEUP;
+}
+#else
+static inline void ep_take_care_of_epollwakeup(struct epoll_event *epev)
+{
+ epev->events &= ~EPOLLWAKEUP;
+}
+#endif
#endif /* _UAPI_LINUX_EVENTPOLL_H */
#define GENL_ID_GENERATE 0
#define GENL_ID_CTRL NLMSG_MIN_TYPE
#define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1)
+#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2)
/**************************************************************************
* Controller
IFLA_HSR_UNSPEC,
IFLA_HSR_SLAVE1,
IFLA_HSR_SLAVE2,
- IFLA_HSR_MULTICAST_SPEC,
+ IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */
+ IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
+ IFLA_HSR_SEQ_NR,
__IFLA_HSR_MAX,
};
};
enum {
+ /* NETLINK_DIAG_NONE, standard nl API requires this attribute! */
NETLINK_DIAG_MEMINFO,
NETLINK_DIAG_GROUPS,
NETLINK_DIAG_RX_RING,
};
enum {
+ /* PACKET_DIAG_NONE, standard nl API requires this attribute! */
PACKET_DIAG_INFO,
PACKET_DIAG_MCLIST,
PACKET_DIAG_RX_RING,
};
enum {
+ /* UNIX_DIAG_NONE, standard nl API requires this attribute! */
UNIX_DIAG_NAME,
UNIX_DIAG_VFS,
UNIX_DIAG_PEER,
static DEFINE_MUTEX(cgroup_root_mutex);
+/*
+ * cgroup destruction makes heavy use of work items and there can be a lot
+ * of concurrent destructions. Use a separate workqueue so that cgroup
+ * destruction work items don't end up filling up max_active of system_wq
+ * which may lead to deadlock.
+ */
+static struct workqueue_struct *cgroup_destroy_wq;
+
/*
* Generate an array of cgroup subsystem pointers. At boot time, this is
* populated with the built in subsystems, and modular subsystems are
static int cgroup_destroy_locked(struct cgroup *cgrp);
static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
bool is_add);
+static int cgroup_file_release(struct inode *inode, struct file *file);
/**
* cgroup_css - obtain a cgroup's css for the specified subsystem
struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head);
INIT_WORK(&cgrp->destroy_work, cgroup_free_fn);
- schedule_work(&cgrp->destroy_work);
+ queue_work(cgroup_destroy_wq, &cgrp->destroy_work);
}
static void cgroup_diput(struct dentry *dentry, struct inode *inode)
.read = seq_read,
.write = cgroup_file_write,
.llseek = seq_lseek,
- .release = single_release,
+ .release = cgroup_file_release,
};
static int cgroup_file_open(struct inode *inode, struct file *file)
ret = cft->release(inode, file);
if (css->ss)
css_put(css);
+ if (file->f_op == &cgroup_seqfile_operations)
+ single_release(inode, file);
return ret;
}
* css_put(). dput() requires process context which we don't have.
*/
INIT_WORK(&css->destroy_work, css_free_work_fn);
- schedule_work(&css->destroy_work);
+ queue_work(cgroup_destroy_wq, &css->destroy_work);
}
static void css_release(struct percpu_ref *ref)
container_of(ref, struct cgroup_subsys_state, refcnt);
INIT_WORK(&css->destroy_work, css_killed_work_fn);
- schedule_work(&css->destroy_work);
+ queue_work(cgroup_destroy_wq, &css->destroy_work);
}
/**
return err;
}
+static int __init cgroup_wq_init(void)
+{
+ /*
+ * There isn't much point in executing destruction path in
+ * parallel. Good chunk is serialized with cgroup_mutex anyway.
+ * Use 1 for @max_active.
+ *
+ * We would prefer to do this in cgroup_init() above, but that
+ * is called before init_workqueues(): so leave this until after.
+ */
+ cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
+ BUG_ON(!cgroup_destroy_wq);
+ return 0;
+}
+core_initcall(cgroup_wq_init);
+
/*
* proc_cgroup_show()
* - Print task's cgroup paths into seq_file, one line for each hierarchy
need_loop = task_has_mempolicy(tsk) ||
!nodes_intersects(*newmems, tsk->mems_allowed);
- if (need_loop)
+ if (need_loop) {
+ local_irq_disable();
write_seqcount_begin(&tsk->mems_allowed_seq);
+ }
nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2);
tsk->mems_allowed = *newmems;
- if (need_loop)
+ if (need_loop) {
write_seqcount_end(&tsk->mems_allowed_seq);
+ local_irq_enable();
+ }
task_unlock(tsk);
}
{
int cpu;
- if (event->cpu != -1) {
- swevent_hlist_put_cpu(event, event->cpu);
- return;
- }
-
for_each_possible_cpu(cpu)
swevent_hlist_put_cpu(event, cpu);
}
int err;
int cpu, failed_cpu;
- if (event->cpu != -1)
- return swevent_hlist_get_cpu(event, event->cpu);
-
get_online_cpus();
for_each_possible_cpu(cpu) {
err = swevent_hlist_get_cpu(event, cpu);
static inline int init_kernel_text(unsigned long addr)
{
if (addr >= (unsigned long)_sinittext &&
- addr <= (unsigned long)_einittext)
+ addr < (unsigned long)_einittext)
return 1;
return 0;
}
int core_kernel_text(unsigned long addr)
{
if (addr >= (unsigned long)_stext &&
- addr <= (unsigned long)_etext)
+ addr < (unsigned long)_etext)
return 1;
if (system_state == SYSTEM_BOOTING &&
bool is_early = desc->action &&
desc->action->flags & IRQF_EARLY_RESUME;
- if (is_early != want_early)
+ if (!is_early && want_early)
continue;
raw_spin_lock_irqsave(&desc->lock, flags);
static int padata_cpu_hash(struct parallel_data *pd)
{
+ unsigned int seq_nr;
int cpu_index;
/*
* seq_nr mod. number of cpus in use.
*/
- spin_lock(&pd->seq_lock);
- cpu_index = pd->seq_nr % cpumask_weight(pd->cpumask.pcpu);
- pd->seq_nr++;
- spin_unlock(&pd->seq_lock);
+ seq_nr = atomic_inc_return(&pd->seq_nr);
+ cpu_index = seq_nr % cpumask_weight(pd->cpumask.pcpu);
return padata_index_to_cpu(pd, cpu_index);
}
padata_init_pqueues(pd);
padata_init_squeues(pd);
setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd);
- pd->seq_nr = 0;
+ atomic_set(&pd->seq_nr, -1);
atomic_set(&pd->reorder_objects, 0);
atomic_set(&pd->refcnt, 0);
pd->pinst = pinst;
static int rcu_idle_lazy_gp_delay = RCU_IDLE_LAZY_GP_DELAY;
module_param(rcu_idle_lazy_gp_delay, int, 0644);
-extern int tick_nohz_enabled;
+extern int tick_nohz_active;
/*
* Try to advance callbacks for all flavors of RCU on the current CPU, but
int tne;
/* Handle nohz enablement switches conservatively. */
- tne = ACCESS_ONCE(tick_nohz_enabled);
+ tne = ACCESS_ONCE(tick_nohz_active);
if (tne != rdtp->tick_nohz_enabled_snap) {
if (rcu_cpu_has_callbacks(cpu, NULL))
invoke_rcu_core(); /* force nohz to see update. */
} while (need_resched());
}
EXPORT_SYMBOL(preempt_schedule);
+#endif /* CONFIG_PREEMPT */
/*
* this is the entry point to schedule() from kernel preemption
exception_exit(prev_state);
}
-#endif /* CONFIG_PREEMPT */
-
int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
void *key)
{
cpumask_clear_cpu(rq->cpu, old_rd->span);
/*
- * If we dont want to free the old_rt yet then
+ * If we dont want to free the old_rd yet then
* set old_rd to NULL to skip the freeing later
* in this function:
*/
if (sd) {
id = cpumask_first(sched_domain_span(sd));
size = cpumask_weight(sched_domain_span(sd));
- rcu_assign_pointer(per_cpu(sd_busy, cpu), sd->parent);
+ sd = sd->parent; /* sd_busy */
}
+ rcu_assign_pointer(per_cpu(sd_busy, cpu), sd);
rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
per_cpu(sd_llc_size, cpu) = size;
*/
for_each_cpu(cpu, sched_group_cpus(sdg)) {
- struct sched_group *sg = cpu_rq(cpu)->sd->groups;
+ struct sched_group_power *sgp;
+ struct rq *rq = cpu_rq(cpu);
- power_orig += sg->sgp->power_orig;
- power += sg->sgp->power;
+ /*
+ * build_sched_domains() -> init_sched_groups_power()
+ * gets here before we've attached the domains to the
+ * runqueues.
+ *
+ * Use power_of(), which is set irrespective of domains
+ * in update_cpu_power().
+ *
+ * This avoids power/power_orig from being 0 and
+ * causing divide-by-zero issues on boot.
+ *
+ * Runtime updates will correct power_orig.
+ */
+ if (unlikely(!rq->sd)) {
+ power_orig += power_of(cpu);
+ power += power_of(cpu);
+ continue;
+ }
+
+ sgp = rq->sd->groups->sgp;
+ power_orig += sgp->power_orig;
+ power += sgp->power;
}
} else {
/*
*/
ktime_t tick_next_period;
ktime_t tick_period;
+
+/*
+ * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR
+ * which is responsible for calling do_timer(), i.e. the timekeeping stuff. This
+ * variable has two functions:
+ *
+ * 1) Prevent a thundering herd issue of a gazillion of CPUs trying to grab the
+ * timekeeping lock all at once. Only the CPU which is assigned to do the
+ * update is handling it.
+ *
+ * 2) Hand off the duty in the NOHZ idle case by setting the value to
+ * TICK_DO_TIMER_NONE, i.e. a non existing CPU. So the next cpu which looks
+ * at it will take over and keep the time keeping alive. The handover
+ * procedure also covers cpu hotplug.
+ */
int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
/*
/*
* NO HZ enabled ?
*/
-int tick_nohz_enabled __read_mostly = 1;
-
+static int tick_nohz_enabled __read_mostly = 1;
+int tick_nohz_active __read_mostly;
/*
* Enable / Disable tickless mode
*/
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
ktime_t now, idle;
- if (!tick_nohz_enabled)
+ if (!tick_nohz_active)
return -1;
now = ktime_get();
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
ktime_t now, iowait;
- if (!tick_nohz_enabled)
+ if (!tick_nohz_active)
return -1;
now = ktime_get();
return false;
}
- if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
+ if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
+ ts->sleep_length = (ktime_t) { .tv64 = NSEC_PER_SEC/HZ };
return false;
+ }
if (need_resched())
return false;
local_irq_disable();
ts = &__get_cpu_var(tick_cpu_sched);
- /*
- * set ts->inidle unconditionally. even if the system did not
- * switch to nohz mode the cpu frequency governers rely on the
- * update of the idle time accounting in tick_nohz_start_idle().
- */
ts->inidle = 1;
__tick_nohz_idle_enter(ts);
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t next;
- if (!tick_nohz_enabled)
+ if (!tick_nohz_active)
return;
local_irq_disable();
local_irq_enable();
return;
}
-
+ tick_nohz_active = 1;
ts->nohz_mode = NOHZ_MODE_LOWRES;
/*
}
#ifdef CONFIG_NO_HZ_COMMON
- if (tick_nohz_enabled)
+ if (tick_nohz_enabled) {
ts->nohz_mode = NOHZ_MODE_HIGHRES;
+ tick_nohz_active = 1;
+ }
#endif
}
#endif /* HIGH_RES_TIMERS */
tk->xtime_nsec -= remainder;
tk->xtime_nsec += 1ULL << tk->shift;
tk->ntp_error += remainder << tk->ntp_error_shift;
-
+ tk->ntp_error -= (1ULL << tk->shift) << tk->ntp_error_shift;
}
#else
#define old_vsyscall_fixup(tk)
/*
* The APs use this path later in boot
*/
- base = kmalloc_node(sizeof(*base),
- GFP_KERNEL | __GFP_ZERO,
- cpu_to_node(cpu));
+ base = kzalloc_node(sizeof(*base), GFP_KERNEL,
+ cpu_to_node(cpu));
if (!base)
return -ENOMEM;
static int __register_ftrace_function(struct ftrace_ops *ops)
{
- if (unlikely(ftrace_disabled))
- return -ENODEV;
-
if (FTRACE_WARN_ON(ops == &global_ops))
return -EINVAL;
{
int ret;
- if (ftrace_disabled)
- return -ENODEV;
-
if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED)))
return -EBUSY;
static int ftrace_startup(struct ftrace_ops *ops, int command)
{
bool hash_enable = true;
+ int ret;
if (unlikely(ftrace_disabled))
return -ENODEV;
+ ret = __register_ftrace_function(ops);
+ if (ret)
+ return ret;
+
ftrace_start_up++;
command |= FTRACE_UPDATE_CALLS;
return 0;
}
-static void ftrace_shutdown(struct ftrace_ops *ops, int command)
+static int ftrace_shutdown(struct ftrace_ops *ops, int command)
{
bool hash_disable = true;
+ int ret;
if (unlikely(ftrace_disabled))
- return;
+ return -ENODEV;
+
+ ret = __unregister_ftrace_function(ops);
+ if (ret)
+ return ret;
ftrace_start_up--;
/*
}
if (!command || !ftrace_enabled)
- return;
+ return 0;
ftrace_run_update_code(command);
+ return 0;
}
static void ftrace_startup_sysctl(void)
if (i == FTRACE_FUNC_HASHSIZE)
return;
- ret = __register_ftrace_function(&trace_probe_ops);
- if (!ret)
- ret = ftrace_startup(&trace_probe_ops, 0);
+ ret = ftrace_startup(&trace_probe_ops, 0);
ftrace_probe_registered = 1;
}
static void __disable_ftrace_function_probe(void)
{
- int ret;
int i;
if (!ftrace_probe_registered)
}
/* no more funcs left */
- ret = __unregister_ftrace_function(&trace_probe_ops);
- if (!ret)
- ftrace_shutdown(&trace_probe_ops, 0);
+ ftrace_shutdown(&trace_probe_ops, 0);
ftrace_probe_registered = 0;
}
static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
static inline void ftrace_startup_enable(int command) { }
/* Keep as macros so we do not need to define the commands */
-# define ftrace_startup(ops, command) \
- ({ \
- (ops)->flags |= FTRACE_OPS_FL_ENABLED; \
- 0; \
+# define ftrace_startup(ops, command) \
+ ({ \
+ int ___ret = __register_ftrace_function(ops); \
+ if (!___ret) \
+ (ops)->flags |= FTRACE_OPS_FL_ENABLED; \
+ ___ret; \
})
-# define ftrace_shutdown(ops, command) do { } while (0)
+# define ftrace_shutdown(ops, command) __unregister_ftrace_function(ops)
+
# define ftrace_startup_sysctl() do { } while (0)
# define ftrace_shutdown_sysctl() do { } while (0)
mutex_lock(&ftrace_lock);
- ret = __register_ftrace_function(ops);
- if (!ret)
- ret = ftrace_startup(ops, 0);
+ ret = ftrace_startup(ops, 0);
mutex_unlock(&ftrace_lock);
int ret;
mutex_lock(&ftrace_lock);
- ret = __unregister_ftrace_function(ops);
- if (!ret)
- ftrace_shutdown(ops, 0);
+ ret = ftrace_shutdown(ops, 0);
mutex_unlock(&ftrace_lock);
return ret;
return NOTIFY_DONE;
}
+/* Just a place holder for function graph */
+static struct ftrace_ops fgraph_ops __read_mostly = {
+ .func = ftrace_stub,
+ .flags = FTRACE_OPS_FL_STUB | FTRACE_OPS_FL_GLOBAL |
+ FTRACE_OPS_FL_RECURSION_SAFE,
+};
+
int register_ftrace_graph(trace_func_graph_ret_t retfunc,
trace_func_graph_ent_t entryfunc)
{
ftrace_graph_return = retfunc;
ftrace_graph_entry = entryfunc;
- ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET);
+ ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET);
out:
mutex_unlock(&ftrace_lock);
ftrace_graph_active--;
ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
ftrace_graph_entry = ftrace_graph_entry_stub;
- ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET);
+ ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET);
unregister_pm_notifier(&ftrace_suspend_notifier);
unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
static int perf_trace_event_perm(struct ftrace_event_call *tp_event,
struct perf_event *p_event)
{
+ if (tp_event->perf_perm) {
+ int ret = tp_event->perf_perm(tp_event, p_event);
+ if (ret)
+ return ret;
+ }
+
/* The ftrace function trace is allowed only for root. */
if (ftrace_event_is_function(tp_event) &&
perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN))
int perf_trace_init(struct perf_event *p_event)
{
struct ftrace_event_call *tp_event;
- int event_id = p_event->attr.config;
+ u64 event_id = p_event->attr.config;
int ret = -EINVAL;
mutex_lock(&event_mutex);
/* Disable any running events */
__ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0);
+ /* Access to events are within rcu_read_lock_sched() */
+ synchronize_sched();
+
down_write(&trace_event_sem);
__trace_remove_event_dirs(tr);
debugfs_remove_recursive(tr->event_dir);
if (!tr->sys_refcount_enter)
unregister_trace_sys_enter(ftrace_syscall_enter, tr);
mutex_unlock(&syscall_trace_lock);
- /*
- * Callers expect the event to be completely disabled on
- * return, so wait for current handlers to finish.
- */
- synchronize_sched();
}
static int reg_event_syscall_exit(struct ftrace_event_file *file,
if (!tr->sys_refcount_exit)
unregister_trace_sys_exit(ftrace_syscall_exit, tr);
mutex_unlock(&syscall_trace_lock);
- /*
- * Callers expect the event to be completely disabled on
- * return, so wait for current handlers to finish.
- */
- synchronize_sched();
}
static int __init init_syscall_trace(struct ftrace_event_call *call)
/* I: attributes used when instantiating standard unbound pools on demand */
static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS];
+/* I: attributes used when instantiating ordered pools on demand */
+static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS];
+
struct workqueue_struct *system_wq __read_mostly;
EXPORT_SYMBOL(system_wq);
struct workqueue_struct *system_highpri_wq __read_mostly;
static inline void debug_work_deactivate(struct work_struct *work) { }
#endif
-/* allocate ID and assign it to @pool */
+/**
+ * worker_pool_assign_id - allocate ID and assing it to @pool
+ * @pool: the pool pointer of interest
+ *
+ * Returns 0 if ID in [0, WORK_OFFQ_POOL_NONE) is allocated and assigned
+ * successfully, -errno on failure.
+ */
static int worker_pool_assign_id(struct worker_pool *pool)
{
int ret;
lockdep_assert_held(&wq_pool_mutex);
- ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
+ ret = idr_alloc(&worker_pool_idr, pool, 0, WORK_OFFQ_POOL_NONE,
+ GFP_KERNEL);
if (ret >= 0) {
pool->id = ret;
return 0;
debug_work_activate(work);
- /* if dying, only works from the same workqueue are allowed */
+ /* if draining, only works from the same workqueue are allowed */
if (unlikely(wq->flags & __WQ_DRAINING) &&
WARN_ON_ONCE(!is_chained_work(wq)))
return;
if (IS_ERR(worker->task))
goto fail;
+ set_user_nice(worker->task, pool->attrs->nice);
+
+ /* prevent userland from meddling with cpumask of workqueue workers */
+ worker->task->flags |= PF_NO_SETAFFINITY;
+
/*
* set_cpus_allowed_ptr() will fail if the cpumask doesn't have any
* online CPUs. It'll be re-applied when any of the CPUs come up.
*/
- set_user_nice(worker->task, pool->attrs->nice);
set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask);
- /* prevent userland from meddling with cpumask of workqueue workers */
- worker->task->flags |= PF_NO_SETAFFINITY;
-
/*
* The caller is responsible for ensuring %POOL_DISASSOCIATED
* remains stable across this function. See the comments above the
static int alloc_and_link_pwqs(struct workqueue_struct *wq)
{
bool highpri = wq->flags & WQ_HIGHPRI;
- int cpu;
+ int cpu, ret;
if (!(wq->flags & WQ_UNBOUND)) {
wq->cpu_pwqs = alloc_percpu(struct pool_workqueue);
mutex_unlock(&wq->mutex);
}
return 0;
+ } else if (wq->flags & __WQ_ORDERED) {
+ ret = apply_workqueue_attrs(wq, ordered_wq_attrs[highpri]);
+ /* there should only be single pwq for ordering guarantee */
+ WARN(!ret && (wq->pwqs.next != &wq->dfl_pwq->pwqs_node ||
+ wq->pwqs.prev != &wq->dfl_pwq->pwqs_node),
+ "ordering guarantee broken for workqueue %s\n", wq->name);
+ return ret;
} else {
return apply_workqueue_attrs(wq, unbound_std_wq_attrs[highpri]);
}
int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL };
int i, cpu;
- /* make sure we have enough bits for OFFQ pool ID */
- BUILD_BUG_ON((1LU << (BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT)) <
- WORK_CPU_END * NR_STD_WORKER_POOLS);
-
WARN_ON(__alignof__(struct pool_workqueue) < __alignof__(long long));
pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
}
}
- /* create default unbound wq attrs */
+ /* create default unbound and ordered wq attrs */
for (i = 0; i < NR_STD_WORKER_POOLS; i++) {
struct workqueue_attrs *attrs;
BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
attrs->nice = std_nice[i];
unbound_std_wq_attrs[i] = attrs;
+
+ /*
+ * An ordered wq should have only one pwq as ordering is
+ * guaranteed by max_active which is enforced by pwqs.
+ * Turn off NUMA so that dfl_pwq is used for all nodes.
+ */
+ BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
+ attrs->nice = std_nice[i];
+ attrs->no_numa = true;
+ ordered_wq_attrs[i] = attrs;
}
system_wq = alloc_workqueue("events", 0, 0);
#include <linux/export.h>
#include <linux/lockref.h>
+#include <linux/mutex.h>
#if USE_CMPXCHG_LOCKREF
# define cmpxchg64_relaxed cmpxchg64
#endif
-/*
- * Allow architectures to override the default cpu_relax() within CMPXCHG_LOOP.
- * This is useful for architectures with an expensive cpu_relax().
- */
-#ifndef arch_mutex_cpu_relax
-# define arch_mutex_cpu_relax() cpu_relax()
-#endif
-
/*
* Note that the "cmpxchg()" reloads the "old" value for the
* failure case.
__get_user(kmsg->msg_flags, &umsg->msg_flags))
return -EFAULT;
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
- return -EINVAL;
+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
kmsg->msg_name = compat_ptr(tmp1);
kmsg->msg_iov = compat_ptr(tmp2);
kmsg->msg_control = compat_ptr(tmp3);
if (x) {
int ret;
__u8 *eth;
+ struct iphdr *iph;
+
nhead = x->props.header_len - skb_headroom(skb);
if (nhead > 0) {
ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
eth = (__u8 *) skb_push(skb, ETH_HLEN);
memcpy(eth, pkt_dev->hh, 12);
*(u16 *) ð[12] = protocol;
+
+ /* Update IPv4 header len as well as checksum value */
+ iph = ip_hdr(skb);
+ iph->tot_len = htons(skb->len - ETH_HLEN);
+ ip_send_check(iph);
}
}
return 1;
static bool seq_nr_after(u16 a, u16 b)
{
/* Remove inconsistency where
- * seq_nr_after(a, b) == seq_nr_before(a, b) */
+ * seq_nr_after(a, b) == seq_nr_before(a, b)
+ */
if ((int) b - a == 32768)
return false;
[IFLA_HSR_SLAVE1] = { .type = NLA_U32 },
[IFLA_HSR_SLAVE2] = { .type = NLA_U32 },
[IFLA_HSR_MULTICAST_SPEC] = { .type = NLA_U8 },
+ [IFLA_HSR_SUPERVISION_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN },
+ [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 },
};
return hsr_dev_finalize(dev, link, multicast_spec);
}
+static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct hsr_priv *hsr_priv;
+
+ hsr_priv = netdev_priv(dev);
+
+ if (hsr_priv->slave[0])
+ if (nla_put_u32(skb, IFLA_HSR_SLAVE1, hsr_priv->slave[0]->ifindex))
+ goto nla_put_failure;
+
+ if (hsr_priv->slave[1])
+ if (nla_put_u32(skb, IFLA_HSR_SLAVE2, hsr_priv->slave[1]->ifindex))
+ goto nla_put_failure;
+
+ if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN,
+ hsr_priv->sup_multicast_addr) ||
+ nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr_priv->sequence_nr))
+ goto nla_put_failure;
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static struct rtnl_link_ops hsr_link_ops __read_mostly = {
.kind = "hsr",
.maxtype = IFLA_HSR_MAX,
.priv_size = sizeof(struct hsr_priv),
.setup = hsr_dev_setup,
.newlink = hsr_newlink,
+ .fill_info = hsr_fill_info,
};
/*
* Handle MSG_ERRQUEUE
*/
-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
{
struct sock_exterr_skb *serr;
struct sk_buff *skb, *skb2;
serr->addr_offset);
sin->sin_port = serr->port;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+ *addr_len = sizeof(*sin);
}
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
err = PTR_ERR(rt);
rt = NULL;
if (err == -ENETUNREACH)
- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
goto out;
}
if (flags & MSG_ERRQUEUE) {
if (family == AF_INET) {
- return ip_recv_error(sk, msg, len);
+ return ip_recv_error(sk, msg, len, addr_len);
#if IS_ENABLED(CONFIG_IPV6)
} else if (family == AF_INET6) {
- return pingv6_ops.ipv6_recv_error(sk, msg, len);
+ return pingv6_ops.ipv6_recv_error(sk, msg, len,
+ addr_len);
#endif
}
}
const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
-/*
- * Add a protocol handler to the hash tables
- */
-
int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
{
if (!prot->netns_ok) {
}
EXPORT_SYMBOL(inet_add_offload);
-/*
- * Remove a protocol from the hash tables.
- */
-
int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
{
int ret;
goto out;
if (flags & MSG_ERRQUEUE) {
- err = ip_recv_error(sk, msg, len);
+ err = ip_recv_error(sk, msg, len, addr_len);
goto out;
}
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
if (err == -ENETUNREACH)
- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
return err;
}
static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
{
struct cg_proto *cg_proto;
- u64 old_lim;
int i;
int ret;
if (val > RES_COUNTER_MAX)
val = RES_COUNTER_MAX;
- old_lim = res_counter_read_u64(&cg_proto->memory_allocated, RES_LIMIT);
ret = res_counter_set_limit(&cg_proto->memory_allocated, val);
if (ret)
return ret;
{
const struct iphdr *iph = skb_gro_network_header(skb);
__wsum wsum;
- __sum16 sum;
+
+ /* Don't bother verifying checksum if we're going to flush anyway. */
+ if (NAPI_GRO_CB(skb)->flush)
+ goto skip_csum;
+
+ wsum = skb->csum;
switch (skb->ip_summed) {
+ case CHECKSUM_NONE:
+ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+ 0);
+
+ /* fall through */
+
case CHECKSUM_COMPLETE:
if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
- skb->csum)) {
+ wsum)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
}
-flush:
+
NAPI_GRO_CB(skb)->flush = 1;
return NULL;
-
- case CHECKSUM_NONE:
- wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
- skb_gro_len(skb), IPPROTO_TCP, 0);
- sum = csum_fold(skb_checksum(skb,
- skb_gro_offset(skb),
- skb_gro_len(skb),
- wsum));
- if (sum)
- goto flush;
-
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- break;
}
+skip_csum:
return tcp_gro_receive(head, skb);
}
err = PTR_ERR(rt);
rt = NULL;
if (err == -ENETUNREACH)
- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
goto out;
}
struct udp_sock *up = udp_sk(sk);
int ret;
+ if (flags & MSG_SENDPAGE_NOTLAST)
+ flags |= MSG_MORE;
+
if (!up->pending) {
struct msghdr msg = { .msg_flags = flags|MSG_MORE };
bool slow;
if (flags & MSG_ERRQUEUE)
- return ip_recv_error(sk, msg, len);
+ return ip_recv_error(sk, msg, len, addr_len);
try_again:
skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
/*
* Handle MSG_ERRQUEUE
*/
-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct sock_exterr_skb *serr;
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
+ *addr_len = sizeof(*sin);
}
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
sin->sin6_family = AF_INET6;
sin->sin6_flowinfo = 0;
+ sin->sin6_port = 0;
if (skb->protocol == htons(ETH_P_IPV6)) {
sin->sin6_addr = ipv6_hdr(skb)->saddr;
if (np->rxopt.all)
/*
* Handle IPV6_RECVPATHMTU
*/
-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+ int *addr_len)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
sin->sin6_port = 0;
sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
+ *addr_len = sizeof(*sin);
}
put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
}
rcu_read_unlock_bh();
- IP6_INC_STATS_BH(dev_net(dst->dev),
- ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+ IP6_INC_STATS(dev_net(dst->dev),
+ ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
return -EINVAL;
}
/* Compatibility glue so we can support IPv6 when it's compiled as a module */
-static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+ int *addr_len)
{
return -EAFNOSUPPORT;
}
}
EXPORT_SYMBOL(inet6_add_protocol);
-/*
- * Remove a protocol from the hash tables.
- */
-
int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
{
int ret;
return -EOPNOTSUPP;
if (flags & MSG_ERRQUEUE)
- return ipv6_recv_error(sk, msg, len);
+ return ipv6_recv_error(sk, msg, len, addr_len);
if (np->rxpmtu && np->rxopt.bits.rxpmtu)
- return ipv6_recv_rxpmtu(sk, msg, len);
+ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
dev_put(dev);
}
+/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
+ * if sufficient data bytes are available
+ */
+static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb)
+{
+ const struct iphdr *iph = (const struct iphdr *) skb->data;
+ struct rt6_info *rt;
+ struct sk_buff *skb2;
+
+ if (!pskb_may_pull(skb, iph->ihl * 4 + sizeof(struct ipv6hdr) + 8))
+ return 1;
+
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+
+ if (!skb2)
+ return 1;
+
+ skb_dst_drop(skb2);
+ skb_pull(skb2, iph->ihl * 4);
+ skb_reset_network_header(skb2);
+
+ rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+
+ if (rt && rt->dst.dev)
+ skb2->dev = rt->dst.dev;
+
+ icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
+
+ if (rt)
+ ip6_rt_put(rt);
+
+ kfree_skb(skb2);
+
+ return 0;
+}
static int ipip6_err(struct sk_buff *skb, u32 info)
{
-
-/* All the routers (except for Linux) return only
- 8 bytes of packet payload. It means, that precise relaying of
- ICMP in the real Internet is absolutely infeasible.
- */
const struct iphdr *iph = (const struct iphdr *)skb->data;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
case ICMP_DEST_UNREACH:
switch (code) {
case ICMP_SR_FAILED:
- case ICMP_PORT_UNREACH:
/* Impossible event. */
return 0;
default:
goto out;
err = 0;
+ if (!ipip6_err_gen_icmpv6_unreach(skb))
+ goto out;
+
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
goto out;
if (!new_skb) {
ip_rt_put(rt);
dev->stats.tx_dropped++;
- dev_kfree_skb(skb);
+ kfree_skb(skb);
return NETDEV_TX_OK;
}
if (skb->sk)
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- dev_kfree_skb(skb);
+ kfree_skb(skb);
out:
dev->stats.tx_errors++;
return NETDEV_TX_OK;
tx_err:
dev->stats.tx_errors++;
- dev_kfree_skb(skb);
+ kfree_skb(skb);
return NETDEV_TX_OK;
}
{
const struct ipv6hdr *iph = skb_gro_network_header(skb);
__wsum wsum;
- __sum16 sum;
+
+ /* Don't bother verifying checksum if we're going to flush anyway. */
+ if (NAPI_GRO_CB(skb)->flush)
+ goto skip_csum;
+
+ wsum = skb->csum;
switch (skb->ip_summed) {
+ case CHECKSUM_NONE:
+ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+ wsum);
+
+ /* fall through */
+
case CHECKSUM_COMPLETE:
if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
- skb->csum)) {
+ wsum)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
}
-flush:
+
NAPI_GRO_CB(skb)->flush = 1;
return NULL;
-
- case CHECKSUM_NONE:
- wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
- skb_gro_len(skb),
- IPPROTO_TCP, 0));
- sum = csum_fold(skb_checksum(skb,
- skb_gro_offset(skb),
- skb_gro_len(skb),
- wsum));
- if (sum)
- goto flush;
-
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- break;
}
+skip_csum:
return tcp_gro_receive(head, skb);
}
bool slow;
if (flags & MSG_ERRQUEUE)
- return ipv6_recv_error(sk, msg, len);
+ return ipv6_recv_error(sk, msg, len, addr_len);
if (np->rxpmtu && np->rxopt.bits.rxpmtu)
- return ipv6_recv_rxpmtu(sk, msg, len);
+ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
try_again:
skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
*addr_len = sizeof(*lsa);
if (flags & MSG_ERRQUEUE)
- return ipv6_recv_error(sk, msg, len);
+ return ipv6_recv_error(sk, msg, len, addr_len);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
* Bit 17 is marked as already used since the VFS quota code
* also abused this API and relied on family == group ID, we
* cater to that by giving it a static family and group ID.
+ * Bit 18 is marked as already used since the PMCRAID driver
+ * did the same thing as the VFS quota code (maybe copied?)
*/
static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
- BIT(GENL_ID_VFS_DQUOT);
+ BIT(GENL_ID_VFS_DQUOT) |
+ BIT(GENL_ID_PMCRAID);
static unsigned long *mc_groups = &mc_group_start;
static unsigned long mc_groups_longs = 1;
for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
if (id_gen_idx != GENL_ID_VFS_DQUOT &&
+ id_gen_idx != GENL_ID_PMCRAID &&
!genl_family_find_byid(id_gen_idx))
return id_gen_idx;
if (++id_gen_idx > GENL_MAX_ID)
{
int first_id;
int n_groups = family->n_mcgrps;
- int err, i;
+ int err = 0, i;
bool groups_allocated = false;
if (!n_groups)
} else if (strcmp(family->name, "NET_DM") == 0) {
first_id = 1;
BUG_ON(n_groups != 1);
- } else if (strcmp(family->name, "VFS_DQUOT") == 0) {
+ } else if (family->id == GENL_ID_VFS_DQUOT) {
first_id = GENL_ID_VFS_DQUOT;
BUG_ON(n_groups != 1);
+ } else if (family->id == GENL_ID_PMCRAID) {
+ first_id = GENL_ID_PMCRAID;
+ BUG_ON(n_groups != 1);
} else {
groups_allocated = true;
err = genl_allocate_reserve_groups(n_groups, &first_id);
pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
- spin_lock(&rb_queue->lock);
+ spin_lock_bh(&rb_queue->lock);
pkc->delete_blk_timer = 1;
- spin_unlock(&rb_queue->lock);
+ spin_unlock_bh(&rb_queue->lock);
prb_del_retire_blk_timer(pkc);
}
if (rnd < clg->a4) {
clg->state = 4;
return true;
- } else if (clg->a4 < rnd && rnd < clg->a1) {
+ } else if (clg->a4 < rnd && rnd < clg->a1 + clg->a4) {
clg->state = 3;
return true;
- } else if (clg->a1 < rnd)
+ } else if (clg->a1 + clg->a4 < rnd)
clg->state = 1;
break;
clg->state = 2;
if (net_random() < clg->a4)
return true;
+ break;
case 2:
if (net_random() < clg->a2)
clg->state = 1;
- if (clg->a3 > net_random())
+ if (net_random() > clg->a3)
return true;
}
#include <net/netlink.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
+#include <net/tcp.h>
/* Simple Token Bucket Filter.
};
+/*
+ * Return length of individual segments of a gso packet,
+ * including all headers (MAC, IP, TCP/UDP)
+ */
+static unsigned int skb_gso_seglen(const struct sk_buff *skb)
+{
+ unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
+ const struct skb_shared_info *shinfo = skb_shinfo(skb);
+
+ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+ hdr_len += tcp_hdrlen(skb);
+ else
+ hdr_len += sizeof(struct udphdr);
+ return hdr_len + shinfo->gso_size;
+}
+
/* GSO packet is too big, segment it so that tbf can transmit
* each segment in time
*/
while (segs) {
nskb = segs->next;
segs->next = NULL;
- if (likely(segs->len <= q->max_size)) {
- qdisc_skb_cb(segs)->pkt_len = segs->len;
- ret = qdisc_enqueue(segs, q->qdisc);
- } else {
- ret = qdisc_reshape_fail(skb, sch);
- }
+ qdisc_skb_cb(segs)->pkt_len = segs->len;
+ ret = qdisc_enqueue(segs, q->qdisc);
if (ret != NET_XMIT_SUCCESS) {
if (net_xmit_drop_count(ret))
sch->qstats.drops++;
int ret;
if (qdisc_pkt_len(skb) > q->max_size) {
- if (skb_is_gso(skb))
+ if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size)
return tbf_segment(skb, sch);
return qdisc_reshape_fail(skb, sch);
}
if (max_size < 0)
goto done;
+ if (max_size < psched_mtu(qdisc_dev(sch)))
+ pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n",
+ max_size, qdisc_dev(sch)->name,
+ psched_mtu(qdisc_dev(sch)));
+
if (q->qdisc != &noop_qdisc) {
err = fifo_set_limit(q->qdisc, qopt->limit);
if (err)
* for a given destination transport address.
*/
- if (!tp->rto_pending) {
+ if (!chunk->resent && !tp->rto_pending) {
chunk->rtt_in_progress = 1;
tp->rto_pending = 1;
}
+
has_data = 1;
}
transport->rto_pending = 0;
}
+ chunk->resent = 1;
+
/* Move the chunk to the retransmit queue. The chunks
* on the retransmit queue are always kept in order.
*/
* instance).
*/
if (!tchunk->tsn_gap_acked &&
+ !tchunk->resent &&
tchunk->rtt_in_progress) {
tchunk->rtt_in_progress = 0;
rtt = jiffies - tchunk->sent_at;
*/
if (!tchunk->tsn_gap_acked) {
tchunk->tsn_gap_acked = 1;
- *highest_new_tsn_in_sack = tsn;
+ if (TSN_lt(*highest_new_tsn_in_sack, tsn))
+ *highest_new_tsn_in_sack = tsn;
bytes_acked += sctp_data_size(tchunk);
if (!tchunk->transport)
migrate_bytes += sctp_data_size(tchunk);
if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
return -EFAULT;
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
- return -EINVAL;
+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
return 0;
}
static int
gss_refresh_null(struct rpc_task *task)
{
- return -EACCES;
+ return 0;
}
static __be32 *
} elsif ($arch eq "blackfin") {
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
$mcount_adjust = -4;
-} elsif ($arch eq "tilegx") {
+} elsif ($arch eq "tilegx" || $arch eq "tile") {
+ # Default to the newer TILE-Gx architecture if only "tile" is given.
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
$type = ".quad";
$alignment = 8;
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/err.h>
-#include <linux/sched.h>
#include <linux/rbtree.h>
-#include <linux/cred.h>
#include <linux/key-type.h>
#include <linux/digsig.h>
static struct key *keyring[INTEGRITY_KEYRING_MAX];
-#ifdef CONFIG_IMA_TRUSTED_KEYRING
-static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
- ".evm",
- ".module",
- ".ima",
-};
-#else
static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
"_evm",
"_module",
"_ima",
};
-#endif
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
const char *digest, int digestlen)
if (!keyring[id]) {
keyring[id] =
- request_key(&key_type_keyring, keyring_name[id], NULL);
+ request_key(&key_type_keyring, keyring_name[id], NULL);
if (IS_ERR(keyring[id])) {
int err = PTR_ERR(keyring[id]);
pr_err("no %s keyring: %d\n", keyring_name[id], err);
return -EOPNOTSUPP;
}
-
-int integrity_init_keyring(const unsigned int id)
-{
- const struct cred *cred = current_cred();
- const struct user_struct *user = cred->user;
-
- keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
- KGIDT_INIT(0), cred,
- ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
- KEY_USR_VIEW | KEY_USR_READ),
- KEY_ALLOC_NOT_IN_QUOTA, user->uid_keyring);
- if (!IS_ERR(keyring[id]))
- set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags);
- else
- pr_info("Can't allocate %s keyring (%ld)\n",
- keyring_name[id], PTR_ERR(keyring[id]));
- return 0;
-}
For more information on integrity appraisal refer to:
<http://linux-ima.sourceforge.net>
If unsure, say N.
-
-config IMA_TRUSTED_KEYRING
- bool "Require all keys on the _ima keyring be signed"
- depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
- default y
- help
- This option requires that all keys added to the _ima
- keyring be signed by a key on the system trusted keyring.
#include "../integrity.h"
-enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
+enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
+ IMA_SHOW_ASCII };
enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
/* digest size for IMA, fits SHA1 or MD5 */
const char *op, struct inode *inode,
const unsigned char *filename);
int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
-int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
+int ima_calc_field_array_hash(struct ima_field_data *field_data,
+ struct ima_template_desc *desc, int num_fields,
struct ima_digest_data *hash);
int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
void ima_add_violation(struct file *file, const unsigned char *filename,
int xattr_len, struct ima_template_entry **entry);
int ima_store_template(struct ima_template_entry *entry, int violation,
struct inode *inode, const unsigned char *filename);
+void ima_free_template_entry(struct ima_template_entry *entry);
const char *ima_d_path(struct path *path, char **pathbuf);
/* rbtree tree calls to lookup, insert, delete
#include <crypto/hash_info.h>
#include "ima.h"
+/*
+ * ima_free_template_entry - free an existing template entry
+ */
+void ima_free_template_entry(struct ima_template_entry *entry)
+{
+ int i;
+
+ for (i = 0; i < entry->template_desc->num_fields; i++)
+ kfree(entry->template_data[i].data);
+
+ kfree(entry);
+}
+
/*
* ima_alloc_init_template - create and initialize a new template entry
*/
if (!*entry)
return -ENOMEM;
+ (*entry)->template_desc = template_desc;
for (i = 0; i < template_desc->num_fields; i++) {
struct ima_template_field *field = template_desc->fields[i];
u32 len;
(*entry)->template_data_len += sizeof(len);
(*entry)->template_data_len += len;
}
- (*entry)->template_desc = template_desc;
return 0;
out:
- kfree(*entry);
+ ima_free_template_entry(*entry);
*entry = NULL;
return result;
}
/* this function uses default algo */
hash.hdr.algo = HASH_ALGO_SHA1;
result = ima_calc_field_array_hash(&entry->template_data[0],
+ entry->template_desc,
num_fields, &hash.hdr);
if (result < 0) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
}
result = ima_store_template(entry, violation, inode, filename);
if (result < 0)
- kfree(entry);
+ ima_free_template_entry(entry);
err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
op, cause, result, 0);
if (!result || result == -EEXIST)
iint->flags |= IMA_MEASURED;
if (result < 0)
- kfree(entry);
+ ima_free_template_entry(entry);
}
void ima_audit_measurement(struct integrity_iint_cache *iint,
}
return result;
}
-
-#ifdef CONFIG_IMA_TRUSTED_KEYRING
-static int __init init_ima_keyring(void)
-{
- int ret;
-
- ret = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
- return 0;
-}
-late_initcall(init_ima_keyring);
-#endif
* Calculate the hash of template data
*/
static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
+ struct ima_template_desc *td,
int num_fields,
struct ima_digest_data *hash,
struct crypto_shash *tfm)
return rc;
for (i = 0; i < num_fields; i++) {
- rc = crypto_shash_update(&desc.shash,
- (const u8 *) &field_data[i].len,
- sizeof(field_data[i].len));
+ if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
+ rc = crypto_shash_update(&desc.shash,
+ (const u8 *) &field_data[i].len,
+ sizeof(field_data[i].len));
+ if (rc)
+ break;
+ }
rc = crypto_shash_update(&desc.shash, field_data[i].data,
field_data[i].len);
if (rc)
return rc;
}
-int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
+int ima_calc_field_array_hash(struct ima_field_data *field_data,
+ struct ima_template_desc *desc, int num_fields,
struct ima_digest_data *hash)
{
struct crypto_shash *tfm;
if (IS_ERR(tfm))
return PTR_ERR(tfm);
- rc = ima_calc_field_array_hash_tfm(field_data, num_fields, hash, tfm);
+ rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields,
+ hash, tfm);
ima_free_tfm(tfm);
struct ima_template_entry *e;
int namelen;
u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+ bool is_ima_template = false;
int i;
/* get entry */
ima_putc(m, e->template_desc->name, namelen);
/* 5th: template length (except for 'ima' template) */
- if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
+ if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0)
+ is_ima_template = true;
+
+ if (!is_ima_template)
ima_putc(m, &e->template_data_len,
sizeof(e->template_data_len));
/* 6th: template specific data */
for (i = 0; i < e->template_desc->num_fields; i++) {
- e->template_desc->fields[i]->field_show(m, IMA_SHOW_BINARY,
- &e->template_data[i]);
+ enum ima_show_type show = IMA_SHOW_BINARY;
+ struct ima_template_field *field = e->template_desc->fields[i];
+
+ if (is_ima_template && strcmp(field->field_id, "d") == 0)
+ show = IMA_SHOW_BINARY_NO_FIELD_LEN;
+ field->field_show(m, show, &e->template_data[i]);
}
return 0;
}
result = ima_calc_boot_aggregate(&hash.hdr);
if (result < 0) {
audit_cause = "hashing_error";
- kfree(entry);
goto err_out;
}
}
result = ima_store_template(entry, violation, NULL,
boot_aggregate_name);
if (result < 0)
- kfree(entry);
+ ima_free_template_entry(entry);
return;
err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
return NULL;
}
-static int template_fmt_size(char *template_fmt)
+static int template_fmt_size(const char *template_fmt)
{
char c;
int template_fmt_len = strlen(template_fmt);
return j + 1;
}
-static int template_desc_init_fields(char *template_fmt,
+static int template_desc_init_fields(const char *template_fmt,
struct ima_template_field ***fields,
int *num_fields)
{
- char *c, *template_fmt_ptr = template_fmt;
+ char *c, *template_fmt_copy, *template_fmt_ptr;
int template_num_fields = template_fmt_size(template_fmt);
int i, result = 0;
if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
return -EINVAL;
+ /* copying is needed as strsep() modifies the original buffer */
+ template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
+ if (template_fmt_copy == NULL)
+ return -ENOMEM;
+
*fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
if (*fields == NULL) {
result = -ENOMEM;
goto out;
}
+
+ template_fmt_ptr = template_fmt_copy;
for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
i < template_num_fields; i++) {
struct ima_template_field *f = lookup_template_field(c);
(*fields)[i] = f;
}
*num_fields = i;
- return 0;
out:
- kfree(*fields);
- *fields = NULL;
+ if (result < 0) {
+ kfree(*fields);
+ *fields = NULL;
+ }
+ kfree(template_fmt_copy);
return result;
}
enum data_formats datafmt,
struct ima_field_data *field_data)
{
- ima_putc(m, &field_data->len, sizeof(u32));
+ if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
+ ima_putc(m, &field_data->len, sizeof(u32));
+
if (!field_data->len)
return;
+
ima_putc(m, field_data->data, field_data->len);
}
ima_show_template_data_ascii(m, show, datafmt, field_data);
break;
case IMA_SHOW_BINARY:
+ case IMA_SHOW_BINARY_NO_FIELD_LEN:
ima_show_template_data_binary(m, show, datafmt, field_data);
break;
default:
#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen);
-
-int integrity_init_keyring(const unsigned int id);
#else
static inline int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen)
{
return -EOPNOTSUPP;
}
-
-static int integrity_init_keyring(const unsigned int id)
-{
- return 0;
-}
#endif
#ifdef CONFIG_INTEGRITY_AUDIT
if (new_rate < 0)
break;
/* make sure we are below the ABDAC clock */
- if (new_rate <= clk_get_rate(dac->pclk)) {
+ if (index < MAX_NUM_RATES &&
+ new_rate <= clk_get_rate(dac->pclk)) {
dac->rates[index] = new_rate / 256;
index++;
}
return;
index = s->packet_index;
+ /* this module generate empty packet for 'no data' */
syt = calculate_syt(s, cycle);
- if (!(s->flags & CIP_BLOCKING)) {
+ if (!(s->flags & CIP_BLOCKING))
data_blocks = calculate_data_blocks(s);
- } else {
- if (syt != 0xffff) {
- data_blocks = s->syt_interval;
- } else {
- data_blocks = 0;
- syt = 0xffffff;
- }
- }
+ else if (syt != 0xffff)
+ data_blocks = s->syt_interval;
+ else
+ data_blocks = 0;
buffer = s->buffer.packets[index].buffer;
buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0)
return;
- quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx));
+ quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx) / 4);
for (stream = 0; stream < tx_rx_header.number; ++stream) {
if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 +
stream * tx_rx_header.size,
if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0)
return;
- quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx));
+ quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx) / 4);
for (stream = 0; stream < tx_rx_header.number; ++stream) {
if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 +
stream * tx_rx_header.size,
unsigned int in_reset:1; /* during reset operation */
unsigned int power_keep_link_on:1; /* don't power off HDA link */
unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
- unsigned int avoid_link_reset:1; /* don't reset link at runtime PM */
int primary_dig_out_type; /* primary digital out PCM type */
};
for (i = 0; i < num_pins; i++) {
hda_nid_t pin = pins[i];
- if (pin == spec->hp_mic_pin) {
- int ret = create_hp_mic_jack_mode(codec, pin);
- if (ret < 0)
- return ret;
+ if (pin == spec->hp_mic_pin)
continue;
- }
if (get_out_jack_num_items(codec, pin) > 1) {
struct snd_kcontrol_new *knew;
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
val &= ~(AC_PINCTL_VREFEN | PIN_HP);
val |= get_vref_idx(vref_caps, idx) | PIN_IN;
} else
- val = snd_hda_get_default_vref(codec, nid);
+ val = snd_hda_get_default_vref(codec, nid) | PIN_IN;
}
snd_hda_set_pin_ctl_cache(codec, nid, val);
call_hp_automute(codec, NULL);
struct hda_gen_spec *spec = codec->spec;
struct snd_kcontrol_new *knew;
- if (get_out_jack_num_items(codec, pin) <= 1 &&
- get_in_jack_num_items(codec, pin) <= 1)
- return 0; /* no need */
knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode",
&hp_mic_jack_mode_enum);
if (!knew)
return 0;
}
+/* return true if either a volume or a mute amp is found for the given
+ * aamix path; the amp has to be either in the mixer node or its direct leaf
+ */
+static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid,
+ hda_nid_t pin, unsigned int *mix_val,
+ unsigned int *mute_val)
+{
+ int idx, num_conns;
+ const hda_nid_t *list;
+ hda_nid_t nid;
+
+ idx = snd_hda_get_conn_index(codec, mix_nid, pin, true);
+ if (idx < 0)
+ return false;
+
+ *mix_val = *mute_val = 0;
+ if (nid_has_volume(codec, mix_nid, HDA_INPUT))
+ *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
+ if (nid_has_mute(codec, mix_nid, HDA_INPUT))
+ *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
+ if (*mix_val && *mute_val)
+ return true;
+
+ /* check leaf node */
+ num_conns = snd_hda_get_conn_list(codec, mix_nid, &list);
+ if (num_conns < idx)
+ return false;
+ nid = list[idx];
+ if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT))
+ *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+ if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT))
+ *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+
+ return *mix_val || *mute_val;
+}
+
/* create input playback/capture controls for the given pin */
static int new_analog_input(struct hda_codec *codec, int input_idx,
hda_nid_t pin, const char *ctlname, int ctlidx,
{
struct hda_gen_spec *spec = codec->spec;
struct nid_path *path;
- unsigned int val;
+ unsigned int mix_val, mute_val;
int err, idx;
- if (!nid_has_volume(codec, mix_nid, HDA_INPUT) &&
- !nid_has_mute(codec, mix_nid, HDA_INPUT))
- return 0; /* no need for analog loopback */
+ if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val))
+ return 0;
path = snd_hda_add_new_path(codec, pin, mix_nid, 0);
if (!path)
spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path);
idx = path->idx[path->depth - 1];
- if (nid_has_volume(codec, mix_nid, HDA_INPUT)) {
- val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
- err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val);
+ if (mix_val) {
+ err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val);
if (err < 0)
return err;
- path->ctls[NID_PATH_VOL_CTL] = val;
+ path->ctls[NID_PATH_VOL_CTL] = mix_val;
}
- if (nid_has_mute(codec, mix_nid, HDA_INPUT)) {
- val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
- err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val);
+ if (mute_val) {
+ err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val);
if (err < 0)
return err;
- path->ctls[NID_PATH_MUTE_CTL] = val;
+ path->ctls[NID_PATH_MUTE_CTL] = mute_val;
}
path->active = true;
if (err < 0)
return err;
+ /* create "Headphone Mic Jack Mode" if no input selection is
+ * available (or user specifies add_jack_modes hint)
+ */
+ if (spec->hp_mic_pin &&
+ (spec->auto_mic || spec->input_mux.num_items == 1 ||
+ spec->add_jack_modes)) {
+ err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin);
+ if (err < 0)
+ return err;
+ }
+
if (spec->add_jack_modes) {
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
err = create_out_jack_modes(codec, cfg->line_outs,
STATESTS_INT_MASK);
azx_stop_chip(chip);
- if (!chip->bus->avoid_link_reset)
- azx_enter_link_reset(chip);
+ azx_enter_link_reset(chip);
azx_clear_irq_pending(chip);
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
hda_display_power(false);
}
dev++;
- complete_all(&chip->probe_wait);
+ if (chip->disabled)
+ complete_all(&chip->probe_wait);
return 0;
out_free:
if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo)
pm_runtime_put_noidle(&pci->dev);
- return 0;
-
out_free:
- chip->init_failed = 1;
+ if (err < 0)
+ chip->init_failed = 1;
+ complete_all(&chip->probe_wait);
return err;
}
if (!spec->eapd_nid)
return;
+ if (codec->inv_eapd)
+ enabled = !enabled;
snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
AC_VERB_SET_EAPD_BTLENABLE,
enabled ? 0x02 : 0x00);
*/
spec->gen.multiout.no_share_stream = 1;
+ /* AD1986A can't manage the dynamic pin on/off smoothly */
+ spec->gen.auto_mute_via_amp = 1;
+
snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl,
ad1986a_fixups);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
+ spec->gen.own_eapd_ctl = 1;
snd_hda_sequence_write_cache(codec, gpio_init_verbs);
break;
case HDA_FIXUP_ACT_PROBE:
#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
#include <linux/thinkpad_acpi.h>
+#include <acpi/acpi.h>
static int (*led_set_func)(int, bool);
+static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
+ void **rv)
+{
+ bool *found = context;
+ *found = true;
+ return AE_OK;
+}
+
+static bool is_thinkpad(struct hda_codec *codec)
+{
+ bool found = false;
+ if (codec->subsystem_id >> 16 != 0x17aa)
+ return false;
+ if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
+ return true;
+ found = false;
+ return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
+}
+
static void update_tpacpi_mute_led(void *private_data, int enabled)
{
struct hda_codec *codec = private_data;
bool removefunc = false;
if (action == HDA_FIXUP_ACT_PROBE) {
+ if (!is_thinkpad(codec))
+ return;
if (!led_set_func)
led_set_func = symbol_request(tpacpi_led_set);
if (!led_set_func) {
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
{}
static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
-static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
+static void jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct hdmi_spec *spec = codec->spec;
+ int pin_idx = pin_nid_to_pin_index(spec, jack->nid);
+ if (pin_idx < 0)
+ return;
+
+ if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
+ snd_hda_jack_report_sync(codec);
+}
+
+static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
+{
int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int pin_nid;
- int pin_idx;
struct hda_jack_tbl *jack;
int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
if (!jack)
return;
- pin_nid = jack->nid;
jack->jack_dirty = 1;
_snd_printd(SND_PR_VERBOSE,
"HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
- codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
+ codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
!!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
- pin_idx = pin_nid_to_pin_index(spec, pin_nid);
- if (pin_idx < 0)
- return;
-
- if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
- snd_hda_jack_report_sync(codec);
+ jack_callback(codec, jack);
}
static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
hda_nid_t pin_nid = per_pin->pin_nid;
hdmi_init_pin(codec, pin_nid);
- snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
+ snd_hda_jack_detect_enable_callback(codec, pin_nid, pin_nid,
+ codec->jackpoll_interval > 0 ? jack_callback : NULL);
}
return 0;
}
ALC889_FIXUP_DAC_ROUTE,
ALC889_FIXUP_MBP_VREF,
ALC889_FIXUP_IMAC91_VREF,
+ ALC889_FIXUP_MBA21_VREF,
ALC882_FIXUP_INV_DMIC,
ALC882_FIXUP_NO_PRIMARY_HP,
+ ALC887_FIXUP_ASUS_BASS,
+ ALC887_FIXUP_BASS_CHMAP,
};
static void alc889_fixup_coef(struct hda_codec *codec,
}
}
-/* Set VREF on speaker pins on imac91 */
-static void alc889_fixup_imac91_vref(struct hda_codec *codec,
- const struct hda_fixup *fix, int action)
+static void alc889_fixup_mac_pins(struct hda_codec *codec,
+ const hda_nid_t *nids, int num_nids)
{
struct alc_spec *spec = codec->spec;
- static hda_nid_t nids[2] = { 0x18, 0x1a };
int i;
- if (action != HDA_FIXUP_ACT_INIT)
- return;
- for (i = 0; i < ARRAY_SIZE(nids); i++) {
+ for (i = 0; i < num_nids; i++) {
unsigned int val;
val = snd_hda_codec_get_pin_target(codec, nids[i]);
val |= AC_PINCTL_VREF_50;
spec->gen.keep_vref_in_automute = 1;
}
+/* Set VREF on speaker pins on imac91 */
+static void alc889_fixup_imac91_vref(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ static hda_nid_t nids[2] = { 0x18, 0x1a };
+
+ if (action == HDA_FIXUP_ACT_INIT)
+ alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
+}
+
+/* Set VREF on speaker pins on mba21 */
+static void alc889_fixup_mba21_vref(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ static hda_nid_t nids[2] = { 0x18, 0x19 };
+
+ if (action == HDA_FIXUP_ACT_INIT)
+ alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
+}
+
/* Don't take HP output as primary
* Strangely, the speaker output doesn't work on Vaio Z and some Vaio
* all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
}
}
+static void alc_fixup_bass_chmap(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action);
+
static const struct hda_fixup alc882_fixups[] = {
[ALC882_FIXUP_ABIT_AW9D_MAX] = {
.type = HDA_FIXUP_PINS,
.chained = true,
.chain_id = ALC882_FIXUP_GPIO1,
},
+ [ALC889_FIXUP_MBA21_VREF] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc889_fixup_mba21_vref,
+ .chained = true,
+ .chain_id = ALC889_FIXUP_MBP_VREF,
+ },
[ALC882_FIXUP_INV_DMIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_inv_dmic_0x12,
.type = HDA_FIXUP_FUNC,
.v.func = alc882_fixup_no_primary_hp,
},
+ [ALC887_FIXUP_ASUS_BASS] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ {0x16, 0x99130130}, /* bass speaker */
+ {}
+ },
+ .chained = true,
+ .chain_id = ALC887_FIXUP_BASS_CHMAP,
+ },
+ [ALC887_FIXUP_BASS_CHMAP] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc_fixup_bass_chmap,
+ },
};
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
+ SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
+ SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
alc_write_coef_idx(codec, 0x18, 0x7388);
break;
case 0x10ec0668:
+ alc_write_coef_idx(codec, 0x11, 0x0001);
alc_write_coef_idx(codec, 0x15, 0x0d60);
alc_write_coef_idx(codec, 0xc3, 0x0000);
break;
alc_write_coef_idx(codec, 0x18, 0x7388);
break;
case 0x10ec0668:
+ alc_write_coef_idx(codec, 0x11, 0x0001);
alc_write_coef_idx(codec, 0x15, 0x0d50);
alc_write_coef_idx(codec, 0xc3, 0x0000);
break;
vref);
}
-static void alc283_chromebook_caps(struct hda_codec *codec)
-{
- snd_hda_override_wcaps(codec, 0x03, 0);
-}
-
static void alc283_fixup_chromebook(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE:
- alc283_chromebook_caps(codec);
+ snd_hda_override_wcaps(codec, 0x03, 0);
/* Disable AA-loopback as it causes white noise */
spec->gen.mixer_nid = 0;
+ break;
+ case HDA_FIXUP_ACT_INIT:
+ /* Enable Line1 input control by verb */
+ val = alc_read_coef_idx(codec, 0x1a);
+ alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
+ break;
+ }
+}
+
+static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ struct alc_spec *spec = codec->spec;
+ int val;
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.hp_automute_hook = alc283_hp_automute_hook;
break;
case HDA_FIXUP_ACT_INIT:
/* Set to manual mode */
val = alc_read_coef_idx(codec, 0x06);
alc_write_coef_idx(codec, 0x06, val & ~0x000c);
- /* Enable Line1 input control by verb */
- val = alc_read_coef_idx(codec, 0x1a);
- alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
break;
}
}
ALC271_FIXUP_HP_GATE_MIC_JACK,
ALC269_FIXUP_ACER_AC700,
ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
+ ALC269VB_FIXUP_ASUS_ZENBOOK,
ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
ALC269VB_FIXUP_ORDISSIMO_EVE2,
ALC283_FIXUP_CHROME_BOOK,
+ ALC283_FIXUP_SENSE_COMBO_JACK,
ALC282_FIXUP_ASUS_TX300,
ALC283_FIXUP_INT_MIC,
ALC290_FIXUP_MONO_SPEAKERS,
.chained = true,
.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
},
+ [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_limit_int_mic_boost,
+ .chained = true,
+ .chain_id = ALC269VB_FIXUP_DMIC,
+ },
[ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_limit_int_mic_boost,
.type = HDA_FIXUP_FUNC,
.v.func = alc283_fixup_chromebook,
},
+ [ALC283_FIXUP_SENSE_COMBO_JACK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc283_fixup_sense_combo_jack,
+ .chained = true,
+ .chain_id = ALC283_FIXUP_CHROME_BOOK,
+ },
[ALC282_FIXUP_ASUS_TX300] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc282_fixup_asus_tx300,
SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
- SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
- SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
- SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK),
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
{.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
+ {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-chrome"},
+ {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
{}
};
ALC861_FIXUP_AMP_VREF_0F,
ALC861_FIXUP_NO_JACK_DETECT,
ALC861_FIXUP_ASUS_A6RP,
+ ALC660_FIXUP_ASUS_W7J,
};
/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
.v.func = alc861_fixup_asus_amp_vref_0f,
.chained = true,
.chain_id = ALC861_FIXUP_NO_JACK_DETECT,
+ },
+ [ALC660_FIXUP_ASUS_W7J] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* ASUS W7J needs a magic pin setup on unused NID 0x10
+ * for enabling outputs
+ */
+ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+ { }
+ },
}
};
static const struct snd_pci_quirk alc861_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
+ SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
};
/* override the 2.1 chmap */
-static void alc662_fixup_bass_chmap(struct hda_codec *codec,
+static void alc_fixup_bass_chmap(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
if (action == HDA_FIXUP_ACT_BUILD) {
},
[ALC662_FIXUP_BASS_CHMAP] = {
.type = HDA_FIXUP_FUNC,
- .v.func = alc662_fixup_bass_chmap,
+ .v.func = alc_fixup_bass_chmap,
.chained = true,
.chain_id = ALC662_FIXUP_ASUS_MODE4
},
},
[ALC662_FIXUP_BASS_1A_CHMAP] = {
.type = HDA_FIXUP_FUNC,
- .v.func = alc662_fixup_bass_chmap,
+ .v.func = alc_fixup_bass_chmap,
.chained = true,
.chain_id = ALC662_FIXUP_BASS_1A,
},
case 0x10ec0272:
case 0x10ec0663:
case 0x10ec0665:
+ case 0x10ec0668:
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
break;
case 0x10ec0273:
*/
static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
+ { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
{ .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
{ .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
- codec->bus->avoid_link_reset = 1;
+ /* resetting controller clears GPIO, so we need to keep on */
+ codec->bus->power_keep_link_on = 1;
}
}
goto out;
}
+ snd_soc_card_set_drvdata(card, priv);
+
card->dev = &pdev->dev;
card->owner = THIS_MODULE;
card->dai_link = dai;
ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
-SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
- ARIZONA_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
- ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
- ARIZONA_OUT3_OSR_SHIFT, 1, 0),
-SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
- ARIZONA_OUT4_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
- ARIZONA_OUT5_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
- ARIZONA_OUT6_OSR_SHIFT, 1, 0),
-
SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT,
0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
- ARIZONA_OUTPUT_PATH_CONFIG_1R,
- ARIZONA_OUT1L_PGA_VOL_SHIFT,
- 0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("HPOUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
- ARIZONA_OUTPUT_PATH_CONFIG_2R,
- ARIZONA_OUT2L_PGA_VOL_SHIFT,
- 0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("HPOUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
- ARIZONA_OUTPUT_PATH_CONFIG_3R,
- ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
-
SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
iface |= 0x0001;
break;
case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
+ iface |= 0x0013;
break;
case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
+ iface |= 0x0003;
break;
default:
return -EINVAL;
/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
+
+ codec->cache_sync = 1;
break;
}
return -ENOMEM;
card->dev = &op->dev;
- platform_set_drvdata(op, pdata);
pdata->card = card;
if (ret)
dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
+ platform_set_drvdata(op, pdata);
+
return ret;
}
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
+#define KIRKWOOD_SPDIF_FORMATS \
+ (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
ctl);
}
- if (dai->id == 0)
- ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */
- else
- ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN; /* spdif */
-
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* configure */
ctl = priv->ctl_play;
+ if (dai->id == 0)
+ ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */
+ else
+ ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN; /* spdif */
+
value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
writel(value, priv->io + KIRKWOOD_PLAYCTL);
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000,
- .formats = KIRKWOOD_I2S_FORMATS,
+ .formats = KIRKWOOD_SPDIF_FORMATS,
},
.capture = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000,
- .formats = KIRKWOOD_I2S_FORMATS,
+ .formats = KIRKWOOD_SPDIF_FORMATS,
},
.ops = &kirkwood_i2s_dai_ops,
},
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
- .formats = KIRKWOOD_I2S_FORMATS,
+ .formats = KIRKWOOD_SPDIF_FORMATS,
},
.capture = {
.channels_min = 1,
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
- .formats = KIRKWOOD_I2S_FORMATS,
+ .formats = KIRKWOOD_SPDIF_FORMATS,
},
.ops = &kirkwood_i2s_dai_ops,
},
SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
n810_ext_control(&codec->dapm);
- return clk_enable(sys_clkout2);
+ return clk_prepare_enable(sys_clkout2);
}
static void n810_shutdown(struct snd_pcm_substream *substream)
{
- clk_disable(sys_clkout2);
+ clk_disable_unprepare(sys_clkout2);
}
static int n810_hw_params(struct snd_pcm_substream *substream,
config SND_SOC_RCAR
tristate "R-Car series SRU/SCU/SSIU/SSI support"
select SND_SIMPLE_CARD
+ select REGMAP
help
This option enables R-Car SUR/SCU/SSIU/SSI sound support
break;
case 2:
((u16 *)(&ucontrol->value.bytes.data))[0]
- &= ~params->mask;
+ &= cpu_to_be16(~params->mask);
break;
case 4:
((u32 *)(&ucontrol->value.bytes.data))[0]
- &= ~params->mask;
+ &= cpu_to_be32(~params->mask);
break;
default:
return -EINVAL;
#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)
{
*/
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
{
- struct device **ptr;
+ struct snd_soc_card **ptr;
int ret;
ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
ret = snd_soc_register_card(card);
if (ret == 0) {
- *ptr = dev;
+ *ptr = card;
devres_add(dev, ptr);
} else {
devres_free(ptr);
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
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)
[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;
}
}
const struct snd_dmaengine_pcm_config *config, unsigned int flags)
{
struct dmaengine_pcm *pcm;
+ int ret;
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (!pcm)
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);
{
struct snd_soc_platform *platform;
struct dmaengine_pcm *pcm;
- unsigned int i;
platform = snd_soc_lookup_platform(dev);
if (!platform)
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);
}
}
-static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
+static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
struct snd_soc_pcm_stream *codec_stream,
struct snd_soc_pcm_stream *cpu_stream)
{
- hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
- hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
+ struct snd_pcm_hardware *hw = &runtime->hw;
+
hw->channels_min = max(codec_stream->channels_min,
cpu_stream->channels_min);
hw->channels_max = min(codec_stream->channels_max,
if (cpu_stream->rates
& (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
hw->rates |= codec_stream->rates;
+
+ snd_pcm_limit_hw_rates(runtime);
+
+ hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
+ hw->rate_min = max(hw->rate_min, codec_stream->rate_min);
+ hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
+ hw->rate_max = min_not_zero(hw->rate_max, codec_stream->rate_max);
}
/*
/* Check that the codec and cpu DAIs are compatible */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
+ soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->playback,
&cpu_dai_drv->playback);
} else {
- soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
+ soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->capture,
&cpu_dai_drv->capture);
}
ret = -EINVAL;
- snd_pcm_limit_hw_rates(runtime);
if (!runtime->hw.rates) {
printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
codec_dai->name, cpu_dai->name);
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
{
struct tegra20_ac97 *ac97;
struct resource *mem;
- u32 of_dma[2];
void __iomem *regs;
int ret = 0;
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)) {
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)
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;
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) {
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)) {
#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"
}
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;
__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);
(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);
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);
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);
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;
__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);
(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);
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);
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);
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);
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) \
};
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,
};
{
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;
* 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),
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");
};
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);
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);
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;
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)
{
}
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,
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;
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);
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;
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
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);
#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
if (usb_pipein(ep->pipe) ||
snd_usb_endpoint_implicit_feedback_sink(ep)) {
+ urb_packs = packs_per_ms;
+ /*
+ * Wireless devices can poll at a max rate of once per 4ms.
+ * For dataintervals less than 5, increase the packet count to
+ * allow the host controller to use bursting to fill in the
+ * gaps.
+ */
+ if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_WIRELESS) {
+ int interval = ep->datainterval;
+ while (interval < 5) {
+ urb_packs <<= 1;
+ ++interval;
+ }
+ }
/* make capture URBs <= 1 ms and smaller than a period */
- urb_packs = min(max_packs_per_urb, packs_per_ms);
+ urb_packs = min(max_packs_per_urb, urb_packs);
while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
urb_packs >>= 1;
ep->nurbs = MAX_URBS;
static enum event_type
process_op(struct event_format *event, struct print_arg *arg, char **tok);
+/*
+ * For __print_symbolic() and __print_flags, we need to completely
+ * evaluate the first argument, which defines what to print next.
+ */
+static enum event_type
+process_field_arg(struct event_format *event, struct print_arg *arg, char **tok)
+{
+ enum event_type type;
+
+ type = process_arg(event, arg, tok);
+
+ while (type == EVENT_OP) {
+ type = process_op(event, arg, tok);
+ }
+
+ return type;
+}
+
static enum event_type
process_cond(struct event_format *event, struct print_arg *top, char **tok)
{
goto out_free;
}
- type = process_arg(event, field, &token);
+ type = process_field_arg(event, field, &token);
/* Handle operations in the first argument */
while (type == EVENT_OP)
goto out_free;
}
- type = process_arg(event, field, &token);
+ type = process_field_arg(event, field, &token);
+
if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free_field;
* is in the bottom half of the 32 bit field.
*/
offset &= 0xffff;
- val = (unsigned long long)(data + offset);
+ val = (unsigned long long)((unsigned long)data + offset);
break;
default: /* not sure what to do there */
return 0;
if (evsel->idx == (int) desc[i].leader_idx) {
evsel->leader = evsel;
/* {anon_group} is a dummy name */
- if (strcmp(desc[i].name, "{anon_group}"))
+ if (strcmp(desc[i].name, "{anon_group}")) {
evsel->group_name = desc[i].name;
+ desc[i].name = NULL;
+ }
evsel->nr_members = desc[i].nr_members;
if (i >= nr_groups || nr > 0) {
ret = 0;
out_free:
- while ((int) --i >= 0)
+ for (i = 0; i < nr_groups; i++)
free(desc[i].name);
free(desc);
/* Override latest entry if it had no specific time coverage */
if (!curr->start) {
comm__override(curr, str, timestamp);
- return 0;
+ } else {
+ new = comm__new(str, timestamp);
+ if (!new)
+ return -ENOMEM;
+ list_add(&new->list, &thread->comm_list);
}
- new = comm__new(str, timestamp);
- if (!new)
- return -ENOMEM;
-
- list_add(&new->list, &thread->comm_list);
thread->comm_set = true;
return 0;
.fi
.SH "SEE ALSO"
.LP
-cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1)
+cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1),
+cpupower\-idle\-set(1)
--- /dev/null
+.TH "CPUPOWER-IDLE-SET" "1" "0.1" "" "cpupower Manual"
+.SH "NAME"
+.LP
+cpupower idle\-set \- Utility to set cpu idle state specific kernel options
+.SH "SYNTAX"
+.LP
+cpupower [ \-c cpulist ] idle\-info [\fIoptions\fP]
+.SH "DESCRIPTION"
+.LP
+The cpupower idle\-set subcommand allows to set cpu idle, also called cpu
+sleep state, specific options offered by the kernel. One example is disabling
+sleep states. This can be handy for power vs performance tuning.
+.SH "OPTIONS"
+.LP
+.TP
+\fB\-d\fR \fB\-\-disable\fR
+Disable a specific processor sleep state.
+.TP
+\fB\-e\fR \fB\-\-enable\fR
+Enable a specific processor sleep state.
+
+.SH "REMARKS"
+.LP
+Cpuidle Governors Policy on Disabling Sleep States
+
+.RS 4
+Depending on the used cpuidle governor, implementing the kernel policy
+how to choose sleep states, subsequent sleep states on this core, might get
+disabled as well.
+
+There are two cpuidle governors ladder and menu. While the ladder
+governor is always available, if CONFIG_CPU_IDLE is selected, the
+menu governor additionally requires CONFIG_NO_HZ.
+
+The behavior and the effect of the disable variable depends on the
+implementation of a particular governor. In the ladder governor, for
+example, it is not coherent, i.e. if one is disabling a light state,
+then all deeper states are disabled as well. Likewise, if one enables a
+deep state but a lighter state still is disabled, then this has no effect.
+.RE
+.LP
+Disabling the Lightest Sleep State may not have any Affect
+
+.RS 4
+If criteria are not met to enter deeper sleep states and the lightest sleep
+state is chosen when idle, the kernel may still enter this sleep state,
+irrespective of whether it is disabled or not. This is also reflected in
+the usage count of the disabled sleep state when using the cpupower idle-info
+command.
+.RE
+.LP
+Selecting specific CPU Cores
+
+.RS 4
+By default processor sleep states of all CPU cores are set. Please refer
+to the cpupower(1) manpage in the \-\-cpu option section how to disable
+C-states of specific cores.
+.RE
+.SH "FILES"
+.nf
+\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP
+\fI/sys/devices/system/cpu/cpuidle/*\fP
+.fi
+.SH "AUTHORS"
+.nf
+Thomas Renninger <trenn@suse.de>
+.fi
+.SH "SEE ALSO"
+.LP
+cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1),
+cpupower\-idle\-info(1)
int sysfs_is_idlestate_disabled(unsigned int cpu,
unsigned int idlestate)
{
- if (sysfs_get_idlestate_count(cpu) < idlestate)
+ if (sysfs_get_idlestate_count(cpu) <= idlestate)
return -1;
if (!sysfs_idlestate_file_exists(cpu, idlestate,
char value[SYSFS_PATH_MAX];
int bytes_written;
- if (sysfs_get_idlestate_count(cpu) < idlestate)
+ if (sysfs_get_idlestate_count(cpu) <= idlestate)
return -1;
if (!sysfs_idlestate_file_exists(cpu, idlestate,