ARM SoC driver specific changes

These changes are all driver specific and cross over between arm-soc
 contents and some other subsystem, in these cases cpufreq, crypto,
 dma, pinctrl, mailbox and usb, and the subsystem owners agreed to
 have these changes merged through arm-soc. As we proceed to untangle
 the dependencies between platform code and driver code, the amount of
 changes in this category is fortunately shrinking, for 3.11 we have
 16 branches here and 101 non-merge changesets, the majority of which
 are for the stedma40 dma engine driver used in the ux500 platform.
 Cleaning up that code touches multiple subsystems, but gets rid
 of the dependency in the end.
 
 The mailbox code moved out from mach-omap2 to drivers/mailbox
 is an intermediate step and is still omap specific at the moment.
 Patches exist to generalize the subsystem and add other drivers
 with the same API, but those did not make it for 3.11.
 
 Conflicts:
 * In cpu-db8500.c results from the removal of the u8500_of_init_devices
   function in combination with the split of u8500_auxdata_lookup.
 
 * In arch/arm/mach-omap2/devices.c, the includes got reshuffled.
   we need to keep linux/wl12xx.h and linux/platform_data/mailbox-omap.h.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIVAwUAUdLnomCrR//JCVInAQJI/A/9FydsQa9sdnzLFgcdX5BeRRwkXLfDifCM
 zDTfUBo+LriKOs7QHblmDg1MnY1UMB2IfrdHD0FsjK7WbZ/91EMAGDPYcI7Fu4+u
 pGStxwWi2v+oCT1jjeOkCPT7hdCqogsSpybYq8itSb+zdvdOi6U35dWEKz8xGqz4
 vTL9gTZbJP0kowkjIcaryk7FIj7BTIvMCW8n55JZEkDe0BuSJGYn5c3Mntut12ZK
 5xM2PeNe2sd3dIdA6XbM2ye/XmYa8xY8Qu4/ijxfH1gnJLvz9Unp96nRXpEbIeMb
 BH2Sro8dxsMCaweIQhSRKGnUWMYO/Rh7/+5EqzJ163Ezthx9nvHXJY2ndWuD7uM1
 IcGrMxLtqP22TEMtZAVEATDp/5ymxEo5GM+eayUojQDn213wOJjRs5xz5IBsH4KM
 8CM/gpadWmLjWku72yEV4lryLcdS0NVQzpTnEbILEGOU4u7qJtxRAp7x7tWBtFg8
 4m/eWcSVk/U2SYbXmQHsfukuWgKY0cnZbctPcdnaqXwTP7toJEAK3gxoMtWh49Jq
 2M2PVFyFejaaq5b/71wAJ7ePYw56H0N/F3RsGpPE55AY15++gSoQ+3t2Si68hDw8
 NtyJMkQYpTvtqJbHXWpQQ3Zfs7pDBe01WDV7i+m4JTNggxUDaO/t1Fqp+fEksm4J
 r+luEf5Gcgk=
 =mJsI
 -----END PGP SIGNATURE-----

Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC driver specific changes from Arnd Bergmann:
 "These changes are all driver specific and cross over between arm-soc
  contents and some other subsystem, in these cases cpufreq, crypto,
  dma, pinctrl, mailbox and usb, and the subsystem owners agreed to have
  these changes merged through arm-soc.

  As we proceed to untangle the dependencies between platform code and
  driver code, the amount of changes in this category is fortunately
  shrinking, for 3.11 we have 16 branches here and 101 non-merge
  changesets, the majority of which are for the stedma40 dma engine
  driver used in the ux500 platform.  Cleaning up that code touches
  multiple subsystems, but gets rid of the dependency in the end.

  The mailbox code moved out from mach-omap2 to drivers/mailbox is an
  intermediate step and is still omap specific at the moment.  Patches
  exist to generalize the subsystem and add other drivers with the same
  API, but those did not make it for 3.11."

* tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (101 commits)
  crypto: ux500: use dmaengine_submit API
  crypto: ux500: use dmaengine_prep_slave_sg API
  crypto: ux500: use dmaengine_device_control API
  crypto: ux500/crypt: add missing __iomem qualifiers
  crypto: ux500/hash: add missing static qualifiers
  crypto: ux500/hash: use readl on iomem addresses
  dmaengine: ste_dma40: Declare memcpy config as static
  ARM: ux500: Remove mop500_snowball_ethernet_clock_enable()
  ARM: ux500: Correct the EN_3v3 regulator's on/off GPIO
  ARM: ux500: Provide a AB8500 GPIO Device Tree node
  gpio: rcar: fix gpio_rcar_of_table
  gpio-rcar: Remove #ifdef CONFIG_OF around OF-specific sections
  gpio-rcar: Reference core gpio documentation in the DT bindings
  clk: exynos5250: Add enum entries for divider clock of i2s1 and i2s2
  ARM: dts: Update Samsung I2S documentation
  ARM: dts: add clock provider information for i2s controllers in Exynos5250
  ARM: dts: add Exynos audio subsystem clock controller node
  clk: samsung: register audio subsystem clocks using common clock framework
  ARM: dts: use #include for all device trees for Samsung
  pinctrl: s3c24xx: use correct header for chained_irq functions
  ...
This commit is contained in:
Linus Torvalds 2013-07-02 14:33:21 -07:00
commit 0bf6a210a4
112 changed files with 3167 additions and 1650 deletions

View file

@ -95,7 +95,6 @@ GPMC chip-select settings properties for child nodes. All are optional.
- gpmc,burst-wrap Enables wrap bursting
- gpmc,burst-read Enables read page/burst mode
- gpmc,burst-write Enables write page/burst mode
- gpmc,device-nand Device is NAND
- gpmc,device-width Total width of device(s) connected to a GPMC
chip-select in bytes. The GPMC supports 8-bit
and 16-bit devices and so this property must be

View file

@ -0,0 +1,64 @@
* Samsung Audio Subsystem Clock Controller
The Samsung Audio Subsystem clock controller generates and supplies clocks
to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
binding described here is applicable to all SoC's in Exynos family.
Required Properties:
- compatible: should be one of the following:
- "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
- "samsung,exynos5250-audss-clock" - controller compatible with all Exynos5 SoCs.
- reg: physical base address and length of the controller's register set.
- #clock-cells: should be 1.
The following is the list of clocks generated by the controller. Each clock is
assigned an identifier and client nodes use this identifier to specify the
clock which they consume. Some of the clocks are available only on a particular
Exynos4 SoC and this is specified where applicable.
Provided clocks:
Clock ID SoC (if specific)
-----------------------------------------------
mout_audss 0
mout_i2s 1
dout_srp 2
dout_aud_bus 3
dout_i2s 4
srp_clk 5
i2s_bus 6
sclk_i2s 7
pcm_bus 8
sclk_pcm 9
Example 1: An example of a clock controller node is listed below.
clock_audss: audss-clock-controller@3810000 {
compatible = "samsung,exynos5250-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
};
Example 2: I2S controller node that consumes the clock generated by the clock
controller. Refer to the standard clock bindings for information
about 'clocks' and 'clock-names' property.
i2s0: i2s@03830000 {
compatible = "samsung,i2s-v5";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
&pdma0 9
&pdma0 8>;
dma-names = "tx", "rx", "tx-sec";
clocks = <&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_SCLK_I2S>,
<&clock_audss EXYNOS_MOUT_AUDSS>,
<&clock_audss EXYNOS_MOUT_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
"mout_audss", "mout_i2s";
};

View file

@ -0,0 +1,66 @@
* DMA40 DMA Controller
Required properties:
- compatible: "stericsson,dma40"
- reg: Address range of the DMAC registers
- reg-names: Names of the above areas to use during resource look-up
- interrupt: Should contain the DMAC interrupt number
- #dma-cells: must be <3>
- memcpy-channels: Channels to be used for memcpy
Optional properties:
- dma-channels: Number of channels supported by hardware - if not present
the driver will attempt to obtain the information from H/W
- disabled-channels: Channels which can not be used
Example:
dma: dma-controller@801C0000 {
compatible = "stericsson,db8500-dma40", "stericsson,dma40";
reg = <0x801C0000 0x1000 0x40010000 0x800>;
reg-names = "base", "lcpa";
interrupt-parent = <&intc>;
interrupts = <0 25 0x4>;
#dma-cells = <2>;
memcpy-channels = <56 57 58 59 60>;
disabled-channels = <12>;
dma-channels = <8>;
};
Clients
Required properties:
- dmas: Comma separated list of dma channel requests
- dma-names: Names of the aforementioned requested channels
Each dmas request consists of 4 cells:
1. A phandle pointing to the DMA controller
2. Device Type
3. The DMA request line number (only when 'use fixed channel' is set)
4. A 32bit mask specifying; mode, direction and endianess [NB: This list will grow]
0x00000001: Mode:
Logical channel when unset
Physical channel when set
0x00000002: Direction:
Memory to Device when unset
Device to Memory when set
0x00000004: Endianess:
Little endian when unset
Big endian when set
0x00000008: Use fixed channel:
Use automatic channel selection when unset
Use DMA request line number when set
Example:
uart@80120000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x80120000 0x1000>;
interrupts = <0 11 0x4>;
dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */
<&dma 13 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "rx";
status = "disabled";
};

View file

@ -39,46 +39,3 @@ Example:
#gpio-cells = <4>;
gpio-controller;
};
Samsung S3C24XX GPIO Controller
Required properties:
- compatible: Compatible property value should be "samsung,s3c24xx-gpio".
- reg: Physical base address of the controller and length of memory mapped
region.
- #gpio-cells: Should be 3. The syntax of the gpio specifier used by client nodes
should be the following with values derived from the SoC user manual.
<[phandle of the gpio controller node]
[pin number within the gpio controller]
[mux function]
[flags and pull up/down]
Values for gpio specifier:
- Pin number: depending on the controller a number from 0 up to 15.
- Mux function: Depending on the SoC and the gpio bank the gpio can be set
as input, output or a special function
- Flags and Pull Up/Down: the values to use differ for the individual SoCs
example S3C2416/S3C2450:
0 - Pull Up/Down Disabled.
1 - Pull Down Enabled.
2 - Pull Up Enabled.
Bit 16 (0x00010000) - Input is active low.
Consult the user manual for the correct values of Mux and Pull Up/Down.
- gpio-controller: Specifies that the node is a gpio controller.
- #address-cells: should be 1.
- #size-cells: should be 1.
Example:
gpa: gpio-controller@56000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "samsung,s3c24xx-gpio";
reg = <0x56000000 0x10>;
#gpio-cells = <3>;
gpio-controller;
};

View file

@ -0,0 +1,46 @@
* Renesas R-Car GPIO Controller
Required Properties:
- compatible: should be one of the following.
- "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller.
- "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
- "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller.
- "renesas,gpio-rcar": for generic R-Car GPIO controller.
- reg: Base address and length of each memory resource used by the GPIO
controller hardware module.
- interrupt-parent: phandle of the parent interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller.
Please refer to gpio.txt in this directory for details of gpio-ranges property
and the common GPIO bindings used by client devices.
Example: R8A7779 (R-Car H1) GPIO controller nodes
gpio0: gpio@ffc40000 {
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc40000 0x2c>;
interrupt-parent = <&gic>;
interrupts = <0 141 0x4>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 0 32>;
};
...
gpio6: gpio@ffc46000 {
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc46000 0x2c>;
interrupt-parent = <&gic>;
interrupts = <0 147 0x4>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 192 9>;
};

View file

@ -29,6 +29,13 @@ Optional properties:
"bch4" 4-bit BCH ecc code
"bch8" 8-bit BCH ecc code
- ti,nand-xfer-type: A string setting the data transfer type. One of:
"prefetch-polled" Prefetch polled mode (default)
"polled" Polled mode, without prefetch
"prefetch-dma" Prefetch enabled sDMA mode
"prefetch-irq" Prefetch enabled irq mode
- elm_id: Specifies elm device node. This is required to support BCH
error correction using ELM module.
@ -55,6 +62,7 @@ Example for an AM33xx board:
reg = <0 0 0>; /* CS0, offset 0 */
nand-bus-width = <16>;
ti,nand-ecc-opt = "bch8";
ti,nand-xfer-type = "polled";
gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>;

View file

@ -7,6 +7,10 @@ on-chip controllers onto these pads.
Required Properties:
- compatible: should be one of the following.
- "samsung,s3c2412-pinctrl": for S3C2412-compatible pin-controller,
- "samsung,s3c2416-pinctrl": for S3C2416-compatible pin-controller,
- "samsung,s3c2440-pinctrl": for S3C2440-compatible pin-controller,
- "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
- "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
- "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
- "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
@ -116,6 +120,10 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
- compatible: identifies the type of the external wakeup interrupt controller
The possible values are:
- samsung,s3c2410-wakeup-eint: represents wakeup interrupt controller
found on Samsung S3C24xx SoCs except S3C2412 and S3C2413,
- samsung,s3c2412-wakeup-eint: represents wakeup interrupt controller
found on Samsung S3C2412 and S3C2413 SoCs,
- samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
found on Samsung S3C64xx SoCs,
- samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller

View file

@ -8,6 +8,16 @@ Required SoC Specific Properties:
- dmas: list of DMA controller phandle and DMA request line ordered pairs.
- dma-names: identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas.
- clocks: Handle to iis clock and RCLK source clk.
- clock-names:
i2s0 uses some base clks from CMU and some are from audio subsystem internal
clock controller. The clock names for i2s0 should be "iis", "i2s_opclk0" and
"i2s_opclk1" as shown in the example below.
i2s1 and i2s2 uses clocks from CMU. The clock names for i2s1 and i2s2 should
be "iis" and "i2s_opclk0".
"iis" is the i2s bus clock and i2s_opclk0, i2s_opclk1 are sources of the root
clk. i2s0 has internal mux to select the source of root clk and i2s1 and i2s2
doesn't have any such mux.
Optional SoC Specific Properties:
@ -20,44 +30,26 @@ Optional SoC Specific Properties:
then this flag is enabled.
- samsung,idma-addr: Internal DMA register base address of the audio
sub system(used in secondary sound source).
Required Board Specific Properties:
- gpios: The gpio specifier for data out,data in, LRCLK, CDCLK and SCLK
interface lines. The format of the gpio specifier depends on the gpio
controller.
The syntax of samsung gpio specifier is
<[phandle of the gpio controller node]
[pin number within the gpio controller]
[mux function]
[flags and pull up/down]
[drive strength]>
- pinctrl-0: Should specify pin control groups used for this controller.
- pinctrl-names: Should contain only one value - "default".
Example:
- SoC Specific Portion:
i2s@03830000 {
i2s0: i2s@03830000 {
compatible = "samsung,i2s-v5";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
&pdma0 9
&pdma0 8>;
dma-names = "tx", "rx", "tx-sec";
clocks = <&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_SCLK_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
samsung,supports-6ch;
samsung,supports-rstclr;
samsung,supports-secdai;
samsung,idma-addr = <0x03000000>;
};
- Board Specific Portion:
i2s@03830000 {
gpios = <&gpz 0 2 0 0>, /* I2S_0_SCLK */
<&gpz 1 2 0 0>, /* I2S_0_CDCLK */
<&gpz 2 2 0 0>, /* I2S_0_LRCK */
<&gpz 3 2 0 0>, /* I2S_0_SDI */
<&gpz 4 2 0 0>, /* I2S_0_SDO[1] */
<&gpz 5 2 0 0>, /* I2S_0_SDO[2] */
<&gpz 6 2 0 0>; /* I2S_0_SDO[3] */
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
};

View file

@ -47,3 +47,85 @@ usb1: gadget@fffa4000 {
interrupts = <10 4>;
atmel,vbus-gpio = <&pioC 5 0>;
};
Atmel High-Speed USB device controller
Required properties:
- compatible: Should be "atmel,at91sam9rl-udc"
- reg: Address and length of the register set for the device
- interrupts: Should contain usba interrupt
- ep childnode: To specify the number of endpoints and their properties.
Optional properties:
- atmel,vbus-gpio: If present, specifies a gpio that needs to be
activated for the bus to be powered.
Required child node properties:
- name: Name of the endpoint.
- reg: Num of the endpoint.
- atmel,fifo-size: Size of the fifo.
- atmel,nb-banks: Number of banks.
- atmel,can-dma: Boolean to specify if the endpoint support DMA.
- atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
usb2: gadget@fff78000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "atmel,at91sam9rl-udc";
reg = <0x00600000 0x80000
0xfff78000 0x400>;
interrupts = <27 4 0>;
atmel,vbus-gpio = <&pioB 19 0>;
ep0 {
reg = <0>;
atmel,fifo-size = <64>;
atmel,nb-banks = <1>;
};
ep1 {
reg = <1>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <2>;
atmel,can-dma;
atmel,can-isoc;
};
ep2 {
reg = <2>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <2>;
atmel,can-dma;
atmel,can-isoc;
};
ep3 {
reg = <3>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <3>;
atmel,can-dma;
};
ep4 {
reg = <4>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <3>;
atmel,can-dma;
};
ep5 {
reg = <5>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <3>;
atmel,can-dma;
atmel,can-isoc;
};
ep6 {
reg = <6>;
atmel,fifo-size = <1024>;
atmel,nb-banks = <3>;
atmel,can-dma;
atmel,can-isoc;
};
};

View file

@ -0,0 +1,50 @@
Ux500 MUSB
Required properties:
- compatible : Should be "stericsson,db8500-musb"
- reg : Offset and length of registers
- interrupts : Interrupt; mode, number and trigger
- dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral"
or both "otg"
Optional properties:
- dmas : A list of dma channels;
dma-controller, event-line, fixed-channel, flags
- dma-names : An ordered list of channel names affiliated to the above
Example:
usb_per5@a03e0000 {
compatible = "stericsson,db8500-musb", "mentor,musb";
reg = <0xa03e0000 0x10000>;
interrupts = <0 23 0x4>;
interrupt-names = "mc";
dr_mode = "otg";
dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
<&dma 38 0 0x0>, /* Logical - MemToDev */
<&dma 37 0 0x2>, /* Logical - DevToMem */
<&dma 37 0 0x0>, /* Logical - MemToDev */
<&dma 36 0 0x2>, /* Logical - DevToMem */
<&dma 36 0 0x0>, /* Logical - MemToDev */
<&dma 19 0 0x2>, /* Logical - DevToMem */
<&dma 19 0 0x0>, /* Logical - MemToDev */
<&dma 18 0 0x2>, /* Logical - DevToMem */
<&dma 18 0 0x0>, /* Logical - MemToDev */
<&dma 17 0 0x2>, /* Logical - DevToMem */
<&dma 17 0 0x0>, /* Logical - MemToDev */
<&dma 16 0 0x2>, /* Logical - DevToMem */
<&dma 16 0 0x0>, /* Logical - MemToDev */
<&dma 39 0 0x2>, /* Logical - DevToMem */
<&dma 39 0 0x0>; /* Logical - MemToDev */
dma-names = "iep_1_9", "oep_1_9",
"iep_2_10", "oep_2_10",
"iep_3_11", "oep_3_11",
"iep_4_12", "oep_4_12",
"iep_5_13", "oep_5_13",
"iep_6_14", "oep_6_14",
"iep_7_15", "oep_7_15",
"iep_8", "oep_8";
};

View file

@ -2087,53 +2087,6 @@ menu "CPU Power Management"
if ARCH_HAS_CPUFREQ
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_S3C
bool
help
Internal configuration node for common cpufreq on Samsung SoC
config CPU_FREQ_S3C24XX
bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
depends on ARCH_S3C24XX && CPU_FREQ
select CPU_FREQ_S3C
help
This enables the CPUfreq driver for the Samsung S3C24XX family
of CPUs.
For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N.
config CPU_FREQ_S3C24XX_PLL
bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
depends on CPU_FREQ_S3C24XX
help
Compile in support for changing the PLL frequency from the
S3C24XX series CPUfreq driver. The PLL takes time to settle
after a frequency change, so by default it is not enabled.
This also means that the PLL tables for the selected CPU(s) will
be built which may increase the size of the kernel image.
config CPU_FREQ_S3C24XX_DEBUG
bool "Debug CPUfreq Samsung driver core"
depends on CPU_FREQ_S3C24XX
help
Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
config CPU_FREQ_S3C24XX_IODEBUG
bool "Debug CPUfreq Samsung driver IO timing"
depends on CPU_FREQ_S3C24XX
help
Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
config CPU_FREQ_S3C24XX_DEBUGFS
bool "Export debugfs for CPUFreq"
depends on CPU_FREQ_S3C24XX && DEBUG_FS
help
Export status information via debugfs.
endif
source "drivers/cpuidle/Kconfig"

View file

@ -360,6 +360,11 @@ ab8500 {
interrupt-controller;
#interrupt-cells = <2>;
ab8500_gpio: ab8500-gpio {
gpio-controller;
#gpio-cells = <2>;
};
ab8500-rtc {
compatible = "stericsson,ab8500-rtc";
interrupts = <17 IRQ_TYPE_LEVEL_HIGH

View file

@ -19,7 +19,7 @@
* published by the Free Software Foundation.
*/
/include/ "skeleton.dtsi"
#include "skeleton.dtsi"
/ {
interrupt-parent = <&gic>;

View file

@ -15,7 +15,7 @@
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
#include "exynos4210.dtsi"
/ {
model = "Insignal Origen evaluation board based on Exynos4210";

View file

@ -15,7 +15,7 @@
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
#include "exynos4210.dtsi"
/ {
model = "Samsung smdkv310 evaluation board based on Exynos4210";

View file

@ -13,7 +13,7 @@
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
#include "exynos4210.dtsi"
/ {
model = "Samsung Trats based on Exynos4210";

View file

@ -13,7 +13,7 @@
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
#include "exynos4210.dtsi"
/ {
model = "Samsung Universal C210 based on Exynos4210 rev0";

View file

@ -19,8 +19,8 @@
* published by the Free Software Foundation.
*/
/include/ "exynos4.dtsi"
/include/ "exynos4210-pinctrl.dtsi"
#include "exynos4.dtsi"
#include "exynos4210-pinctrl.dtsi"
/ {
compatible = "samsung,exynos4210";

View file

@ -17,7 +17,7 @@
* published by the Free Software Foundation.
*/
/include/ "exynos4x12.dtsi"
#include "exynos4x12.dtsi"
/ {
compatible = "samsung,exynos4212";

View file

@ -12,7 +12,7 @@
*/
/dts-v1/;
/include/ "exynos4412.dtsi"
#include "exynos4412.dtsi"
/ {
model = "Hardkernel ODROID-X board based on Exynos4412";

View file

@ -13,7 +13,7 @@
*/
/dts-v1/;
/include/ "exynos4412.dtsi"
#include "exynos4412.dtsi"
/ {
model = "Insignal Origen evaluation board based on Exynos4412";

View file

@ -13,7 +13,7 @@
*/
/dts-v1/;
/include/ "exynos4412.dtsi"
#include "exynos4412.dtsi"
/ {
model = "Samsung SMDK evaluation board based on Exynos4412";

View file

@ -17,7 +17,7 @@
* published by the Free Software Foundation.
*/
/include/ "exynos4x12.dtsi"
#include "exynos4x12.dtsi"
/ {
compatible = "samsung,exynos4412";

View file

@ -17,8 +17,8 @@
* published by the Free Software Foundation.
*/
/include/ "exynos4.dtsi"
/include/ "exynos4x12-pinctrl.dtsi"
#include "exynos4.dtsi"
#include "exynos4x12-pinctrl.dtsi"
/ {
aliases {

View file

@ -10,7 +10,7 @@
*/
/dts-v1/;
/include/ "exynos5250.dtsi"
#include "exynos5250.dtsi"
/ {
model = "Insignal Arndale evaluation board based on EXYNOS5250";

View file

@ -10,7 +10,7 @@
*/
/dts-v1/;
/include/ "exynos5250.dtsi"
#include "exynos5250.dtsi"
/ {
model = "SAMSUNG SMDK5250 board based on EXYNOS5250";

View file

@ -9,8 +9,8 @@
*/
/dts-v1/;
/include/ "exynos5250.dtsi"
/include/ "cros5250-common.dtsi"
#include "exynos5250.dtsi"
#include "cros5250-common.dtsi"
/ {
model = "Google Snow";

View file

@ -17,8 +17,10 @@
* published by the Free Software Foundation.
*/
/include/ "skeleton.dtsi"
/include/ "exynos5250-pinctrl.dtsi"
#include "skeleton.dtsi"
#include "exynos5250-pinctrl.dtsi"
#include <dt-bindings/clk/exynos-audss-clk.h>
/ {
compatible = "samsung,exynos5250";
@ -72,6 +74,12 @@ clock: clock-controller@0x10010000 {
#clock-cells = <1>;
};
clock_audss: audss-clock-controller@3810000 {
compatible = "samsung,exynos5250-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
};
gic:interrupt-controller@10481000 {
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
#interrupt-cells = <3>;
@ -451,6 +459,10 @@ i2s0: i2s@03830000 {
&pdma0 9
&pdma0 8>;
dma-names = "tx", "rx", "tx-sec";
clocks = <&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_SCLK_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
samsung,supports-6ch;
samsung,supports-rstclr;
samsung,supports-secdai;
@ -465,6 +477,8 @@ i2s1: i2s@12D60000 {
dmas = <&pdma1 12
&pdma1 11>;
dma-names = "tx", "rx";
clocks = <&clock 307>, <&clock 157>;
clock-names = "iis", "i2s_opclk0";
pinctrl-names = "default";
pinctrl-0 = <&i2s1_bus>;
};
@ -475,6 +489,8 @@ i2s2: i2s@12D70000 {
dmas = <&pdma0 12
&pdma0 11>;
dma-names = "tx", "rx";
clocks = <&clock 308>, <&clock 158>;
clock-names = "iis", "i2s_opclk0";
pinctrl-names = "default";
pinctrl-0 = <&i2s2_bus>;
};

View file

@ -10,7 +10,7 @@
*/
/dts-v1/;
/include/ "exynos5440.dtsi"
#include "exynos5440.dtsi"
/ {
model = "SAMSUNG SD5v1 board based on EXYNOS5440";

View file

@ -10,7 +10,7 @@
*/
/dts-v1/;
/include/ "exynos5440.dtsi"
#include "exynos5440.dtsi"
/ {
model = "SAMSUNG SSDK5440 board based on EXYNOS5440";

View file

@ -9,7 +9,7 @@
* published by the Free Software Foundation.
*/
/include/ "skeleton.dtsi"
#include "skeleton.dtsi"
/ {
compatible = "samsung,exynos5440";

View file

@ -106,7 +106,6 @@ nand@1,0 {
nand-bus-width = <8>;
ti,nand-ecc-opt = "sw";
gpmc,device-nand;
gpmc,cs-on-ns = <0>;
gpmc,cs-rd-off-ns = <36>;
gpmc,cs-wr-off-ns = <36>;

View file

@ -9,7 +9,7 @@
*/
/dts-v1/;
/include/ "s3c2416.dtsi"
#include "s3c2416.dtsi"
/ {
model = "SMDK2416";

View file

@ -8,8 +8,8 @@
* published by the Free Software Foundation.
*/
/include/ "s3c24xx.dtsi"
/include/ "s3c2416-pinctrl.dtsi"
#include "s3c24xx.dtsi"
#include "s3c2416-pinctrl.dtsi"
/ {
model = "Samsung S3C2416 SoC";

View file

@ -8,7 +8,7 @@
* published by the Free Software Foundation.
*/
/include/ "skeleton.dtsi"
#include "skeleton.dtsi"
/ {
compatible = "samsung,s3c24xx";

View file

@ -22,12 +22,13 @@ memory {
en_3v3_reg: en_3v3 {
compatible = "regulator-fixed";
regulator-name = "en-3v3-fixed-supply";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpios = <&gpio0 26 0x4>; // 26
startup-delay-us = <5000>;
enable-active-high;
regulator-name = "en-3v3-fixed-supply";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
/* AB8500 GPIOs start from 1 - offset 25 is GPIO26. */
gpio = <&ab8500_gpio 25 0x4>;
startup-delay-us = <5000>;
enable-active-high;
};
gpio_keys {

View file

@ -26,7 +26,8 @@ CONFIG_ARCH_OMAP=y
CONFIG_ARCH_OMAP1=y
CONFIG_OMAP_RESET_CLOCKS=y
# CONFIG_OMAP_MUX is not set
CONFIG_OMAP_MBOX_FWK=y
CONFIG_MAILBOX=y
CONFIG_OMAP1_MBOX=y
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_DM_TIMER=y
CONFIG_ARCH_OMAP730=y

View file

@ -19,10 +19,6 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
# DSP
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
obj-y += $(i2c-omap-m) $(i2c-omap-y)

View file

@ -212,9 +212,6 @@ obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o
obj-$(CONFIG_OMAP3_EMU) += emu.o
obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
obj-y += $(iommu-m) $(iommu-y)

View file

@ -112,6 +112,9 @@ struct gpmc_timings nand_default_timings[1] = {
.cs_rd_off = 36,
.cs_wr_off = 36,
.we_on = 6,
.oe_on = 6,
.adv_on = 6,
.adv_rd_off = 24,
.adv_wr_off = 36,

View file

@ -21,6 +21,7 @@
#include <linux/pinctrl/machine.h>
#include <linux/platform_data/omap4-keypad.h>
#include <linux/wl12xx.h>
#include <linux/platform_data/mailbox-omap.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@ -283,25 +284,31 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
return 0;
}
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
static inline void __init omap_init_mbox(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
struct omap_mbox_pdata *pdata;
oh = omap_hwmod_lookup("mailbox");
if (!oh) {
pr_err("%s: unable to find hwmod\n", __func__);
return;
}
if (!oh->dev_attr) {
pr_err("%s: hwmod doesn't have valid attrs\n", __func__);
return;
}
pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0);
pdata = (struct omap_mbox_pdata *)oh->dev_attr;
pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata));
WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
__func__, PTR_ERR(pdev));
}
#else
static inline void omap_init_mbox(void) { }
#endif /* CONFIG_OMAP_MBOX_FWK */
#endif /* CONFIG_OMAP2PLUS_MBOX */
static inline void omap_init_sti(void) {}

View file

@ -43,44 +43,6 @@ static struct platform_device gpmc_nand_device = {
.resource = gpmc_nand_resource,
};
static int omap2_nand_gpmc_retime(
struct omap_nand_platform_data *gpmc_nand_data,
struct gpmc_timings *gpmc_t)
{
struct gpmc_timings t;
int err;
memset(&t, 0, sizeof(t));
t.sync_clk = gpmc_t->sync_clk;
t.cs_on = gpmc_t->cs_on;
t.adv_on = gpmc_t->adv_on;
/* Read */
t.adv_rd_off = gpmc_t->adv_rd_off;
t.oe_on = t.adv_on;
t.access = gpmc_t->access;
t.oe_off = gpmc_t->oe_off;
t.cs_rd_off = gpmc_t->cs_rd_off;
t.rd_cycle = gpmc_t->rd_cycle;
/* Write */
t.adv_wr_off = gpmc_t->adv_wr_off;
t.we_on = t.oe_on;
if (cpu_is_omap34xx()) {
t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
t.wr_access = gpmc_t->wr_access;
}
t.we_off = gpmc_t->we_off;
t.cs_wr_off = gpmc_t->cs_wr_off;
t.wr_cycle = gpmc_t->wr_cycle;
err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
if (err)
return err;
return 0;
}
static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
{
/* support only OMAP3 class */
@ -131,7 +93,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
if (gpmc_t) {
err = omap2_nand_gpmc_retime(gpmc_nand_data, gpmc_t);
err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
if (err < 0) {
dev_err(dev, "Unable to set gpmc timings: %d\n", err);
return err;
@ -140,8 +102,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
if (gpmc_nand_data->of_node) {
gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
} else {
s.device_nand = true;
/* Enable RD PIN Monitoring Reg */
if (gpmc_nand_data->dev_ready) {
s.wait_on_read = true;
@ -149,6 +109,8 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
}
}
s.device_nand = true;
if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
s.device_width = GPMC_DEVWIDTH_16BIT;
else

View file

@ -30,6 +30,7 @@
#include <linux/of_mtd.h>
#include <linux/of_device.h>
#include <linux/mtd/nand.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/mtd-nand-omap2.h>
@ -155,6 +156,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
/* Define chip-selects as reserved by default until probe completes */
static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
static unsigned int gpmc_cs_num = GPMC_CS_NUM;
static unsigned int gpmc_nr_waitpins;
static struct device *gpmc_dev;
static int gpmc_irq;
@ -521,8 +523,10 @@ static int gpmc_cs_remap(int cs, u32 base)
int ret;
u32 old_base, size;
if (cs > GPMC_CS_NUM)
if (cs > gpmc_cs_num) {
pr_err("%s: requested chip-select is disabled\n", __func__);
return -ENODEV;
}
gpmc_cs_get_memconf(cs, &old_base, &size);
if (base == old_base)
return 0;
@ -545,9 +549,10 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
struct resource *res = &gpmc_cs_mem[cs];
int r = -1;
if (cs > GPMC_CS_NUM)
if (cs > gpmc_cs_num) {
pr_err("%s: requested chip-select is disabled\n", __func__);
return -ENODEV;
}
size = gpmc_mem_align(size);
if (size > (1 << GPMC_SECTION_SHIFT))
return -ENOMEM;
@ -582,7 +587,7 @@ EXPORT_SYMBOL(gpmc_cs_request);
void gpmc_cs_free(int cs)
{
spin_lock(&gpmc_mem_lock);
if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) {
if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
BUG();
spin_unlock(&gpmc_mem_lock);
@ -777,7 +782,7 @@ static void gpmc_mem_exit(void)
{
int cs;
for (cs = 0; cs < GPMC_CS_NUM; cs++) {
for (cs = 0; cs < gpmc_cs_num; cs++) {
if (!gpmc_cs_mem_enabled(cs))
continue;
gpmc_cs_delete_mem(cs);
@ -798,7 +803,7 @@ static void gpmc_mem_init(void)
gpmc_mem_root.end = GPMC_MEM_END;
/* Reserve all regions that has been set up by bootloader */
for (cs = 0; cs < GPMC_CS_NUM; cs++) {
for (cs = 0; cs < gpmc_cs_num; cs++) {
u32 base, size;
if (!gpmc_cs_mem_enabled(cs))
@ -1245,7 +1250,6 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
p->sync_read = of_property_read_bool(np, "gpmc,sync-read");
p->sync_write = of_property_read_bool(np, "gpmc,sync-write");
p->device_nand = of_property_read_bool(np, "gpmc,device-nand");
of_property_read_u32(np, "gpmc,device-width", &p->device_width);
of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
@ -1345,6 +1349,13 @@ static const char * const nand_ecc_opts[] = {
[OMAP_ECC_BCH8_CODE_HW] = "bch8",
};
static const char * const nand_xfer_types[] = {
[NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
[NAND_OMAP_POLLED] = "polled",
[NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
[NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
};
static int gpmc_probe_nand_child(struct platform_device *pdev,
struct device_node *child)
{
@ -1374,6 +1385,13 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
break;
}
if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
if (!strcasecmp(s, nand_xfer_types[val])) {
gpmc_nand_data->xfer_type = val;
break;
}
val = of_get_nand_bus_width(child);
if (val == 16)
gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
@ -1513,6 +1531,20 @@ static int gpmc_probe_dt(struct platform_device *pdev)
if (!of_id)
return 0;
ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs",
&gpmc_cs_num);
if (ret < 0) {
pr_err("%s: number of chip-selects not defined\n", __func__);
return ret;
} else if (gpmc_cs_num < 1) {
pr_err("%s: all chip-selects are disabled\n", __func__);
return -EINVAL;
} else if (gpmc_cs_num > GPMC_CS_NUM) {
pr_err("%s: number of supported chip-selects cannot be > %d\n",
__func__, GPMC_CS_NUM);
return -EINVAL;
}
ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
&gpmc_nr_waitpins);
if (ret < 0) {
@ -1577,7 +1609,8 @@ static int gpmc_probe(struct platform_device *pdev)
return PTR_ERR(gpmc_l3_clk);
}
clk_prepare_enable(gpmc_l3_clk);
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
gpmc_dev = &pdev->dev;
@ -1610,12 +1643,14 @@ static int gpmc_probe(struct platform_device *pdev)
/* Now the GPMC is initialised, unreserve the chip-selects */
gpmc_cs_map = 0;
if (!pdev->dev.of_node)
if (!pdev->dev.of_node) {
gpmc_cs_num = GPMC_CS_NUM;
gpmc_nr_waitpins = GPMC_NR_WAITPINS;
}
rc = gpmc_probe_dt(pdev);
if (rc < 0) {
clk_disable_unprepare(gpmc_l3_clk);
pm_runtime_put_sync(&pdev->dev);
clk_put(gpmc_l3_clk);
dev_err(gpmc_dev, "failed to probe DT parameters\n");
return rc;
@ -1628,10 +1663,30 @@ static int gpmc_remove(struct platform_device *pdev)
{
gpmc_free_irq();
gpmc_mem_exit();
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
gpmc_dev = NULL;
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int gpmc_suspend(struct device *dev)
{
omap3_gpmc_save_context();
pm_runtime_put_sync(dev);
return 0;
}
static int gpmc_resume(struct device *dev)
{
pm_runtime_get_sync(dev);
omap3_gpmc_restore_context();
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume);
static struct platform_driver gpmc_driver = {
.probe = gpmc_probe,
.remove = gpmc_remove,
@ -1639,6 +1694,7 @@ static struct platform_driver gpmc_driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(gpmc_dt_ids),
.pm = &gpmc_pm_ops,
},
};
@ -1701,7 +1757,6 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev)
return IRQ_HANDLED;
}
#ifdef CONFIG_ARCH_OMAP3
static struct omap3_gpmc_regs gpmc_context;
void omap3_gpmc_save_context(void)
@ -1715,7 +1770,7 @@ void omap3_gpmc_save_context(void)
gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
for (i = 0; i < GPMC_CS_NUM; i++) {
for (i = 0; i < gpmc_cs_num; i++) {
gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
if (gpmc_context.cs_context[i].is_valid) {
gpmc_context.cs_context[i].config1 =
@ -1747,7 +1802,7 @@ void omap3_gpmc_restore_context(void)
gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
for (i = 0; i < GPMC_CS_NUM; i++) {
for (i = 0; i < gpmc_cs_num; i++) {
if (gpmc_context.cs_context[i].is_valid) {
gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
gpmc_context.cs_context[i].config1);
@ -1766,4 +1821,3 @@ void omap3_gpmc_restore_context(void)
}
}
}
#endif /* CONFIG_ARCH_OMAP3 */

View file

@ -16,6 +16,7 @@
#include <linux/i2c-omap.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/omap-dma.h>
#include <linux/platform_data/mailbox-omap.h>
#include <plat/dmtimer.h>
#include "omap_hwmod.h"
@ -166,6 +167,18 @@ static struct omap_hwmod omap2420_dma_system_hwmod = {
};
/* mailbox */
static struct omap_mbox_dev_info omap2420_mailbox_info[] = {
{ .name = "dsp", .tx_id = 0, .rx_id = 1, .irq_id = 0, .usr_id = 0 },
{ .name = "iva", .tx_id = 2, .rx_id = 3, .irq_id = 1, .usr_id = 3 },
};
static struct omap_mbox_pdata omap2420_mailbox_attrs = {
.num_users = 4,
.num_fifos = 6,
.info_cnt = ARRAY_SIZE(omap2420_mailbox_info),
.info = omap2420_mailbox_info,
};
static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = {
{ .name = "dsp", .irq = 26 + OMAP_INTC_START, },
{ .name = "iva", .irq = 34 + OMAP_INTC_START, },
@ -186,6 +199,7 @@ static struct omap_hwmod omap2420_mailbox_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
},
},
.dev_attr = &omap2420_mailbox_attrs,
};
/*

View file

@ -17,6 +17,7 @@
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/omap-dma.h>
#include <linux/platform_data/mailbox-omap.h>
#include <plat/dmtimer.h>
#include "omap_hwmod.h"
@ -170,6 +171,17 @@ static struct omap_hwmod omap2430_dma_system_hwmod = {
};
/* mailbox */
static struct omap_mbox_dev_info omap2430_mailbox_info[] = {
{ .name = "dsp", .tx_id = 0, .rx_id = 1 },
};
static struct omap_mbox_pdata omap2430_mailbox_attrs = {
.num_users = 4,
.num_fifos = 6,
.info_cnt = ARRAY_SIZE(omap2430_mailbox_info),
.info = omap2430_mailbox_info,
};
static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = {
{ .irq = 26 + OMAP_INTC_START, },
{ .irq = -1 },
@ -189,6 +201,7 @@ static struct omap_hwmod omap2430_mailbox_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
},
},
.dev_attr = &omap2430_mailbox_attrs,
};
/* mcspi3 */

View file

@ -25,6 +25,7 @@
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/platform_data/iommu-omap.h>
#include <linux/platform_data/mailbox-omap.h>
#include <plat/dmtimer.h>
#include "am35xx.h"
@ -1504,6 +1505,17 @@ static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = {
.sysc = &omap3xxx_mailbox_sysc,
};
static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = {
{ .name = "dsp", .tx_id = 0, .rx_id = 1 },
};
static struct omap_mbox_pdata omap3xxx_mailbox_attrs = {
.num_users = 2,
.num_fifos = 2,
.info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info),
.info = omap3xxx_mailbox_info,
};
static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = {
{ .irq = 26 + OMAP_INTC_START, },
{ .irq = -1 },
@ -1523,6 +1535,7 @@ static struct omap_hwmod omap3xxx_mailbox_hwmod = {
.idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT,
},
},
.dev_attr = &omap3xxx_mailbox_attrs,
};
/*

View file

@ -28,7 +28,7 @@ config CPU_S3C2410
select CPU_ARM920T
select CPU_LLSERIAL_S3C2410
select S3C2410_CLOCK
select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
select S3C2410_PM if PM
select SAMSUNG_HRT
select SAMSUNG_WDT_RESET
@ -206,27 +206,38 @@ config S3C24XX_GPIO_EXTRA128
Add an extra 128 gpio numbers to the available GPIO pool. This is
available for boards that need extra gpios for external devices.
config S3C24XX_PLL
bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
depends on ARM_S3C24XX
help
Compile in support for changing the PLL frequency from the
S3C24XX series CPUfreq driver. The PLL takes time to settle
after a frequency change, so by default it is not enabled.
This also means that the PLL tables for the selected CPU(s) will
be built which may increase the size of the kernel image.
# cpu frequency items common between s3c2410 and s3c2440/s3c2442
config S3C2410_IOTIMING
bool
depends on CPU_FREQ_S3C24XX
depends on ARM_S3C24XX_CPUFREQ
help
Internal node to select io timing code that is common to the s3c2410
and s3c2440/s3c2442 cpu frequency support.
config S3C2410_CPUFREQ_UTILS
bool
depends on CPU_FREQ_S3C24XX
help
Internal node to select timing code that is common to the s3c2410
and s3c2440/s3c244 cpu frequency support.
bool
depends on ARM_S3C24XX_CPUFREQ
help
Internal node to select timing code that is common to the s3c2410
and s3c2440/s3c244 cpu frequency support.
# cpu frequency support common to s3c2412, s3c2413 and s3c2442
config S3C2412_IOTIMING
bool
depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443)
depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
help
Intel node to select io timing code that is common to the s3c2412
and the s3c2443.
@ -235,16 +246,9 @@ config S3C2412_IOTIMING
if CPU_S3C2410
config S3C2410_CPUFREQ
bool
depends on CPU_FREQ_S3C24XX
select S3C2410_CPUFREQ_UTILS
help
CPU Frequency scaling support for S3C2410
config S3C2410_PLL
bool
depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL
depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
default y
help
Select the PLL table for the S3C2410
@ -280,7 +284,7 @@ config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
select ISA
select MACH_BAST_IDE
select S3C2410_IOTIMING if S3C2410_CPUFREQ
select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
select S3C24XX_DCLK
select S3C24XX_SIMTEC_NOR
select S3C24XX_SIMTEC_PM if PM
@ -387,14 +391,6 @@ config CPU_S3C2412_ONLY
!CPU_S3C2442 && !CPU_S3C2443
default y
config S3C2412_CPUFREQ
bool
depends on CPU_FREQ_S3C24XX
default y
select S3C2412_IOTIMING
help
CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
config S3C2412_DMA
bool
help
@ -508,14 +504,6 @@ endif # CPU_S3C2416
if CPU_S3C2440
config S3C2440_CPUFREQ
bool "S3C2440/S3C2442 CPU Frequency scaling support"
depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
default y
select S3C2410_CPUFREQ_UTILS
help
CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
config S3C2440_DMA
bool
help
@ -535,15 +523,15 @@ config S3C2440_XTAL_16934400
config S3C2440_PLL_12000000
bool
depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
default y if CPU_FREQ_S3C24XX_PLL
depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
default y if S3C24XX_PLL
help
PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
config S3C2440_PLL_16934400
bool
depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
default y if CPU_FREQ_S3C24XX_PLL
depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
default y if S3C24XX_PLL
help
PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
@ -597,7 +585,7 @@ config MACH_NEXCODER_2440
config MACH_OSIRIS
bool "Simtec IM2440D20 (OSIRIS) module"
select S3C2410_IOTIMING if S3C2440_CPUFREQ
select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
select S3C2440_XTAL_12000000
select S3C24XX_DCLK
select S3C24XX_GPIO_EXTRA128
@ -669,7 +657,7 @@ config MACH_RX1950
bool "HP iPAQ rx1950"
select I2C
select PM_H1940 if PM
select S3C2410_IOTIMING if S3C2440_CPUFREQ
select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
select S3C2440_XTAL_16934400
select S3C24XX_DCLK
select S3C24XX_PWM

View file

@ -17,13 +17,11 @@ obj- :=
obj-y += common.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_S3C2410_CPUFREQ) += cpufreq-s3c2410.o
obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
obj-$(CONFIG_CPU_S3C2412) += s3c2412.o clock-s3c2412.o
obj-$(CONFIG_S3C2412_CPUFREQ) += cpufreq-s3c2412.o
obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o
obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
@ -34,7 +32,6 @@ obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o clock-s3c244x.o
obj-$(CONFIG_S3C2440_CPUFREQ) += cpufreq-s3c2440.o
obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
@ -59,9 +56,6 @@ obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o
obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o
obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpufreq.o
obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpufreq-debugfs.o
#
# machine support
# following is ordered alphabetically by option text.

View file

@ -31,7 +31,7 @@
#include <plat/cpu-freq-core.h>
#include <plat/clock.h>
#include "s3c2412.h"
#include <mach/s3c2412.h>
#define print_ns(x) ((x) / 10), ((x) % 10)

View file

@ -21,28 +21,14 @@
static struct stedma40_chan_cfg msp0_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
/* data_width is set during configuration */
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
};
static struct stedma40_chan_cfg msp0_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_DST_MEMORY,
.dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
/* data_width is set during configuration */
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
};
struct msp_i2s_platform_data msp0_platform_data = {
@ -53,28 +39,14 @@ struct msp_i2s_platform_data msp0_platform_data = {
static struct stedma40_chan_cfg msp1_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
/* data_width is set during configuration */
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV30_MSP3,
};
static struct stedma40_chan_cfg msp1_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_DST_MEMORY,
.dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
/* data_width is set during configuration */
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV30_MSP1,
};
struct msp_i2s_platform_data msp1_platform_data = {
@ -85,32 +57,16 @@ struct msp_i2s_platform_data msp1_platform_data = {
static struct stedma40_chan_cfg msp2_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
/* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
.src_info.psize = STEDMA40_PSIZE_LOG_1,
.dst_info.psize = STEDMA40_PSIZE_LOG_1,
/* data_width is set during configuration */
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV14_MSP2,
};
static struct stedma40_chan_cfg msp2_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_DST_MEMORY,
.dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV14_MSP2,
.use_fixed_channel = true,
.phy_channel = 1,
/* data_width is set during configuration */
};
static struct platform_device *db8500_add_msp_i2s(struct device *parent,

View file

@ -34,20 +34,14 @@
#ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV29_SD_MM0,
};
static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV29_SD_MM0,
};
#endif
@ -89,20 +83,14 @@ void mop500_sdi_tc35892_init(struct device *parent)
#ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV32_SD_MM1,
};
static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV32_SD_MM1,
};
#endif
@ -127,20 +115,14 @@ struct mmci_platform_data mop500_sdi1_data = {
#ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV28_SD_MM2_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV28_SD_MM2,
};
static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV28_SD_MM2,
};
#endif
@ -169,20 +151,14 @@ struct mmci_platform_data mop500_sdi2_data = {
#ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV42_SD_MM4_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV42_SD_MM4,
};
static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV42_SD_MM4,
};
#endif

View file

@ -413,47 +413,23 @@ static void mop500_prox_deactivate(struct device *dev)
regulator_put(prox_regulator);
}
void mop500_snowball_ethernet_clock_enable(void)
{
struct clk *clk;
clk = clk_get_sys("fsmc", NULL);
if (!IS_ERR(clk))
clk_prepare_enable(clk);
}
static struct cryp_platform_data u8500_cryp1_platform_data = {
.mem_to_engine = {
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV48_CAC1_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV48_CAC1,
.mode = STEDMA40_MODE_LOGICAL,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
},
.engine_to_mem = {
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV48_CAC1_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV48_CAC1,
.mode = STEDMA40_MODE_LOGICAL,
.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
}
};
static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = {
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV50_HAC1_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV50_HAC1_TX,
.mode = STEDMA40_MODE_LOGICAL,
.src_info.psize = STEDMA40_PSIZE_LOG_16,
.dst_info.psize = STEDMA40_PSIZE_LOG_16,
};
static struct hash_platform_data u8500_hash1_platform_data = {
@ -470,20 +446,14 @@ static struct platform_device *mop500_platform_devs[] __initdata = {
#ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV8_SSP0_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV8_SSP0,
};
static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV8_SSP0_TX,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV8_SSP0,
};
#endif
@ -511,56 +481,38 @@ static void __init mop500_spi_init(struct device *parent)
#ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV13_UART0_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV13_UART0,
};
static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV13_UART0_TX,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV13_UART0,
};
static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV12_UART1_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV12_UART1,
};
static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV12_UART1_TX,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV12_UART1,
};
static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB8500_DMA_DEV11_UART2_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV11_UART2,
};
static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
.dst_dev_type = DB8500_DMA_DEV11_UART2_TX,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV11_UART2,
};
#endif
@ -674,7 +626,7 @@ static void __init snowball_init_machine(void)
mop500_audio_init(parent);
mop500_uart_init(parent);
mop500_snowball_ethernet_clock_enable();
u8500_cryp1_hash1_init(parent);
/* This board has full regulator constraints */
regulator_has_full_constraints();

View file

@ -93,6 +93,7 @@ extern struct amba_pl011_data uart0_plat;
extern struct amba_pl011_data uart1_plat;
extern struct amba_pl011_data uart2_plat;
extern struct pl022_ssp_controller ssp0_plat;
extern struct stedma40_platform_data dma40_plat_data;
extern void mop500_sdi_init(struct device *parent);
extern void snowball_sdi_init(struct device *parent);
@ -104,7 +105,6 @@ void __init mop500_pinmaps_init(void);
void __init snowball_pinmaps_init(void);
void __init hrefv60_pinmaps_init(void);
void mop500_audio_init(struct device *parent);
void mop500_snowball_ethernet_clock_enable(void);
int __init mop500_uib_init(void);
void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,

View file

@ -162,26 +162,15 @@ static void __init db8500_add_gpios(struct device *parent)
dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE);
}
static int usb_db8500_rx_dma_cfg[] = {
DB8500_DMA_DEV38_USB_OTG_IEP_1_9,
DB8500_DMA_DEV37_USB_OTG_IEP_2_10,
DB8500_DMA_DEV36_USB_OTG_IEP_3_11,
DB8500_DMA_DEV19_USB_OTG_IEP_4_12,
DB8500_DMA_DEV18_USB_OTG_IEP_5_13,
DB8500_DMA_DEV17_USB_OTG_IEP_6_14,
DB8500_DMA_DEV16_USB_OTG_IEP_7_15,
DB8500_DMA_DEV39_USB_OTG_IEP_8
};
static int usb_db8500_tx_dma_cfg[] = {
DB8500_DMA_DEV38_USB_OTG_OEP_1_9,
DB8500_DMA_DEV37_USB_OTG_OEP_2_10,
DB8500_DMA_DEV36_USB_OTG_OEP_3_11,
DB8500_DMA_DEV19_USB_OTG_OEP_4_12,
DB8500_DMA_DEV18_USB_OTG_OEP_5_13,
DB8500_DMA_DEV17_USB_OTG_OEP_6_14,
DB8500_DMA_DEV16_USB_OTG_OEP_7_15,
DB8500_DMA_DEV39_USB_OTG_OEP_8
static int usb_db8500_dma_cfg[] = {
DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9,
DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10,
DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11,
DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12,
DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13,
DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14,
DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15,
DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8
};
static const char *db8500_read_soc_id(void)
@ -215,7 +204,7 @@ struct device * __init u8500_init_devices(void)
db8500_add_rtc(parent);
db8500_add_gpios(parent);
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg);
for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
platform_devs[i]->dev.parent = parent;
@ -226,34 +215,13 @@ struct device * __init u8500_init_devices(void)
}
#ifdef CONFIG_MACH_UX500_DT
/* TODO: Once all pieces are DT:ed, remove completely. */
static struct device * __init u8500_of_init_devices(void)
{
struct device *parent = db8500_soc_device_init();
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
u8500_dma40_device.dev.parent = parent;
/*
* Devices to be DT:ed:
* u8500_dma40_device = todo
* db8500_pmu_device = done
* db8500_prcmu_device = done
*/
platform_device_register(&u8500_dma40_device);
return parent;
}
static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
/* Requires call-back bindings. */
OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
/* Requires DMA bindings. */
OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", NULL),
OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", NULL),
OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", NULL),
OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat),
OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", &mop500_sdi0_data),
OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", &mop500_sdi1_data),
@ -294,6 +262,8 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
"ux500-msp-i2s.2", &msp2_platform_data),
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
"ux500-msp-i2s.3", &msp3_platform_data),
/* Requires clock name bindings and channel address lookup table. */
OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL),
{},
};
@ -317,22 +287,18 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
static void __init u8500_init_machine(void)
{
struct device *parent = NULL;
struct device *parent = db8500_soc_device_init();
/* Pinmaps must be in place before devices register */
if (of_machine_is_compatible("st-ericsson,mop500"))
mop500_pinmaps_init();
else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
snowball_pinmaps_init();
mop500_snowball_ethernet_clock_enable();
} else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
hrefv60_pinmaps_init();
else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
/* TODO: Add pinmaps for ccu9540 board. */
/* TODO: Export SoC, USB, cpu-freq and DMA40 */
parent = u8500_of_init_devices();
/* automatically probe child nodes of dbx5x0 devices */
if (of_machine_is_compatible("st-ericsson,u8540"))
of_platform_populate(NULL, u8500_local_bus_nodes,

View file

@ -42,128 +42,7 @@ static struct resource dma40_resources[] = {
}
};
/* Default configuration for physcial memcpy */
struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
.mode = STEDMA40_MODE_PHYSICAL,
.dir = STEDMA40_MEM_TO_MEM,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.src_info.psize = STEDMA40_PSIZE_PHY_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.psize = STEDMA40_PSIZE_PHY_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
};
/* Default configuration for logical memcpy */
struct stedma40_chan_cfg dma40_memcpy_conf_log = {
.dir = STEDMA40_MEM_TO_MEM,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.src_info.psize = STEDMA40_PSIZE_LOG_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.psize = STEDMA40_PSIZE_LOG_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
};
/*
* Mapping between destination event lines and physical device address.
* The event line is tied to a device and therefore the address is constant.
* When the address comes from a primecell it will be configured in runtime
* and we set the address to -1 as a placeholder.
*/
static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = {
/* MUSB - these will be runtime-reconfigured */
[DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1,
[DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1,
[DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1,
[DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1,
[DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1,
[DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1,
[DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1,
[DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1,
/* PrimeCells - run-time configured */
[DB8500_DMA_DEV0_SPI0_TX] = -1,
[DB8500_DMA_DEV1_SD_MMC0_TX] = -1,
[DB8500_DMA_DEV2_SD_MMC1_TX] = -1,
[DB8500_DMA_DEV3_SD_MMC2_TX] = -1,
[DB8500_DMA_DEV8_SSP0_TX] = -1,
[DB8500_DMA_DEV9_SSP1_TX] = -1,
[DB8500_DMA_DEV11_UART2_TX] = -1,
[DB8500_DMA_DEV12_UART1_TX] = -1,
[DB8500_DMA_DEV13_UART0_TX] = -1,
[DB8500_DMA_DEV28_SD_MM2_TX] = -1,
[DB8500_DMA_DEV29_SD_MM0_TX] = -1,
[DB8500_DMA_DEV32_SD_MM1_TX] = -1,
[DB8500_DMA_DEV33_SPI2_TX] = -1,
[DB8500_DMA_DEV35_SPI1_TX] = -1,
[DB8500_DMA_DEV40_SPI3_TX] = -1,
[DB8500_DMA_DEV41_SD_MM3_TX] = -1,
[DB8500_DMA_DEV42_SD_MM4_TX] = -1,
[DB8500_DMA_DEV43_SD_MM5_TX] = -1,
[DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV48_CAC1_TX] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET,
[DB8500_DMA_DEV50_HAC1_TX] = U8500_HASH1_BASE + HASH1_TX_REG_OFFSET,
};
/* Mapping between source event lines and physical device address */
static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
/* MUSB - these will be runtime-reconfigured */
[DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1,
[DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1,
[DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1,
[DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1,
[DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1,
[DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1,
[DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1,
[DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1,
/* PrimeCells */
[DB8500_DMA_DEV0_SPI0_RX] = -1,
[DB8500_DMA_DEV1_SD_MMC0_RX] = -1,
[DB8500_DMA_DEV2_SD_MMC1_RX] = -1,
[DB8500_DMA_DEV3_SD_MMC2_RX] = -1,
[DB8500_DMA_DEV8_SSP0_RX] = -1,
[DB8500_DMA_DEV9_SSP1_RX] = -1,
[DB8500_DMA_DEV11_UART2_RX] = -1,
[DB8500_DMA_DEV12_UART1_RX] = -1,
[DB8500_DMA_DEV13_UART0_RX] = -1,
[DB8500_DMA_DEV28_SD_MM2_RX] = -1,
[DB8500_DMA_DEV29_SD_MM0_RX] = -1,
[DB8500_DMA_DEV32_SD_MM1_RX] = -1,
[DB8500_DMA_DEV33_SPI2_RX] = -1,
[DB8500_DMA_DEV35_SPI1_RX] = -1,
[DB8500_DMA_DEV40_SPI3_RX] = -1,
[DB8500_DMA_DEV41_SD_MM3_RX] = -1,
[DB8500_DMA_DEV42_SD_MM4_RX] = -1,
[DB8500_DMA_DEV43_SD_MM5_RX] = -1,
[DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
[DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET,
};
/* Reserved event lines for memcpy only */
static int dma40_memcpy_event[] = {
DB8500_DMA_MEMCPY_TX_0,
DB8500_DMA_MEMCPY_TX_1,
DB8500_DMA_MEMCPY_TX_2,
DB8500_DMA_MEMCPY_TX_3,
DB8500_DMA_MEMCPY_TX_4,
DB8500_DMA_MEMCPY_TX_5,
};
static struct stedma40_platform_data dma40_plat_data = {
.dev_len = DB8500_DMA_NR_DEV,
.dev_rx = dma40_rx_map,
.dev_tx = dma40_tx_map,
.memcpy = dma40_memcpy_event,
.memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
.memcpy_conf_phy = &dma40_memcpy_conf_phy,
.memcpy_conf_log = &dma40_memcpy_conf_log,
struct stedma40_platform_data dma40_plat_data = {
.disabled_channels = {-1},
};

View file

@ -12,133 +12,74 @@
#define DB8500_DMA_NR_DEV 64
enum dma_src_dev_type {
DB8500_DMA_DEV0_SPI0_RX = 0,
DB8500_DMA_DEV1_SD_MMC0_RX = 1,
DB8500_DMA_DEV2_SD_MMC1_RX = 2,
DB8500_DMA_DEV3_SD_MMC2_RX = 3,
DB8500_DMA_DEV4_I2C1_RX = 4,
DB8500_DMA_DEV5_I2C3_RX = 5,
DB8500_DMA_DEV6_I2C2_RX = 6,
DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */
DB8500_DMA_DEV8_SSP0_RX = 8,
DB8500_DMA_DEV9_SSP1_RX = 9,
DB8500_DMA_DEV10_MCDE_RX = 10,
DB8500_DMA_DEV11_UART2_RX = 11,
DB8500_DMA_DEV12_UART1_RX = 12,
DB8500_DMA_DEV13_UART0_RX = 13,
DB8500_DMA_DEV14_MSP2_RX = 14,
DB8500_DMA_DEV15_I2C0_RX = 15,
DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16,
DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17,
DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18,
DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19,
DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24,
DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25,
DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26,
DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27,
DB8500_DMA_DEV28_SD_MM2_RX = 28,
DB8500_DMA_DEV29_SD_MM0_RX = 29,
DB8500_DMA_DEV30_MSP1_RX = 30,
/*
* Unless otherwise specified, all channels numbers are used for
* TX & RX, and can be used for either source or destination
* channels.
*/
enum dma_dev_type {
DB8500_DMA_DEV0_SPI0 = 0,
DB8500_DMA_DEV1_SD_MMC0 = 1,
DB8500_DMA_DEV2_SD_MMC1 = 2,
DB8500_DMA_DEV3_SD_MMC2 = 3,
DB8500_DMA_DEV4_I2C1 = 4,
DB8500_DMA_DEV5_I2C3 = 5,
DB8500_DMA_DEV6_I2C2 = 6,
DB8500_DMA_DEV7_I2C4 = 7, /* Only on V1 and later */
DB8500_DMA_DEV8_SSP0 = 8,
DB8500_DMA_DEV9_SSP1 = 9,
DB8500_DMA_DEV10_MCDE_RX = 10, /* RX only */
DB8500_DMA_DEV11_UART2 = 11,
DB8500_DMA_DEV12_UART1 = 12,
DB8500_DMA_DEV13_UART0 = 13,
DB8500_DMA_DEV14_MSP2 = 14,
DB8500_DMA_DEV15_I2C0 = 15,
DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15 = 16,
DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14 = 17,
DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13 = 18,
DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12 = 19,
DB8500_DMA_DEV20_SLIM0_CH0_HSI_CH0 = 20,
DB8500_DMA_DEV21_SLIM0_CH1_HSI_CH1 = 21,
DB8500_DMA_DEV22_SLIM0_CH2_HSI_CH2 = 22,
DB8500_DMA_DEV23_SLIM0_CH3_HSI_CH3 = 23,
DB8500_DMA_DEV24_SXA0 = 24,
DB8500_DMA_DEV25_SXA1 = 25,
DB8500_DMA_DEV26_SXA2 = 26,
DB8500_DMA_DEV27_SXA3 = 27,
DB8500_DMA_DEV28_SD_MM2 = 28,
DB8500_DMA_DEV29_SD_MM0 = 29,
DB8500_DMA_DEV30_MSP1 = 30,
/* On DB8500v2, MSP3 RX replaces MSP1 RX */
DB8500_DMA_DEV30_MSP3_RX = 30,
DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31,
DB8500_DMA_DEV32_SD_MM1_RX = 32,
DB8500_DMA_DEV33_SPI2_RX = 33,
DB8500_DMA_DEV34_I2C3_RX2 = 34,
DB8500_DMA_DEV35_SPI1_RX = 35,
DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36,
DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37,
DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38,
DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39,
DB8500_DMA_DEV40_SPI3_RX = 40,
DB8500_DMA_DEV41_SD_MM3_RX = 41,
DB8500_DMA_DEV42_SD_MM4_RX = 42,
DB8500_DMA_DEV43_SD_MM5_RX = 43,
DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44,
DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45,
DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46,
DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47,
DB8500_DMA_DEV48_CAC1_RX = 48,
/* 49, 50 and 51 are not used */
DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52,
DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53,
DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54,
DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55,
/* 56, 57, 58, 59 and 60 are not used */
DB8500_DMA_DEV61_CAC0_RX = 61,
/* 62 and 63 are not used */
};
enum dma_dest_dev_type {
DB8500_DMA_DEV0_SPI0_TX = 0,
DB8500_DMA_DEV1_SD_MMC0_TX = 1,
DB8500_DMA_DEV2_SD_MMC1_TX = 2,
DB8500_DMA_DEV3_SD_MMC2_TX = 3,
DB8500_DMA_DEV4_I2C1_TX = 4,
DB8500_DMA_DEV5_I2C3_TX = 5,
DB8500_DMA_DEV6_I2C2_TX = 6,
DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */
DB8500_DMA_DEV8_SSP0_TX = 8,
DB8500_DMA_DEV9_SSP1_TX = 9,
/* 10 is not used*/
DB8500_DMA_DEV11_UART2_TX = 11,
DB8500_DMA_DEV12_UART1_TX = 12,
DB8500_DMA_DEV13_UART0_TX = 13,
DB8500_DMA_DEV14_MSP2_TX = 14,
DB8500_DMA_DEV15_I2C0_TX = 15,
DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16,
DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17,
DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18,
DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19,
DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24,
DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25,
DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26,
DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27,
DB8500_DMA_DEV28_SD_MM2_TX = 28,
DB8500_DMA_DEV29_SD_MM0_TX = 29,
DB8500_DMA_DEV30_MSP1_TX = 30,
DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31,
DB8500_DMA_DEV32_SD_MM1_TX = 32,
DB8500_DMA_DEV33_SPI2_TX = 33,
DB8500_DMA_DEV34_I2C3_TX2 = 34,
DB8500_DMA_DEV35_SPI1_TX = 35,
DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36,
DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37,
DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38,
DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39,
DB8500_DMA_DEV40_SPI3_TX = 40,
DB8500_DMA_DEV41_SD_MM3_TX = 41,
DB8500_DMA_DEV42_SD_MM4_TX = 42,
DB8500_DMA_DEV43_SD_MM5_TX = 43,
DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44,
DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45,
DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46,
DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47,
DB8500_DMA_DEV48_CAC1_TX = 48,
DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,
DB8500_DMA_DEV50_HAC1_TX = 50,
DB8500_DMA_MEMCPY_TX_0 = 51,
DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52,
DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53,
DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54,
DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55,
DB8500_DMA_MEMCPY_TX_1 = 56,
DB8500_DMA_MEMCPY_TX_2 = 57,
DB8500_DMA_MEMCPY_TX_3 = 58,
DB8500_DMA_MEMCPY_TX_4 = 59,
DB8500_DMA_MEMCPY_TX_5 = 60,
DB8500_DMA_DEV61_CAC0_TX = 61,
DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,
DB8500_DMA_DEV63_HAC0_TX = 63,
DB8500_DMA_DEV30_MSP3 = 30,
DB8500_DMA_DEV31_MSP0_SLIM0_CH0 = 31,
DB8500_DMA_DEV32_SD_MM1 = 32,
DB8500_DMA_DEV33_SPI2 = 33,
DB8500_DMA_DEV34_I2C3_RX2_TX2 = 34,
DB8500_DMA_DEV35_SPI1 = 35,
DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11 = 36,
DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10 = 37,
DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9 = 38,
DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 = 39,
DB8500_DMA_DEV40_SPI3 = 40,
DB8500_DMA_DEV41_SD_MM3 = 41,
DB8500_DMA_DEV42_SD_MM4 = 42,
DB8500_DMA_DEV43_SD_MM5 = 43,
DB8500_DMA_DEV44_SXA4 = 44,
DB8500_DMA_DEV45_SXA5 = 45,
DB8500_DMA_DEV46_SLIM0_CH8_SRC_SXA6 = 46,
DB8500_DMA_DEV47_SLIM0_CH9_SRC_SXA7 = 47,
DB8500_DMA_DEV48_CAC1 = 48,
DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, /* TX only */
DB8500_DMA_DEV50_HAC1_TX = 50, /* TX only */
DB8500_DMA_MEMCPY_TX_0 = 51, /* TX only */
DB8500_DMA_DEV52_SLIM0_CH4_HSI_CH4 = 52,
DB8500_DMA_DEV53_SLIM0_CH5_HSI_CH5 = 53,
DB8500_DMA_DEV54_SLIM0_CH6_HSI_CH6 = 54,
DB8500_DMA_DEV55_SLIM0_CH7_HSI_CH7 = 55,
/* 56 -> 60 are channels reserved for memcpy only */
DB8500_DMA_DEV61_CAC0 = 61,
DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, /* TX only */
DB8500_DMA_DEV63_HAC0_TX = 63, /* TX only */
};
#endif

View file

@ -14,25 +14,15 @@
#define MUSB_DMA40_RX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_PERIPH_TO_MEM, \
.dst_dev_type = STEDMA40_DEV_DST_MEMORY, \
.src_info.data_width = STEDMA40_WORD_WIDTH, \
.dst_info.data_width = STEDMA40_WORD_WIDTH, \
.src_info.psize = STEDMA40_PSIZE_LOG_16, \
.dst_info.psize = STEDMA40_PSIZE_LOG_16, \
.dir = DMA_DEV_TO_MEM, \
}
#define MUSB_DMA40_TX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_MEM_TO_PERIPH, \
.src_dev_type = STEDMA40_DEV_SRC_MEMORY, \
.src_info.data_width = STEDMA40_WORD_WIDTH, \
.dst_info.data_width = STEDMA40_WORD_WIDTH, \
.src_info.psize = STEDMA40_PSIZE_LOG_16, \
.dst_info.psize = STEDMA40_PSIZE_LOG_16, \
.dir = DMA_MEM_TO_DEV, \
}
static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS]
static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
= {
MUSB_DMA40_RX_CH,
MUSB_DMA40_RX_CH,
@ -44,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS]
MUSB_DMA40_RX_CH
};
static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS]
static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
= {
MUSB_DMA40_TX_CH,
MUSB_DMA40_TX_CH,
@ -56,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS]
MUSB_DMA40_TX_CH,
};
static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = {
static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
&musb_dma_rx_ch[0],
&musb_dma_rx_ch[1],
&musb_dma_rx_ch[2],
@ -67,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = {
&musb_dma_rx_ch[7]
};
static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = {
static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
&musb_dma_tx_ch[0],
&musb_dma_tx_ch[1],
&musb_dma_tx_ch[2],
@ -81,23 +71,11 @@ static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = {
static struct ux500_musb_board_data musb_board_data = {
.dma_rx_param_array = ux500_dma_rx_param_array,
.dma_tx_param_array = ux500_dma_tx_param_array,
.num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS,
.num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS,
.dma_filter = stedma40_filter,
};
static u64 ux500_musb_dmamask = DMA_BIT_MASK(32);
static struct musb_hdrc_config musb_hdrc_config = {
.multipoint = true,
.dyn_fifo = true,
.num_eps = 16,
.ram_bits = 16,
};
static struct musb_hdrc_platform_data musb_platform_data = {
.mode = MUSB_OTG,
.config = &musb_hdrc_config,
.board_data = &musb_board_data,
};
@ -118,27 +96,26 @@ struct platform_device ux500_musb_device = {
.id = 0,
.dev = {
.platform_data = &musb_platform_data,
.dma_mask = &ux500_musb_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
};
static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type)
static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
{
u32 idx;
for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++)
musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx];
for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
musb_dma_rx_ch[idx].dev_type = dev_type[idx];
}
static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
{
u32 idx;
for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++)
musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
musb_dma_tx_ch[idx].dev_type = dev_type[idx];
}
void ux500_add_usb(struct device *parent, resource_size_t base, int irq,

View file

@ -86,22 +86,6 @@ config OMAP_MUX_WARNINGS
to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect OMAP_MUX for your product.
config OMAP_MBOX_FWK
tristate "Mailbox framework support"
depends on ARCH_OMAP && !ARCH_MULTIPLATFORM
help
Say Y here if you want to use OMAP Mailbox framework support for
DSP, IVA1.0 and IVA2 in OMAP1/2/3.
config OMAP_MBOX_KFIFO_SIZE
int "Mailbox kfifo default buffer size (bytes)"
depends on OMAP_MBOX_FWK
default 256
help
Specify the default size of mailbox's kfifo buffers (bytes).
This can also be changed at runtime (via the mbox_kfifo_size
module parameter).
config OMAP_IOMMU_IVA2
bool

View file

@ -17,6 +17,3 @@ obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
obj-y += $(i2c-omap-m) $(i2c-omap-y)
# OMAP mailbox framework
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o

View file

@ -202,7 +202,7 @@ extern int s3c_plltab_register(struct cpufreq_frequency_table *plls,
extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
#define s3c_cpufreq_debugfs_call(x) x
#else
#define s3c_cpufreq_debugfs_call(x) NULL
@ -259,17 +259,17 @@ extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
#define s3c2412_iotiming_set NULL
#endif /* CONFIG_S3C2412_IOTIMING */
#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG
#define s3c_freq_dbg(x...) printk(KERN_INFO x)
#else
#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */
#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG
#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
#else
#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */
static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
int index, size_t table_size,

View file

@ -126,7 +126,7 @@ struct s3c_cpufreq_board {
};
/* Things depending on frequency scaling. */
#ifdef CONFIG_CPU_FREQ_S3C
#ifdef CONFIG_ARM_S3C_CPUFREQ
#define __init_or_cpufreq
#else
#define __init_or_cpufreq __init
@ -134,7 +134,7 @@ struct s3c_cpufreq_board {
/* Board functions */
#ifdef CONFIG_CPU_FREQ_S3C
#ifdef CONFIG_ARM_S3C_CPUFREQ
extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
#else
@ -142,4 +142,4 @@ static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
{
return 0;
}
#endif /* CONFIG_CPU_FREQ_S3C */
#endif /* CONFIG_ARM_S3C_CPUFREQ */

View file

@ -6,3 +6,4 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Author: Padmavathi Venna <padma.v@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.
*
* Common Clock Framework support for Audio Subsystem Clock Controller.
*/
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <dt-bindings/clk/exynos-audss-clk.h>
static DEFINE_SPINLOCK(lock);
static struct clk **clk_table;
static void __iomem *reg_base;
static struct clk_onecell_data clk_data;
#define ASS_CLK_SRC 0x0
#define ASS_CLK_DIV 0x4
#define ASS_CLK_GATE 0x8
static unsigned long reg_save[][2] = {
{ASS_CLK_SRC, 0},
{ASS_CLK_DIV, 0},
{ASS_CLK_GATE, 0},
};
/* list of all parent clock list */
static const char *mout_audss_p[] = { "fin_pll", "fout_epll" };
static const char *mout_i2s_p[] = { "mout_audss", "cdclk0", "sclk_audio0" };
#ifdef CONFIG_PM_SLEEP
static int exynos_audss_clk_suspend(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(reg_save); i++)
reg_save[i][1] = readl(reg_base + reg_save[i][0]);
return 0;
}
static void exynos_audss_clk_resume(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(reg_save); i++)
writel(reg_save[i][1], reg_base + reg_save[i][0]);
}
static struct syscore_ops exynos_audss_clk_syscore_ops = {
.suspend = exynos_audss_clk_suspend,
.resume = exynos_audss_clk_resume,
};
#endif /* CONFIG_PM_SLEEP */
/* register exynos_audss clocks */
void __init exynos_audss_clk_init(struct device_node *np)
{
reg_base = of_iomap(np, 0);
if (!reg_base) {
pr_err("%s: failed to map audss registers\n", __func__);
return;
}
clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
GFP_KERNEL);
if (!clk_table) {
pr_err("%s: could not allocate clk lookup table\n", __func__);
return;
}
clk_data.clks = clk_table;
clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
mout_audss_p, ARRAY_SIZE(mout_audss_p), 0,
reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
mout_i2s_p, ARRAY_SIZE(mout_i2s_p), 0,
reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
"mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
0, &lock);
clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL,
"dout_aud_bus", "dout_srp", 0,
reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s",
"mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
&lock);
clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk",
"dout_srp", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 0, 0, &lock);
clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus",
"dout_aud_bus", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 2, 0, &lock);
clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s",
"dout_i2s", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 3, 0, &lock);
clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus",
"sclk_pcm", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 4, 0, &lock);
clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm",
"div_pcm0", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 5, 0, &lock);
#ifdef CONFIG_PM_SLEEP
register_syscore_ops(&exynos_audss_clk_syscore_ops);
#endif
pr_info("Exynos: Audss: clock setup completed\n");
}
CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock",
exynos_audss_clk_init);
CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock",
exynos_audss_clk_init);

View file

@ -87,6 +87,7 @@ enum exynos5250_clks {
sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3,
sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm,
sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
div_i2s1, div_i2s2,
/* gate clocks */
gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
@ -291,8 +292,8 @@ struct samsung_div_clock exynos5250_div_clks[] __initdata = {
DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8),
DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4),
DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8),
DIV(none, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
DIV(none, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
DIV(div_i2s1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
DIV(div_i2s2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4),
DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"),
DIV_F(none, "div_mipi1_pre", "div_mipi1",

View file

@ -10,7 +10,7 @@
* DBx500-PRCMU Timer
* The PRCMU has 5 timers which are available in a always-on
* power domain. We use the Timer 4 for our always-on clock
* source on DB8500 and Timer 3 on DB5500.
* source on DB8500.
*/
#include <linux/clockchips.h>
#include <linux/clksrc-dbx500-prcmu.h>
@ -30,15 +30,14 @@
static void __iomem *clksrc_dbx500_timer_base;
static cycle_t clksrc_dbx500_prcmu_read(struct clocksource *cs)
static cycle_t notrace clksrc_dbx500_prcmu_read(struct clocksource *cs)
{
void __iomem *base = clksrc_dbx500_timer_base;
u32 count, count2;
do {
count = readl(clksrc_dbx500_timer_base +
PRCMU_TIMER_DOWNCOUNT);
count2 = readl(clksrc_dbx500_timer_base +
PRCMU_TIMER_DOWNCOUNT);
count = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
count2 = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
} while (count2 != count);
/* Negate because the timer is a decrementing counter */

View file

@ -96,6 +96,56 @@ config ARM_OMAP2PLUS_CPUFREQ
default ARCH_OMAP2PLUS
select CPU_FREQ_TABLE
config ARM_S3C_CPUFREQ
bool
help
Internal configuration node for common cpufreq on Samsung SoC
config ARM_S3C24XX_CPUFREQ
bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
depends on ARCH_S3C24XX
select ARM_S3C_CPUFREQ
help
This enables the CPUfreq driver for the Samsung S3C24XX family
of CPUs.
For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N.
config ARM_S3C24XX_CPUFREQ_DEBUG
bool "Debug CPUfreq Samsung driver core"
depends on ARM_S3C24XX_CPUFREQ
help
Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
config ARM_S3C24XX_CPUFREQ_IODEBUG
bool "Debug CPUfreq Samsung driver IO timing"
depends on ARM_S3C24XX_CPUFREQ
help
Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
config ARM_S3C24XX_CPUFREQ_DEBUGFS
bool "Export debugfs for CPUFreq"
depends on ARM_S3C24XX_CPUFREQ && DEBUG_FS
help
Export status information via debugfs.
config ARM_S3C2410_CPUFREQ
bool
depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2410
select S3C2410_CPUFREQ_UTILS
help
CPU Frequency scaling support for S3C2410
config ARM_S3C2412_CPUFREQ
bool
depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2412
default y
select S3C2412_IOTIMING
help
CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
config ARM_S3C2416_CPUFREQ
bool "S3C2416 CPU Frequency scaling support"
depends on CPU_S3C2416
@ -118,6 +168,14 @@ config ARM_S3C2416_CPUFREQ_VCORESCALE
If in doubt, say N.
config ARM_S3C2440_CPUFREQ
bool "S3C2440/S3C2442 CPU Frequency scaling support"
depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2440 || CPU_S3C2442)
select S3C2410_CPUFREQ_UTILS
default y
help
CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
config ARM_S3C64XX_CPUFREQ
bool "Samsung S3C64XX"
depends on CPU_S3C6410

View file

@ -65,7 +65,12 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_PXA25x) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA27x) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
obj-$(CONFIG_ARM_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o

View file

@ -25,13 +25,12 @@
#include <asm/mach/map.h>
#include <mach/regs-clock.h>
#include <mach/s3c2412.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/cpu-freq-core.h>
#include "s3c2412.h"
/* our clock resources. */
static struct clk *xtal;
static struct clk *fclk;

View file

@ -291,7 +291,7 @@ void cryp_save_device_context(struct cryp_device_data *device_data,
int cryp_mode)
{
enum cryp_algo_mode algomode;
struct cryp_register *src_reg = device_data->base;
struct cryp_register __iomem *src_reg = device_data->base;
struct cryp_config *config =
(struct cryp_config *)device_data->current_ctx;
@ -349,7 +349,7 @@ void cryp_save_device_context(struct cryp_device_data *device_data,
void cryp_restore_device_context(struct cryp_device_data *device_data,
struct cryp_device_context *ctx)
{
struct cryp_register *reg = device_data->base;
struct cryp_register __iomem *reg = device_data->base;
struct cryp_config *config =
(struct cryp_config *)device_data->current_ctx;

View file

@ -114,6 +114,9 @@ enum cryp_status_id {
};
/* Cryp DMA interface */
#define CRYP_DMA_TX_FIFO 0x08
#define CRYP_DMA_RX_FIFO 0x10
enum cryp_dma_req_type {
CRYP_DMA_DISABLE_BOTH,
CRYP_DMA_ENABLE_IN_DATA,
@ -217,7 +220,8 @@ struct cryp_dma {
/**
* struct cryp_device_data - structure for a cryp device.
* @base: Pointer to the hardware base address.
* @base: Pointer to virtual base address of the cryp device.
* @phybase: Pointer to physical memory location of the cryp device.
* @dev: Pointer to the devices dev structure.
* @clk: Pointer to the device's clock control.
* @pwr_regulator: Pointer to the device's power control.
@ -232,6 +236,7 @@ struct cryp_dma {
*/
struct cryp_device_data {
struct cryp_register __iomem *base;
phys_addr_t phybase;
struct device *dev;
struct clk *clk;
struct regulator *pwr_regulator;

View file

@ -475,6 +475,19 @@ static int cryp_get_device_data(struct cryp_ctx *ctx,
static void cryp_dma_setup_channel(struct cryp_device_data *device_data,
struct device *dev)
{
struct dma_slave_config mem2cryp = {
.direction = DMA_MEM_TO_DEV,
.dst_addr = device_data->phybase + CRYP_DMA_TX_FIFO,
.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
.dst_maxburst = 4,
};
struct dma_slave_config cryp2mem = {
.direction = DMA_DEV_TO_MEM,
.src_addr = device_data->phybase + CRYP_DMA_RX_FIFO,
.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
.src_maxburst = 4,
};
dma_cap_zero(device_data->dma.mask);
dma_cap_set(DMA_SLAVE, device_data->dma.mask);
@ -490,6 +503,9 @@ static void cryp_dma_setup_channel(struct cryp_device_data *device_data,
stedma40_filter,
device_data->dma.cfg_cryp2mem);
dmaengine_slave_config(device_data->dma.chan_mem2cryp, &mem2cryp);
dmaengine_slave_config(device_data->dma.chan_cryp2mem, &cryp2mem);
init_completion(&device_data->dma.cryp_dma_complete);
}
@ -537,10 +553,10 @@ static int cryp_set_dma_transfer(struct cryp_ctx *ctx,
dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
"(TO_DEVICE)", __func__);
desc = channel->device->device_prep_slave_sg(channel,
ctx->device->dma.sg_src,
ctx->device->dma.sg_src_len,
direction, DMA_CTRL_ACK, NULL);
desc = dmaengine_prep_slave_sg(channel,
ctx->device->dma.sg_src,
ctx->device->dma.sg_src_len,
direction, DMA_CTRL_ACK);
break;
case DMA_FROM_DEVICE:
@ -561,12 +577,12 @@ static int cryp_set_dma_transfer(struct cryp_ctx *ctx,
dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
"(FROM_DEVICE)", __func__);
desc = channel->device->device_prep_slave_sg(channel,
ctx->device->dma.sg_dst,
ctx->device->dma.sg_dst_len,
direction,
DMA_CTRL_ACK |
DMA_PREP_INTERRUPT, NULL);
desc = dmaengine_prep_slave_sg(channel,
ctx->device->dma.sg_dst,
ctx->device->dma.sg_dst_len,
direction,
DMA_CTRL_ACK |
DMA_PREP_INTERRUPT);
desc->callback = cryp_dma_out_callback;
desc->callback_param = ctx;
@ -578,7 +594,7 @@ static int cryp_set_dma_transfer(struct cryp_ctx *ctx,
return -EFAULT;
}
cookie = desc->tx_submit(desc);
cookie = dmaengine_submit(desc);
dma_async_issue_pending(channel);
return 0;
@ -591,12 +607,12 @@ static void cryp_dma_done(struct cryp_ctx *ctx)
dev_dbg(ctx->device->dev, "[%s]: ", __func__);
chan = ctx->device->dma.chan_mem2cryp;
chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_src,
ctx->device->dma.sg_src_len, DMA_TO_DEVICE);
chan = ctx->device->dma.chan_cryp2mem;
chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_dst,
ctx->device->dma.sg_dst_len, DMA_FROM_DEVICE);
}
@ -1431,6 +1447,7 @@ static int ux500_cryp_probe(struct platform_device *pdev)
goto out_kfree;
}
device_data->phybase = res->start;
device_data->base = ioremap(res->start, resource_size(res));
if (!device_data->base) {
dev_err(dev, "[%s]: ioremap failed!", __func__);
@ -1458,11 +1475,17 @@ static int ux500_cryp_probe(struct platform_device *pdev)
goto out_regulator;
}
ret = clk_prepare(device_data->clk);
if (ret) {
dev_err(dev, "[%s]: clk_prepare() failed!", __func__);
goto out_clk;
}
/* Enable device power (and clock) */
ret = cryp_enable_power(device_data->dev, device_data, false);
if (ret) {
dev_err(dev, "[%s]: cryp_enable_power() failed!", __func__);
goto out_clk;
goto out_clk_unprepare;
}
cryp_error = cryp_check(device_data);
@ -1518,11 +1541,16 @@ static int ux500_cryp_probe(struct platform_device *pdev)
goto out_power;
}
dev_info(dev, "successfully registered\n");
return 0;
out_power:
cryp_disable_power(device_data->dev, device_data, false);
out_clk_unprepare:
clk_unprepare(device_data->clk);
out_clk:
clk_put(device_data->clk);
@ -1593,6 +1621,7 @@ static int ux500_cryp_remove(struct platform_device *pdev)
dev_err(&pdev->dev, "[%s]: cryp_disable_power() failed",
__func__);
clk_unprepare(device_data->clk);
clk_put(device_data->clk);
regulator_put(device_data->pwr_regulator);

View file

@ -11,6 +11,7 @@
#include <linux/bitops.h>
#define HASH_BLOCK_SIZE 64
#define HASH_DMA_FIFO 4
#define HASH_DMA_ALIGN_SIZE 4
#define HASH_DMA_PERFORMANCE_MIN_SIZE 1024
#define HASH_BYTES_PER_WORD 4
@ -347,7 +348,8 @@ struct hash_req_ctx {
/**
* struct hash_device_data - structure for a hash device.
* @base: Pointer to the hardware base address.
* @base: Pointer to virtual base address of the hash device.
* @phybase: Pointer to physical memory location of the hash device.
* @list_node: For inclusion in klist.
* @dev: Pointer to the device dev structure.
* @ctx_lock: Spinlock for current_ctx.
@ -361,6 +363,7 @@ struct hash_req_ctx {
*/
struct hash_device_data {
struct hash_register __iomem *base;
phys_addr_t phybase;
struct klist_node list_node;
struct device *dev;
struct spinlock ctx_lock;

View file

@ -122,6 +122,13 @@ static void hash_dma_setup_channel(struct hash_device_data *device_data,
struct device *dev)
{
struct hash_platform_data *platform_data = dev->platform_data;
struct dma_slave_config conf = {
.direction = DMA_MEM_TO_DEV,
.dst_addr = device_data->phybase + HASH_DMA_FIFO,
.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
.dst_maxburst = 16,
};
dma_cap_zero(device_data->dma.mask);
dma_cap_set(DMA_SLAVE, device_data->dma.mask);
@ -131,6 +138,8 @@ static void hash_dma_setup_channel(struct hash_device_data *device_data,
platform_data->dma_filter,
device_data->dma.cfg_mem2hash);
dmaengine_slave_config(device_data->dma.chan_mem2hash, &conf);
init_completion(&device_data->dma.complete);
}
@ -171,9 +180,9 @@ static int hash_set_dma_transfer(struct hash_ctx *ctx, struct scatterlist *sg,
dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
"(TO_DEVICE)", __func__);
desc = channel->device->device_prep_slave_sg(channel,
desc = dmaengine_prep_slave_sg(channel,
ctx->device->dma.sg, ctx->device->dma.sg_len,
direction, DMA_CTRL_ACK | DMA_PREP_INTERRUPT, NULL);
direction, DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
if (!desc) {
dev_err(ctx->device->dev,
"[%s]: device_prep_slave_sg() failed!", __func__);
@ -183,7 +192,7 @@ static int hash_set_dma_transfer(struct hash_ctx *ctx, struct scatterlist *sg,
desc->callback = hash_dma_callback;
desc->callback_param = ctx;
cookie = desc->tx_submit(desc);
cookie = dmaengine_submit(desc);
dma_async_issue_pending(channel);
return 0;
@ -194,7 +203,7 @@ static void hash_dma_done(struct hash_ctx *ctx)
struct dma_chan *chan;
chan = ctx->device->dma.chan_mem2hash;
chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg,
ctx->device->dma.sg_len, DMA_TO_DEVICE);
@ -464,12 +473,12 @@ static void hash_hw_write_key(struct hash_device_data *device_data,
HASH_SET_DIN(&word, nwords);
}
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
HASH_SET_DCAL;
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
}
@ -652,7 +661,7 @@ static void hash_messagepad(struct hash_device_data *device_data,
if (index_bytes)
HASH_SET_DIN(message, nwords);
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
/* num_of_bytes == 0 => NBLW <- 0 (32 bits valid in DATAIN) */
@ -667,7 +676,7 @@ static void hash_messagepad(struct hash_device_data *device_data,
(int)(readl_relaxed(&device_data->base->str) &
HASH_STR_NBLW_MASK));
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
}
@ -767,7 +776,7 @@ void hash_begin(struct hash_device_data *device_data, struct hash_ctx *ctx)
/* HW and SW initializations */
/* Note: there is no need to initialize buffer and digest members */
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
/*
@ -783,8 +792,7 @@ void hash_begin(struct hash_device_data *device_data, struct hash_ctx *ctx)
HASH_CLEAR_BITS(&device_data->base->str, HASH_STR_NBLW_MASK);
}
int hash_process_data(
struct hash_device_data *device_data,
static int hash_process_data(struct hash_device_data *device_data,
struct hash_ctx *ctx, struct hash_req_ctx *req_ctx,
int msg_length, u8 *data_buffer, u8 *buffer, u8 *index)
{
@ -953,7 +961,7 @@ static int hash_dma_final(struct ahash_request *req)
wait_for_completion(&ctx->device->dma.complete);
hash_dma_done(ctx);
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
if (ctx->config.oper_mode == HASH_OPER_MODE_HMAC && ctx->key) {
@ -983,7 +991,7 @@ static int hash_dma_final(struct ahash_request *req)
* hash_hw_final - The final hash calculation function
* @req: The hash request for the job.
*/
int hash_hw_final(struct ahash_request *req)
static int hash_hw_final(struct ahash_request *req)
{
int ret = 0;
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@ -1051,7 +1059,7 @@ int hash_hw_final(struct ahash_request *req)
req_ctx->state.index);
} else {
HASH_SET_DCAL;
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
}
@ -1180,7 +1188,7 @@ int hash_resume_state(struct hash_device_data *device_data,
temp_cr = device_state->temp_cr;
writel_relaxed(temp_cr & HASH_CR_RESUME_MASK, &device_data->base->cr);
if (device_data->base->cr & HASH_CR_MODE_MASK)
if (readl(&device_data->base->cr) & HASH_CR_MODE_MASK)
hash_mode = HASH_OPER_MODE_HMAC;
else
hash_mode = HASH_OPER_MODE_HASH;
@ -1224,7 +1232,7 @@ int hash_save_state(struct hash_device_data *device_data,
* actually makes sure that there isn't any ongoing calculation in the
* hardware.
*/
while (device_data->base->str & HASH_STR_DCAL_MASK)
while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
cpu_relax();
temp_cr = readl_relaxed(&device_data->base->cr);
@ -1233,7 +1241,7 @@ int hash_save_state(struct hash_device_data *device_data,
device_state->din_reg = readl_relaxed(&device_data->base->din);
if (device_data->base->cr & HASH_CR_MODE_MASK)
if (readl(&device_data->base->cr) & HASH_CR_MODE_MASK)
hash_mode = HASH_OPER_MODE_HMAC;
else
hash_mode = HASH_OPER_MODE_HASH;
@ -1699,6 +1707,7 @@ static int ux500_hash_probe(struct platform_device *pdev)
goto out_kfree;
}
device_data->phybase = res->start;
device_data->base = ioremap(res->start, resource_size(res));
if (!device_data->base) {
dev_err(dev, "[%s] ioremap() failed!",
@ -1726,11 +1735,17 @@ static int ux500_hash_probe(struct platform_device *pdev)
goto out_regulator;
}
ret = clk_prepare(device_data->clk);
if (ret) {
dev_err(dev, "[%s] clk_prepare() failed!", __func__);
goto out_clk;
}
/* Enable device power (and clock) */
ret = hash_enable_power(device_data, false);
if (ret) {
dev_err(dev, "[%s]: hash_enable_power() failed!", __func__);
goto out_clk;
goto out_clk_unprepare;
}
ret = hash_check_hw(device_data);
@ -1756,12 +1771,15 @@ static int ux500_hash_probe(struct platform_device *pdev)
goto out_power;
}
dev_info(dev, "[%s] successfully probed\n", __func__);
dev_info(dev, "successfully registered\n");
return 0;
out_power:
hash_disable_power(device_data, false);
out_clk_unprepare:
clk_unprepare(device_data->clk);
out_clk:
clk_put(device_data->clk);
@ -1826,6 +1844,7 @@ static int ux500_hash_remove(struct platform_device *pdev)
dev_err(dev, "[%s]: hash_disable_power() failed",
__func__);
clk_unprepare(device_data->clk);
clk_put(device_data->clk);
regulator_put(device_data->regulator);

View file

@ -17,6 +17,8 @@
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/amba/bus.h>
#include <linux/regulator/consumer.h>
#include <linux/platform_data/dma-ste-dma40.h>
@ -45,15 +47,63 @@
#define D40_LCLA_LINK_PER_EVENT_GRP 128
#define D40_LCLA_END D40_LCLA_LINK_PER_EVENT_GRP
/* Max number of logical channels per physical channel */
#define D40_MAX_LOG_CHAN_PER_PHY 32
/* Attempts before giving up to trying to get pages that are aligned */
#define MAX_LCLA_ALLOC_ATTEMPTS 256
/* Bit markings for allocation map */
#define D40_ALLOC_FREE (1 << 31)
#define D40_ALLOC_PHY (1 << 30)
#define D40_ALLOC_FREE BIT(31)
#define D40_ALLOC_PHY BIT(30)
#define D40_ALLOC_LOG_FREE 0
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
#define D40_MEMCPY_MAX_CHANS 8
/* Reserved event lines for memcpy only. */
#define DB8500_DMA_MEMCPY_EV_0 51
#define DB8500_DMA_MEMCPY_EV_1 56
#define DB8500_DMA_MEMCPY_EV_2 57
#define DB8500_DMA_MEMCPY_EV_3 58
#define DB8500_DMA_MEMCPY_EV_4 59
#define DB8500_DMA_MEMCPY_EV_5 60
static int dma40_memcpy_channels[] = {
DB8500_DMA_MEMCPY_EV_0,
DB8500_DMA_MEMCPY_EV_1,
DB8500_DMA_MEMCPY_EV_2,
DB8500_DMA_MEMCPY_EV_3,
DB8500_DMA_MEMCPY_EV_4,
DB8500_DMA_MEMCPY_EV_5,
};
/* Default configuration for physcial memcpy */
static struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
.mode = STEDMA40_MODE_PHYSICAL,
.dir = DMA_MEM_TO_MEM,
.src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.src_info.psize = STEDMA40_PSIZE_PHY_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
.dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.dst_info.psize = STEDMA40_PSIZE_PHY_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
};
/* Default configuration for logical memcpy */
static struct stedma40_chan_cfg dma40_memcpy_conf_log = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = DMA_MEM_TO_MEM,
.src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.src_info.psize = STEDMA40_PSIZE_LOG_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
.dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.dst_info.psize = STEDMA40_PSIZE_LOG_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
};
/**
* enum 40_command - The different commands and/or statuses.
@ -171,6 +221,9 @@ static u32 d40_backup_regs_chan[] = {
D40_CHAN_REG_SDLNK,
};
#define BACKUP_REGS_SZ_MAX ((BACKUP_REGS_SZ_V4A > BACKUP_REGS_SZ_V4B) ? \
BACKUP_REGS_SZ_V4A : BACKUP_REGS_SZ_V4B)
/**
* struct d40_interrupt_lookup - lookup table for interrupt handler
*
@ -471,6 +524,8 @@ struct d40_gen_dmac {
* @phy_start: Physical memory start of the DMA registers.
* @phy_size: Size of the DMA register map.
* @irq: The IRQ number.
* @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem
* transfers).
* @num_phy_chans: The number of physical channels. Read from HW. This
* is the number of available channels for this driver, not counting "Secure
* mode" allocated physical channels.
@ -514,6 +569,7 @@ struct d40_base {
phys_addr_t phy_start;
resource_size_t phy_size;
int irq;
int num_memcpy_chans;
int num_phy_chans;
int num_log_chans;
struct device_dma_parameters dma_parms;
@ -534,7 +590,7 @@ struct d40_base {
resource_size_t lcpa_size;
struct kmem_cache *desc_slab;
u32 reg_val_backup[BACKUP_REGS_SZ];
u32 reg_val_backup_v4[MAX(BACKUP_REGS_SZ_V4A, BACKUP_REGS_SZ_V4B)];
u32 reg_val_backup_v4[BACKUP_REGS_SZ_MAX];
u32 *reg_val_backup_chan;
u16 gcc_pwr_off_mask;
bool initialized;
@ -792,7 +848,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
* that uses linked lists.
*/
if (!(chan->phy_chan->use_soft_lli &&
chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM))
chan->dma_cfg.dir == DMA_DEV_TO_MEM))
curr_lcla = d40_lcla_alloc_one(chan, desc);
first_lcla = curr_lcla;
@ -954,20 +1010,21 @@ static int d40_psize_2_burst_size(bool is_log, int psize)
/*
* The dma only supports transmitting packages up to
* STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of
* dma elements required to send the entire sg list
* STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes.
*
* Calculate the total number of dma elements required to send the entire sg list.
*/
static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2)
{
int dmalen;
u32 max_w = max(data_width1, data_width2);
u32 min_w = min(data_width1, data_width2);
u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w);
u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
if (seg_max > STEDMA40_MAX_SEG_SIZE)
seg_max -= (1 << max_w);
seg_max -= max_w;
if (!IS_ALIGNED(size, 1 << max_w))
if (!IS_ALIGNED(size, max_w))
return -EINVAL;
if (size <= seg_max)
@ -1257,21 +1314,17 @@ static void __d40_config_set_event(struct d40_chan *d40c,
static void d40_config_set_event(struct d40_chan *d40c,
enum d40_events event_type)
{
/* Enable event line connected to device (or memcpy) */
if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) ||
(d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) {
u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
/* Enable event line connected to device (or memcpy) */
if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) ||
(d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
__d40_config_set_event(d40c, event_type, event,
D40_CHAN_REG_SSLNK);
}
if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) {
u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
if (d40c->dma_cfg.dir != DMA_DEV_TO_MEM)
__d40_config_set_event(d40c, event_type, event,
D40_CHAN_REG_SDLNK);
}
}
static u32 d40_chan_has_events(struct d40_chan *d40c)
@ -1417,7 +1470,7 @@ static u32 d40_residue(struct d40_chan *d40c)
>> D40_SREG_ELEM_PHY_ECNT_POS;
}
return num_elt * (1 << d40c->dma_cfg.dst_info.data_width);
return num_elt * d40c->dma_cfg.dst_info.data_width;
}
static bool d40_tx_is_linked(struct d40_chan *d40c)
@ -1693,7 +1746,7 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data)
}
/* ACK interrupt */
writel(1 << idx, base->virtbase + il[row].clr);
writel(BIT(idx), base->virtbase + il[row].clr);
spin_lock(&d40c->lock);
@ -1715,8 +1768,6 @@ static int d40_validate_conf(struct d40_chan *d40c,
struct stedma40_chan_cfg *conf)
{
int res = 0;
u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type);
u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type);
bool is_log = conf->mode == STEDMA40_MODE_LOGICAL;
if (!conf->dir) {
@ -1724,48 +1775,14 @@ static int d40_validate_conf(struct d40_chan *d40c,
res = -EINVAL;
}
if (conf->dst_dev_type != STEDMA40_DEV_DST_MEMORY &&
d40c->base->plat_data->dev_tx[conf->dst_dev_type] == 0 &&
d40c->runtime_addr == 0) {
chan_err(d40c, "Invalid TX channel address (%d)\n",
conf->dst_dev_type);
if ((is_log && conf->dev_type > d40c->base->num_log_chans) ||
(!is_log && conf->dev_type > d40c->base->num_phy_chans) ||
(conf->dev_type < 0)) {
chan_err(d40c, "Invalid device type (%d)\n", conf->dev_type);
res = -EINVAL;
}
if (conf->src_dev_type != STEDMA40_DEV_SRC_MEMORY &&
d40c->base->plat_data->dev_rx[conf->src_dev_type] == 0 &&
d40c->runtime_addr == 0) {
chan_err(d40c, "Invalid RX channel address (%d)\n",
conf->src_dev_type);
res = -EINVAL;
}
if (conf->dir == STEDMA40_MEM_TO_PERIPH &&
dst_event_group == STEDMA40_DEV_DST_MEMORY) {
chan_err(d40c, "Invalid dst\n");
res = -EINVAL;
}
if (conf->dir == STEDMA40_PERIPH_TO_MEM &&
src_event_group == STEDMA40_DEV_SRC_MEMORY) {
chan_err(d40c, "Invalid src\n");
res = -EINVAL;
}
if (src_event_group == STEDMA40_DEV_SRC_MEMORY &&
dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) {
chan_err(d40c, "No event line\n");
res = -EINVAL;
}
if (conf->dir == STEDMA40_PERIPH_TO_PERIPH &&
(src_event_group != dst_event_group)) {
chan_err(d40c, "Invalid event group\n");
res = -EINVAL;
}
if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) {
if (conf->dir == DMA_DEV_TO_DEV) {
/*
* DMAC HW supports it. Will be added to this driver,
* in case any dma client requires it.
@ -1775,9 +1792,9 @@ static int d40_validate_conf(struct d40_chan *d40c,
}
if (d40_psize_2_burst_size(is_log, conf->src_info.psize) *
(1 << conf->src_info.data_width) !=
conf->src_info.data_width !=
d40_psize_2_burst_size(is_log, conf->dst_info.psize) *
(1 << conf->dst_info.data_width)) {
conf->dst_info.data_width) {
/*
* The DMAC hardware only supports
* src (burst x width) == dst (burst x width)
@ -1819,8 +1836,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy,
if (phy->allocated_src == D40_ALLOC_FREE)
phy->allocated_src = D40_ALLOC_LOG_FREE;
if (!(phy->allocated_src & (1 << log_event_line))) {
phy->allocated_src |= 1 << log_event_line;
if (!(phy->allocated_src & BIT(log_event_line))) {
phy->allocated_src |= BIT(log_event_line);
goto found;
} else
goto not_found;
@ -1831,8 +1848,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy,
if (phy->allocated_dst == D40_ALLOC_FREE)
phy->allocated_dst = D40_ALLOC_LOG_FREE;
if (!(phy->allocated_dst & (1 << log_event_line))) {
phy->allocated_dst |= 1 << log_event_line;
if (!(phy->allocated_dst & BIT(log_event_line))) {
phy->allocated_dst |= BIT(log_event_line);
goto found;
} else
goto not_found;
@ -1862,11 +1879,11 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src,
/* Logical channel */
if (is_src) {
phy->allocated_src &= ~(1 << log_event_line);
phy->allocated_src &= ~BIT(log_event_line);
if (phy->allocated_src == D40_ALLOC_LOG_FREE)
phy->allocated_src = D40_ALLOC_FREE;
} else {
phy->allocated_dst &= ~(1 << log_event_line);
phy->allocated_dst &= ~BIT(log_event_line);
if (phy->allocated_dst == D40_ALLOC_LOG_FREE)
phy->allocated_dst = D40_ALLOC_FREE;
}
@ -1882,7 +1899,7 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src,
static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
{
int dev_type;
int dev_type = d40c->dma_cfg.dev_type;
int event_group;
int event_line;
struct d40_phy_res *phys;
@ -1896,14 +1913,12 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
phys = d40c->base->phy_res;
num_phy_chans = d40c->base->num_phy_chans;
if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
dev_type = d40c->dma_cfg.src_dev_type;
if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) {
log_num = 2 * dev_type;
is_src = true;
} else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
} else if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
/* dst event lines are used for logical memcpy */
dev_type = d40c->dma_cfg.dst_dev_type;
log_num = 2 * dev_type + 1;
is_src = false;
} else
@ -1913,7 +1928,7 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
event_line = D40_TYPE_TO_EVENT(dev_type);
if (!is_log) {
if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
if (d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
/* Find physical half channel */
if (d40c->dma_cfg.use_fixed_channel) {
i = d40c->dma_cfg.phy_channel;
@ -2014,14 +2029,23 @@ static int d40_config_memcpy(struct d40_chan *d40c)
dma_cap_mask_t cap = d40c->chan.device->cap_mask;
if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) {
d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log;
d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY;
d40c->dma_cfg.dst_dev_type = d40c->base->plat_data->
memcpy[d40c->chan.chan_id];
d40c->dma_cfg = dma40_memcpy_conf_log;
d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id];
d40_log_cfg(&d40c->dma_cfg,
&d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
} else if (dma_has_cap(DMA_MEMCPY, cap) &&
dma_has_cap(DMA_SLAVE, cap)) {
d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy;
d40c->dma_cfg = dma40_memcpy_conf_phy;
/* Generate interrrupt at end of transfer or relink. */
d40c->dst_def_cfg |= BIT(D40_SREG_CFG_TIM_POS);
/* Generate interrupt on error. */
d40c->src_def_cfg |= BIT(D40_SREG_CFG_EIM_POS);
d40c->dst_def_cfg |= BIT(D40_SREG_CFG_EIM_POS);
} else {
chan_err(d40c, "No memcpy\n");
return -EINVAL;
@ -2034,7 +2058,7 @@ static int d40_free_dma(struct d40_chan *d40c)
{
int res = 0;
u32 event;
u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
struct d40_phy_res *phy = d40c->phy_chan;
bool is_src;
@ -2052,14 +2076,12 @@ static int d40_free_dma(struct d40_chan *d40c)
return -EINVAL;
}
if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
d40c->dma_cfg.dir == DMA_MEM_TO_MEM)
is_src = false;
} else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM)
is_src = true;
} else {
else {
chan_err(d40c, "Unknown direction\n");
return -EINVAL;
}
@ -2100,7 +2122,7 @@ static bool d40_is_paused(struct d40_chan *d40c)
unsigned long flags;
void __iomem *active_reg;
u32 status;
u32 event;
u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
spin_lock_irqsave(&d40c->lock, flags);
@ -2119,12 +2141,10 @@ static bool d40_is_paused(struct d40_chan *d40c)
goto _exit;
}
if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
status = readl(chanbase + D40_CHAN_REG_SDLNK);
} else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
} else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) {
status = readl(chanbase + D40_CHAN_REG_SSLNK);
} else {
chan_err(d40c, "Unknown direction\n");
@ -2255,24 +2275,6 @@ d40_prep_desc(struct d40_chan *chan, struct scatterlist *sg,
return NULL;
}
static dma_addr_t
d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction)
{
struct stedma40_platform_data *plat = chan->base->plat_data;
struct stedma40_chan_cfg *cfg = &chan->dma_cfg;
dma_addr_t addr = 0;
if (chan->runtime_addr)
return chan->runtime_addr;
if (direction == DMA_DEV_TO_MEM)
addr = plat->dev_rx[cfg->src_dev_type];
else if (direction == DMA_MEM_TO_DEV)
addr = plat->dev_tx[cfg->dst_dev_type];
return addr;
}
static struct dma_async_tx_descriptor *
d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,
struct scatterlist *sg_dst, unsigned int sg_len,
@ -2299,14 +2301,10 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,
if (sg_next(&sg_src[sg_len - 1]) == sg_src)
desc->cyclic = true;
if (direction != DMA_TRANS_NONE) {
dma_addr_t dev_addr = d40_get_dev_addr(chan, direction);
if (direction == DMA_DEV_TO_MEM)
src_dev_addr = dev_addr;
else if (direction == DMA_MEM_TO_DEV)
dst_dev_addr = dev_addr;
}
if (direction == DMA_DEV_TO_MEM)
src_dev_addr = chan->runtime_addr;
else if (direction == DMA_MEM_TO_DEV)
dst_dev_addr = chan->runtime_addr;
if (chan_is_logical(chan))
ret = d40_prep_sg_log(chan, desc, sg_src, sg_dst,
@ -2366,7 +2364,7 @@ static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src)
u32 rtreg;
u32 event = D40_TYPE_TO_EVENT(dev_type);
u32 group = D40_TYPE_TO_GROUP(dev_type);
u32 bit = 1 << event;
u32 bit = BIT(event);
u32 prioreg;
struct d40_gen_dmac *dmac = &d40c->base->gen_dmac;
@ -2397,13 +2395,57 @@ static void d40_set_prio_realtime(struct d40_chan *d40c)
if (d40c->base->rev < 3)
return;
if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) ||
(d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
__d40_set_prio_rt(d40c, d40c->dma_cfg.src_dev_type, true);
if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) ||
(d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
__d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true);
if ((d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH) ||
(d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
__d40_set_prio_rt(d40c, d40c->dma_cfg.dst_dev_type, false);
if ((d40c->dma_cfg.dir == DMA_MEM_TO_DEV) ||
(d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
__d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false);
}
#define D40_DT_FLAGS_MODE(flags) ((flags >> 0) & 0x1)
#define D40_DT_FLAGS_DIR(flags) ((flags >> 1) & 0x1)
#define D40_DT_FLAGS_BIG_ENDIAN(flags) ((flags >> 2) & 0x1)
#define D40_DT_FLAGS_FIXED_CHAN(flags) ((flags >> 3) & 0x1)
static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
struct stedma40_chan_cfg cfg;
dma_cap_mask_t cap;
u32 flags;
memset(&cfg, 0, sizeof(struct stedma40_chan_cfg));
dma_cap_zero(cap);
dma_cap_set(DMA_SLAVE, cap);
cfg.dev_type = dma_spec->args[0];
flags = dma_spec->args[2];
switch (D40_DT_FLAGS_MODE(flags)) {
case 0: cfg.mode = STEDMA40_MODE_LOGICAL; break;
case 1: cfg.mode = STEDMA40_MODE_PHYSICAL; break;
}
switch (D40_DT_FLAGS_DIR(flags)) {
case 0:
cfg.dir = DMA_MEM_TO_DEV;
cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags);
break;
case 1:
cfg.dir = DMA_DEV_TO_MEM;
cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags);
break;
}
if (D40_DT_FLAGS_FIXED_CHAN(flags)) {
cfg.phy_channel = dma_spec->args[1];
cfg.use_fixed_channel = true;
}
return dma_request_channel(cap, stedma40_filter, &cfg);
}
/* DMA ENGINE functions */
@ -2435,23 +2477,21 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
}
pm_runtime_get_sync(d40c->base->dev);
/* Fill in basic CFG register values */
d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg,
&d40c->dst_def_cfg, chan_is_logical(d40c));
d40_set_prio_realtime(d40c);
if (chan_is_logical(d40c)) {
d40_log_cfg(&d40c->dma_cfg,
&d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM)
d40c->lcpa = d40c->base->lcpa_base +
d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE;
else
d40c->lcpa = d40c->base->lcpa_base +
d40c->dma_cfg.dst_dev_type *
d40c->dma_cfg.dev_type *
D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
/* Unmask the Global Interrupt Mask. */
d40c->src_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS);
d40c->dst_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS);
}
dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n",
@ -2641,33 +2681,10 @@ static void d40_terminate_all(struct dma_chan *chan)
static int
dma40_config_to_halfchannel(struct d40_chan *d40c,
struct stedma40_half_channel_info *info,
enum dma_slave_buswidth width,
u32 maxburst)
{
enum stedma40_periph_data_width addr_width;
int psize;
switch (width) {
case DMA_SLAVE_BUSWIDTH_1_BYTE:
addr_width = STEDMA40_BYTE_WIDTH;
break;
case DMA_SLAVE_BUSWIDTH_2_BYTES:
addr_width = STEDMA40_HALFWORD_WIDTH;
break;
case DMA_SLAVE_BUSWIDTH_4_BYTES:
addr_width = STEDMA40_WORD_WIDTH;
break;
case DMA_SLAVE_BUSWIDTH_8_BYTES:
addr_width = STEDMA40_DOUBLEWORD_WIDTH;
break;
default:
dev_err(d40c->base->dev,
"illegal peripheral address width "
"requested (%d)\n",
width);
return -EINVAL;
}
if (chan_is_logical(d40c)) {
if (maxburst >= 16)
psize = STEDMA40_PSIZE_LOG_16;
@ -2688,7 +2705,6 @@ dma40_config_to_halfchannel(struct d40_chan *d40c,
psize = STEDMA40_PSIZE_PHY_1;
}
info->data_width = addr_width;
info->psize = psize;
info->flow_ctrl = STEDMA40_NO_FLOW_CTRL;
@ -2712,21 +2728,14 @@ static int d40_set_runtime_config(struct dma_chan *chan,
dst_maxburst = config->dst_maxburst;
if (config->direction == DMA_DEV_TO_MEM) {
dma_addr_t dev_addr_rx =
d40c->base->plat_data->dev_rx[cfg->src_dev_type];
config_addr = config->src_addr;
if (dev_addr_rx)
dev_dbg(d40c->base->dev,
"channel has a pre-wired RX address %08x "
"overriding with %08x\n",
dev_addr_rx, config_addr);
if (cfg->dir != STEDMA40_PERIPH_TO_MEM)
if (cfg->dir != DMA_DEV_TO_MEM)
dev_dbg(d40c->base->dev,
"channel was not configured for peripheral "
"to memory transfer (%d) overriding\n",
cfg->dir);
cfg->dir = STEDMA40_PERIPH_TO_MEM;
cfg->dir = DMA_DEV_TO_MEM;
/* Configure the memory side */
if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
@ -2735,21 +2744,14 @@ static int d40_set_runtime_config(struct dma_chan *chan,
dst_maxburst = src_maxburst;
} else if (config->direction == DMA_MEM_TO_DEV) {
dma_addr_t dev_addr_tx =
d40c->base->plat_data->dev_tx[cfg->dst_dev_type];
config_addr = config->dst_addr;
if (dev_addr_tx)
dev_dbg(d40c->base->dev,
"channel has a pre-wired TX address %08x "
"overriding with %08x\n",
dev_addr_tx, config_addr);
if (cfg->dir != STEDMA40_MEM_TO_PERIPH)
if (cfg->dir != DMA_MEM_TO_DEV)
dev_dbg(d40c->base->dev,
"channel was not configured for memory "
"to peripheral transfer (%d) overriding\n",
cfg->dir);
cfg->dir = STEDMA40_MEM_TO_PERIPH;
cfg->dir = DMA_MEM_TO_DEV;
/* Configure the memory side */
if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
@ -2763,6 +2765,11 @@ static int d40_set_runtime_config(struct dma_chan *chan,
return -EINVAL;
}
if (config_addr <= 0) {
dev_err(d40c->base->dev, "no address supplied\n");
return -EINVAL;
}
if (src_maxburst * src_addr_width != dst_maxburst * dst_addr_width) {
dev_err(d40c->base->dev,
"src/dst width/maxburst mismatch: %d*%d != %d*%d\n",
@ -2781,14 +2788,24 @@ static int d40_set_runtime_config(struct dma_chan *chan,
src_maxburst = dst_maxburst * dst_addr_width / src_addr_width;
}
/* Only valid widths are; 1, 2, 4 and 8. */
if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES ||
dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES ||
((src_addr_width > 1) && (src_addr_width & 1)) ||
((dst_addr_width > 1) && (dst_addr_width & 1)))
return -EINVAL;
cfg->src_info.data_width = src_addr_width;
cfg->dst_info.data_width = dst_addr_width;
ret = dma40_config_to_halfchannel(d40c, &cfg->src_info,
src_addr_width,
src_maxburst);
if (ret)
return ret;
ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info,
dst_addr_width,
dst_maxburst);
if (ret)
return ret;
@ -2797,8 +2814,7 @@ static int d40_set_runtime_config(struct dma_chan *chan,
if (chan_is_logical(d40c))
d40_log_cfg(cfg, &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
else
d40_phy_cfg(cfg, &d40c->src_def_cfg,
&d40c->dst_def_cfg, false);
d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg);
/* These settings will take precedence later */
d40c->runtime_addr = config_addr;
@ -2929,7 +2945,7 @@ static int __init d40_dmaengine_init(struct d40_base *base,
}
d40_chan_init(base, &base->dma_memcpy, base->log_chans,
base->num_log_chans, base->plat_data->memcpy_len);
base->num_log_chans, base->num_memcpy_chans);
dma_cap_zero(base->dma_memcpy.cap_mask);
dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
@ -3123,13 +3139,14 @@ static int __init d40_phy_res_init(struct d40_base *base)
static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
{
struct stedma40_platform_data *plat_data;
struct stedma40_platform_data *plat_data = pdev->dev.platform_data;
struct clk *clk = NULL;
void __iomem *virtbase = NULL;
struct resource *res = NULL;
struct d40_base *base = NULL;
int num_log_chans = 0;
int num_phy_chans;
int num_memcpy_chans;
int clk_ret = -EINVAL;
int i;
u32 pid;
@ -3189,8 +3206,10 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
* DB8540v1 has revision 4
*/
rev = AMBA_REV_BITS(pid);
plat_data = pdev->dev.platform_data;
if (rev < 2) {
d40_err(&pdev->dev, "hardware revision: %d is not supported", rev);
goto failure;
}
/* The number of physical channels on this HW */
if (plat_data->num_of_phy_chans)
@ -3198,26 +3217,20 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
else
num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4;
dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n",
rev, res->start, num_phy_chans);
/* The number of channels used for memcpy */
if (plat_data->num_of_memcpy_chans)
num_memcpy_chans = plat_data->num_of_memcpy_chans;
else
num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels);
if (rev < 2) {
d40_err(&pdev->dev, "hardware revision: %d is not supported",
rev);
goto failure;
}
num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY;
/* Count the number of logical channels in use */
for (i = 0; i < plat_data->dev_len; i++)
if (plat_data->dev_rx[i] != 0)
num_log_chans++;
for (i = 0; i < plat_data->dev_len; i++)
if (plat_data->dev_tx[i] != 0)
num_log_chans++;
dev_info(&pdev->dev,
"hardware rev: %d @ 0x%x with %d physical and %d logical channels\n",
rev, res->start, num_phy_chans, num_log_chans);
base = kzalloc(ALIGN(sizeof(struct d40_base), 4) +
(num_phy_chans + num_log_chans + plat_data->memcpy_len) *
(num_phy_chans + num_log_chans + num_memcpy_chans) *
sizeof(struct d40_chan), GFP_KERNEL);
if (base == NULL) {
@ -3227,6 +3240,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
base->rev = rev;
base->clk = clk;
base->num_memcpy_chans = num_memcpy_chans;
base->num_phy_chans = num_phy_chans;
base->num_log_chans = num_log_chans;
base->phy_start = res->start;
@ -3278,17 +3292,11 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
if (!base->lookup_phy_chans)
goto failure;
if (num_log_chans + plat_data->memcpy_len) {
/*
* The max number of logical channels are event lines for all
* src devices and dst devices
*/
base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 *
sizeof(struct d40_chan *),
GFP_KERNEL);
if (!base->lookup_log_chans)
goto failure;
}
base->lookup_log_chans = kzalloc(num_log_chans *
sizeof(struct d40_chan *),
GFP_KERNEL);
if (!base->lookup_log_chans)
goto failure;
base->reg_val_backup_chan = kmalloc(base->num_phy_chans *
sizeof(d40_backup_regs_chan),
@ -3472,17 +3480,82 @@ static int __init d40_lcla_allocate(struct d40_base *base)
return ret;
}
static int __init d40_of_probe(struct platform_device *pdev,
struct device_node *np)
{
struct stedma40_platform_data *pdata;
int num_phy = 0, num_memcpy = 0, num_disabled = 0;
const const __be32 *list;
pdata = devm_kzalloc(&pdev->dev,
sizeof(struct stedma40_platform_data),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
/* If absent this value will be obtained from h/w. */
of_property_read_u32(np, "dma-channels", &num_phy);
if (num_phy > 0)
pdata->num_of_phy_chans = num_phy;
list = of_get_property(np, "memcpy-channels", &num_memcpy);
num_memcpy /= sizeof(*list);
if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) {
d40_err(&pdev->dev,
"Invalid number of memcpy channels specified (%d)\n",
num_memcpy);
return -EINVAL;
}
pdata->num_of_memcpy_chans = num_memcpy;
of_property_read_u32_array(np, "memcpy-channels",
dma40_memcpy_channels,
num_memcpy);
list = of_get_property(np, "disabled-channels", &num_disabled);
num_disabled /= sizeof(*list);
if (num_disabled > STEDMA40_MAX_PHYS || num_disabled < 0) {
d40_err(&pdev->dev,
"Invalid number of disabled channels specified (%d)\n",
num_disabled);
return -EINVAL;
}
of_property_read_u32_array(np, "disabled-channels",
pdata->disabled_channels,
num_disabled);
pdata->disabled_channels[num_disabled] = -1;
pdev->dev.platform_data = pdata;
return 0;
}
static int __init d40_probe(struct platform_device *pdev)
{
int err;
struct stedma40_platform_data *plat_data = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
int ret = -ENOENT;
struct d40_base *base;
struct d40_base *base = NULL;
struct resource *res = NULL;
int num_reserved_chans;
u32 val;
base = d40_hw_detect_init(pdev);
if (!plat_data) {
if (np) {
if(d40_of_probe(pdev, np)) {
ret = -ENOMEM;
goto failure;
}
} else {
d40_err(&pdev->dev, "No pdata or Device Tree provided\n");
goto failure;
}
}
base = d40_hw_detect_init(pdev);
if (!base)
goto failure;
@ -3575,6 +3648,7 @@ static int __init d40_probe(struct platform_device *pdev)
base->lcpa_regulator = regulator_get(base->dev, "lcla_esram");
if (IS_ERR(base->lcpa_regulator)) {
d40_err(&pdev->dev, "Failed to get lcpa_regulator\n");
ret = PTR_ERR(base->lcpa_regulator);
base->lcpa_regulator = NULL;
goto failure;
}
@ -3590,19 +3664,26 @@ static int __init d40_probe(struct platform_device *pdev)
}
base->initialized = true;
err = d40_dmaengine_init(base, num_reserved_chans);
if (err)
ret = d40_dmaengine_init(base, num_reserved_chans);
if (ret)
goto failure;
base->dev->dma_parms = &base->dma_parms;
err = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
if (err) {
ret = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
if (ret) {
d40_err(&pdev->dev, "Failed to set dma max seg size\n");
goto failure;
}
d40_hw_init(base);
if (np) {
ret = of_dma_controller_register(np, d40_xlate, NULL);
if (ret)
dev_err(&pdev->dev,
"could not register of_dma_controller\n");
}
dev_info(base->dev, "initialized\n");
return 0;
@ -3656,11 +3737,17 @@ static int __init d40_probe(struct platform_device *pdev)
return ret;
}
static const struct of_device_id d40_match[] = {
{ .compatible = "stericsson,dma40", },
{}
};
static struct platform_driver d40_driver = {
.driver = {
.owner = THIS_MODULE,
.name = D40_NAME,
.pm = DMA40_PM_OPS,
.of_match_table = d40_match,
},
};

View file

@ -10,6 +10,18 @@
#include "ste_dma40_ll.h"
u8 d40_width_to_bits(enum dma_slave_buswidth width)
{
if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
return STEDMA40_ESIZE_8_BIT;
else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
return STEDMA40_ESIZE_16_BIT;
else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return STEDMA40_ESIZE_64_BIT;
else
return STEDMA40_ESIZE_32_BIT;
}
/* Sets up proper LCSP1 and LCSP3 register for a logical channel */
void d40_log_cfg(struct stedma40_chan_cfg *cfg,
u32 *lcsp1, u32 *lcsp3)
@ -18,106 +30,100 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg,
u32 l1 = 0; /* src */
/* src is mem? -> increase address pos */
if (cfg->dir == STEDMA40_MEM_TO_PERIPH ||
cfg->dir == STEDMA40_MEM_TO_MEM)
l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS;
if (cfg->dir == DMA_MEM_TO_DEV ||
cfg->dir == DMA_MEM_TO_MEM)
l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS);
/* dst is mem? -> increase address pos */
if (cfg->dir == STEDMA40_PERIPH_TO_MEM ||
cfg->dir == STEDMA40_MEM_TO_MEM)
l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS;
if (cfg->dir == DMA_DEV_TO_MEM ||
cfg->dir == DMA_MEM_TO_MEM)
l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS);
/* src is hw? -> master port 1 */
if (cfg->dir == STEDMA40_PERIPH_TO_MEM ||
cfg->dir == STEDMA40_PERIPH_TO_PERIPH)
l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS;
if (cfg->dir == DMA_DEV_TO_MEM ||
cfg->dir == DMA_DEV_TO_DEV)
l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS);
/* dst is hw? -> master port 1 */
if (cfg->dir == STEDMA40_MEM_TO_PERIPH ||
cfg->dir == STEDMA40_PERIPH_TO_PERIPH)
l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS;
if (cfg->dir == DMA_MEM_TO_DEV ||
cfg->dir == DMA_DEV_TO_DEV)
l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS);
l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS;
l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS);
l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS;
l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS;
l3 |= d40_width_to_bits(cfg->dst_info.data_width)
<< D40_MEM_LCSP3_DCFG_ESIZE_POS;
l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS;
l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS);
l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS;
l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS;
l1 |= d40_width_to_bits(cfg->src_info.data_width)
<< D40_MEM_LCSP1_SCFG_ESIZE_POS;
*lcsp1 = l1;
*lcsp3 = l3;
}
/* Sets up SRC and DST CFG register for both logical and physical channels */
void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
u32 *src_cfg, u32 *dst_cfg, bool is_log)
void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg)
{
u32 src = 0;
u32 dst = 0;
if (!is_log) {
/* Physical channel */
if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) ||
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
/* Set master port to 1 */
src |= 1 << D40_SREG_CFG_MST_POS;
src |= D40_TYPE_TO_EVENT(cfg->src_dev_type);
if ((cfg->dir == DMA_DEV_TO_MEM) ||
(cfg->dir == DMA_DEV_TO_DEV)) {
/* Set master port to 1 */
src |= BIT(D40_SREG_CFG_MST_POS);
src |= D40_TYPE_TO_EVENT(cfg->dev_type);
if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
src |= 1 << D40_SREG_CFG_PHY_TM_POS;
else
src |= 3 << D40_SREG_CFG_PHY_TM_POS;
}
if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) ||
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
/* Set master port to 1 */
dst |= 1 << D40_SREG_CFG_MST_POS;
dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type);
if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
src |= BIT(D40_SREG_CFG_PHY_TM_POS);
else
src |= 3 << D40_SREG_CFG_PHY_TM_POS;
}
if ((cfg->dir == DMA_MEM_TO_DEV) ||
(cfg->dir == DMA_DEV_TO_DEV)) {
/* Set master port to 1 */
dst |= BIT(D40_SREG_CFG_MST_POS);
dst |= D40_TYPE_TO_EVENT(cfg->dev_type);
if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
dst |= 1 << D40_SREG_CFG_PHY_TM_POS;
else
dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
}
/* Interrupt on end of transfer for destination */
dst |= 1 << D40_SREG_CFG_TIM_POS;
if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
dst |= BIT(D40_SREG_CFG_PHY_TM_POS);
else
dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
}
/* Interrupt on end of transfer for destination */
dst |= BIT(D40_SREG_CFG_TIM_POS);
/* Generate interrupt on error */
src |= 1 << D40_SREG_CFG_EIM_POS;
dst |= 1 << D40_SREG_CFG_EIM_POS;
/* Generate interrupt on error */
src |= BIT(D40_SREG_CFG_EIM_POS);
dst |= BIT(D40_SREG_CFG_EIM_POS);
/* PSIZE */
if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
src |= 1 << D40_SREG_CFG_PHY_PEN_POS;
src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
}
if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
dst |= 1 << D40_SREG_CFG_PHY_PEN_POS;
dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
}
/* PSIZE */
if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
src |= BIT(D40_SREG_CFG_PHY_PEN_POS);
src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
}
if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
dst |= BIT(D40_SREG_CFG_PHY_PEN_POS);
dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
}
/* Element size */
src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS;
dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS;
/* Element size */
src |= d40_width_to_bits(cfg->src_info.data_width)
<< D40_SREG_CFG_ESIZE_POS;
dst |= d40_width_to_bits(cfg->dst_info.data_width)
<< D40_SREG_CFG_ESIZE_POS;
/* Set the priority bit to high for the physical channel */
if (cfg->high_priority) {
src |= 1 << D40_SREG_CFG_PRI_POS;
dst |= 1 << D40_SREG_CFG_PRI_POS;
}
} else {
/* Logical channel */
dst |= 1 << D40_SREG_CFG_LOG_GIM_POS;
src |= 1 << D40_SREG_CFG_LOG_GIM_POS;
/* Set the priority bit to high for the physical channel */
if (cfg->high_priority) {
src |= BIT(D40_SREG_CFG_PRI_POS);
dst |= BIT(D40_SREG_CFG_PRI_POS);
}
if (cfg->src_info.big_endian)
src |= 1 << D40_SREG_CFG_LBE_POS;
src |= BIT(D40_SREG_CFG_LBE_POS);
if (cfg->dst_info.big_endian)
dst |= 1 << D40_SREG_CFG_LBE_POS;
dst |= BIT(D40_SREG_CFG_LBE_POS);
*src_cfg = src;
*dst_cfg = dst;
@ -143,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
num_elems = 2 << psize;
/* Must be aligned */
if (!IS_ALIGNED(data, 0x1 << data_width))
if (!IS_ALIGNED(data, data_width))
return -EINVAL;
/* Transfer size can't be smaller than (num_elms * elem_size) */
if (data_size < num_elems * (0x1 << data_width))
if (data_size < num_elems * data_width)
return -EINVAL;
/* The number of elements. IE now many chunks */
lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
/*
* Distance to next element sized entry.
* Usually the size of the element unless you want gaps.
*/
if (addr_inc)
lli->reg_elt |= (0x1 << data_width) <<
D40_SREG_ELEM_PHY_EIDX_POS;
lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS;
/* Where the data is */
lli->reg_ptr = data;
@ -167,18 +172,20 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
/* If this scatter list entry is the last one, no next link */
if (next_lli == 0)
lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS;
lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS);
else
lli->reg_lnk = next_lli;
/* Set/clear interrupt generation on this link item.*/
if (term_int)
lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS;
lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS);
else
lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS);
lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS);
/* Post link */
lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS;
/*
* Post link - D40_SREG_LNK_PHY_PRE_POS = 0
* Relink happens after transfer completion.
*/
return 0;
}
@ -187,16 +194,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2)
{
u32 max_w = max(data_width1, data_width2);
u32 min_w = min(data_width1, data_width2);
u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w);
u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
if (seg_max > STEDMA40_MAX_SEG_SIZE)
seg_max -= (1 << max_w);
seg_max -= max_w;
if (size <= seg_max)
return size;
if (size <= 2 * seg_max)
return ALIGN(size / 2, 1 << max_w);
return ALIGN(size / 2, max_w);
return seg_max;
}
@ -362,10 +369,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli,
lli->lcsp13 = reg_cfg;
/* The number of elements to transfer */
lli->lcsp02 = ((data_size >> data_width) <<
lli->lcsp02 = ((data_size / data_width) <<
D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK;
BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE);
BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE);
/* 16 LSBs address of the current element */
lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK;

View file

@ -432,8 +432,7 @@ enum d40_lli_flags {
void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
u32 *src_cfg,
u32 *dst_cfg,
bool is_log);
u32 *dst_cfg);
void d40_log_cfg(struct stedma40_chan_cfg *cfg,
u32 *lcsp1,

View file

@ -51,6 +51,8 @@ struct gpio_rcar_priv {
#define FILONOFF 0x28
#define BOTHEDGE 0x4c
#define RCAR_MAX_GPIO_PER_BANK 32
static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
{
return ioread32(p->base + offs);
@ -274,9 +276,35 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = {
.map = gpio_rcar_irq_domain_map,
};
static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p)
{
struct gpio_rcar_config *pdata = p->pdev->dev.platform_data;
struct device_node *np = p->pdev->dev.of_node;
struct of_phandle_args args;
int ret;
if (pdata) {
p->config = *pdata;
} else if (IS_ENABLED(CONFIG_OF) && np) {
ret = of_parse_phandle_with_args(np, "gpio-ranges",
"#gpio-range-cells", 0, &args);
p->config.number_of_pins = ret == 0 && args.args_count == 3
? args.args[2]
: RCAR_MAX_GPIO_PER_BANK;
p->config.gpio_base = -1;
}
if (p->config.number_of_pins == 0 ||
p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) {
dev_warn(&p->pdev->dev,
"Invalid number of gpio lines %u, using %u\n",
p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK);
p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK;
}
}
static int gpio_rcar_probe(struct platform_device *pdev)
{
struct gpio_rcar_config *pdata = pdev->dev.platform_data;
struct gpio_rcar_priv *p;
struct resource *io, *irq;
struct gpio_chip *gpio_chip;
@ -291,14 +319,14 @@ static int gpio_rcar_probe(struct platform_device *pdev)
goto err0;
}
/* deal with driver instance configuration */
if (pdata)
p->config = *pdata;
p->pdev = pdev;
platform_set_drvdata(pdev, p);
spin_lock_init(&p->lock);
/* Get device configuration from DT node or platform data. */
gpio_rcar_parse_pdata(p);
platform_set_drvdata(pdev, p);
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -325,6 +353,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
gpio_chip->set = gpio_rcar_set;
gpio_chip->to_irq = gpio_rcar_to_irq;
gpio_chip->label = name;
gpio_chip->dev = &pdev->dev;
gpio_chip->owner = THIS_MODULE;
gpio_chip->base = p->config.gpio_base;
gpio_chip->ngpio = p->config.number_of_pins;
@ -371,10 +400,12 @@ static int gpio_rcar_probe(struct platform_device *pdev)
p->config.irq_base, ret);
}
ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0,
gpio_chip->base, gpio_chip->ngpio);
if (ret < 0)
dev_warn(&pdev->dev, "failed to add pin range\n");
if (p->config.pctl_name) {
ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0,
gpio_chip->base, gpio_chip->ngpio);
if (ret < 0)
dev_warn(&pdev->dev, "failed to add pin range\n");
}
return 0;
@ -397,11 +428,23 @@ static int gpio_rcar_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id gpio_rcar_of_table[] = {
{
.compatible = "renesas,gpio-rcar",
},
{ },
};
MODULE_DEVICE_TABLE(of, gpio_rcar_of_table);
#endif
static struct platform_driver gpio_rcar_device_driver = {
.probe = gpio_rcar_probe,
.remove = gpio_rcar_remove,
.driver = {
.name = "gpio_rcar",
.of_match_table = of_match_ptr(gpio_rcar_of_table),
}
};

View file

@ -933,67 +933,6 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
s3c_gpiolib_track(chip);
}
#if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
unsigned int pin;
if (WARN_ON(gc->of_gpio_n_cells < 3))
return -EINVAL;
if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
if (gpiospec->args[0] > gc->ngpio)
return -EINVAL;
pin = gc->base + gpiospec->args[0];
if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
pr_warn("gpio_xlate: failed to set pin function\n");
if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
pr_warn("gpio_xlate: failed to set pin pull up/down\n");
if (flags)
*flags = gpiospec->args[2] >> 16;
return gpiospec->args[0];
}
static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
{ .compatible = "samsung,s3c24xx-gpio", },
{}
};
static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset)
{
struct gpio_chip *gc = &chip->chip;
u64 address;
if (!of_have_populated_dt())
return;
address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
gc->of_node = of_find_matching_node_by_address(NULL,
s3c24xx_gpio_dt_match, address);
if (!gc->of_node) {
pr_info("gpio: device tree node not found for gpio controller"
" with base address %08llx\n", address);
return;
}
gc->of_gpio_n_cells = 3;
gc->of_xlate = s3c24xx_gpio_xlate;
}
#else
static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset)
{
return;
}
#endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
int nr_chips, void __iomem *base)
{
@ -1018,8 +957,6 @@ static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
gc->direction_output = samsung_gpiolib_2bit_output;
samsung_gpiolib_add(chip);
s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
}
}
@ -3026,6 +2963,10 @@ static __init int samsung_gpiolib_init(void)
*/
struct device_node *pctrl_np;
static const struct of_device_id exynos_pinctrl_ids[] = {
{ .compatible = "samsung,s3c2412-pinctrl", },
{ .compatible = "samsung,s3c2416-pinctrl", },
{ .compatible = "samsung,s3c2440-pinctrl", },
{ .compatible = "samsung,s3c2450-pinctrl", },
{ .compatible = "samsung,exynos4210-pinctrl", },
{ .compatible = "samsung,exynos4x12-pinctrl", },
{ .compatible = "samsung,exynos5250-pinctrl", },

View file

@ -16,4 +16,38 @@ config PL320_MBOX
Management Engine, primarily for cpufreq. Say Y here if you want
to use the PL320 IPCM support.
config OMAP_MBOX
tristate
help
This option is selected by any OMAP architecture specific mailbox
driver such as CONFIG_OMAP1_MBOX or CONFIG_OMAP2PLUS_MBOX. This
enables the common OMAP mailbox framework code.
config OMAP1_MBOX
tristate "OMAP1 Mailbox framework support"
depends on ARCH_OMAP1
select OMAP_MBOX
help
Mailbox implementation for OMAP chips with hardware for
interprocessor communication involving DSP in OMAP1. Say Y here
if you want to use OMAP1 Mailbox framework support.
config OMAP2PLUS_MBOX
tristate "OMAP2+ Mailbox framework support"
depends on ARCH_OMAP2PLUS
select OMAP_MBOX
help
Mailbox implementation for OMAP family chips with hardware for
interprocessor communication involving DSP, IVA1.0 and IVA2 in
OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you
want to use OMAP2+ Mailbox framework support.
config OMAP_MBOX_KFIFO_SIZE
int "Mailbox kfifo default buffer size (bytes)"
depends on OMAP2PLUS_MBOX || OMAP1_MBOX
default 256
help
Specify the default size of mailbox's kfifo buffers (bytes).
This can also be changed at runtime (via the mbox_kfifo_size
module parameter).
endif

View file

@ -1 +1,7 @@
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o
obj-$(CONFIG_OMAP1_MBOX) += mailbox_omap1.o
mailbox_omap1-objs := mailbox-omap1.o
obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox_omap2.o
mailbox_omap2-objs := mailbox-omap2.o

View file

@ -13,7 +13,8 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <plat/mailbox.h>
#include "omap-mbox.h"
#define MAILBOX_ARM2DSP1 0x00
#define MAILBOX_ARM2DSP1b 0x04
@ -86,21 +87,21 @@ static int omap1_mbox_fifo_full(struct omap_mbox *mbox)
/* irq */
static void
omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
if (irq == IRQ_RX)
enable_irq(mbox->irq);
}
static void
omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
if (irq == IRQ_RX)
disable_irq(mbox->irq);
}
static int
omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
if (irq == IRQ_TX)
return 0;
@ -152,6 +153,9 @@ static int omap1_mbox_probe(struct platform_device *pdev)
list[0]->irq = platform_get_irq_byname(pdev, "dsp");
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
return -ENOENT;
mbox_base = ioremap(mem->start, resource_size(mem));
if (!mbox_base)
return -ENOMEM;

View file

@ -11,15 +11,15 @@
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/mailbox-omap.h>
#include <plat/mailbox.h>
#include "soc.h"
#include "omap-mbox.h"
#define MAILBOX_REVISION 0x000
#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
@ -59,11 +59,9 @@ struct omap_mbox2_priv {
u32 notfull_bit;
u32 ctx[OMAP4_MBOX_NR_REGS];
unsigned long irqdisable;
u32 intr_type;
};
static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq);
static inline unsigned int mbox_read_reg(size_t ofs)
{
return __raw_readl(mbox_base + ofs);
@ -124,8 +122,7 @@ static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
}
/* Mailbox IRQ handle functions */
static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
struct omap_mbox2_priv *p = mbox->priv;
u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
@ -135,20 +132,22 @@ static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
mbox_write_reg(l, p->irqenable);
}
static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
struct omap_mbox2_priv *p = mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
if (!cpu_is_omap44xx())
/*
* Read and update the interrupt configuration register for pre-OMAP4.
* OMAP4 and later SoCs have a dedicated interrupt disabling register.
*/
if (!p->intr_type)
bit = mbox_read_reg(p->irqdisable) & ~bit;
mbox_write_reg(bit, p->irqdisable);
}
static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
struct omap_mbox2_priv *p = mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
@ -159,8 +158,7 @@ static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
mbox_read_reg(p->irqstatus);
}
static int omap2_mbox_is_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
struct omap_mbox2_priv *p = mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
@ -175,7 +173,8 @@ static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
int i;
struct omap_mbox2_priv *p = mbox->priv;
int nr_regs;
if (cpu_is_omap44xx())
if (p->intr_type)
nr_regs = OMAP4_MBOX_NR_REGS;
else
nr_regs = MBOX_NR_REGS;
@ -192,7 +191,8 @@ static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
int i;
struct omap_mbox2_priv *p = mbox->priv;
int nr_regs;
if (cpu_is_omap44xx())
if (p->intr_type)
nr_regs = OMAP4_MBOX_NR_REGS;
else
nr_regs = MBOX_NR_REGS;
@ -220,192 +220,120 @@ static struct omap_mbox_ops omap2_mbox_ops = {
.restore_ctx = omap2_mbox_restore_ctx,
};
/*
* MAILBOX 0: ARM -> DSP,
* MAILBOX 1: ARM <- DSP.
* MAILBOX 2: ARM -> IVA,
* MAILBOX 3: ARM <- IVA.
*/
/* FIXME: the following structs should be filled automatically by the user id */
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2)
/* DSP */
static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE(0),
.fifo_stat = MAILBOX_FIFOSTATUS(0),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE(1),
.msg_stat = MAILBOX_MSGSTATUS(1),
},
.irqenable = MAILBOX_IRQENABLE(0),
.irqstatus = MAILBOX_IRQSTATUS(0),
.notfull_bit = MAILBOX_IRQ_NOTFULL(0),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
.irqdisable = MAILBOX_IRQENABLE(0),
};
struct omap_mbox mbox_dsp_info = {
.name = "dsp",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_dsp_priv,
};
#endif
#if defined(CONFIG_ARCH_OMAP3)
struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL };
#endif
#if defined(CONFIG_SOC_OMAP2420)
/* IVA */
static struct omap_mbox2_priv omap2_mbox_iva_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE(2),
.fifo_stat = MAILBOX_FIFOSTATUS(2),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE(3),
.msg_stat = MAILBOX_MSGSTATUS(3),
},
.irqenable = MAILBOX_IRQENABLE(3),
.irqstatus = MAILBOX_IRQSTATUS(3),
.notfull_bit = MAILBOX_IRQ_NOTFULL(2),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
.irqdisable = MAILBOX_IRQENABLE(3),
};
static struct omap_mbox mbox_iva_info = {
.name = "iva",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_iva_priv,
};
#endif
#ifdef CONFIG_ARCH_OMAP2
struct omap_mbox *omap2_mboxes[] = {
&mbox_dsp_info,
#ifdef CONFIG_SOC_OMAP2420
&mbox_iva_info,
#endif
NULL
};
#endif
#if defined(CONFIG_ARCH_OMAP4)
/* OMAP4 */
static struct omap_mbox2_priv omap2_mbox_1_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE(0),
.fifo_stat = MAILBOX_FIFOSTATUS(0),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE(1),
.msg_stat = MAILBOX_MSGSTATUS(1),
},
.irqenable = OMAP4_MAILBOX_IRQENABLE(0),
.irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
.notfull_bit = MAILBOX_IRQ_NOTFULL(0),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
.irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
};
struct omap_mbox mbox_1_info = {
.name = "mailbox-1",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_1_priv,
};
static struct omap_mbox2_priv omap2_mbox_2_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE(3),
.fifo_stat = MAILBOX_FIFOSTATUS(3),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE(2),
.msg_stat = MAILBOX_MSGSTATUS(2),
},
.irqenable = OMAP4_MAILBOX_IRQENABLE(0),
.irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
.notfull_bit = MAILBOX_IRQ_NOTFULL(3),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(2),
.irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
};
struct omap_mbox mbox_2_info = {
.name = "mailbox-2",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_2_priv,
};
struct omap_mbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
#endif
static int omap2_mbox_probe(struct platform_device *pdev)
{
struct resource *mem;
int ret;
struct omap_mbox **list;
struct omap_mbox **list, *mbox, *mboxblk;
struct omap_mbox2_priv *priv, *privblk;
struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
struct omap_mbox_dev_info *info;
int i;
if (false)
;
#if defined(CONFIG_ARCH_OMAP3)
else if (cpu_is_omap34xx()) {
list = omap3_mboxes;
list[0]->irq = platform_get_irq(pdev, 0);
}
#endif
#if defined(CONFIG_ARCH_OMAP2)
else if (cpu_is_omap2430()) {
list = omap2_mboxes;
list[0]->irq = platform_get_irq(pdev, 0);
} else if (cpu_is_omap2420()) {
list = omap2_mboxes;
list[0]->irq = platform_get_irq_byname(pdev, "dsp");
list[1]->irq = platform_get_irq_byname(pdev, "iva");
}
#endif
#if defined(CONFIG_ARCH_OMAP4)
else if (cpu_is_omap44xx()) {
list = omap4_mboxes;
list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
}
#endif
else {
if (!pdata || !pdata->info_cnt || !pdata->info) {
pr_err("%s: platform not supported\n", __func__);
return -ENODEV;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mbox_base = ioremap(mem->start, resource_size(mem));
if (!mbox_base)
/* allocate one extra for marking end of list */
list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL);
if (!list)
return -ENOMEM;
ret = omap_mbox_register(&pdev->dev, list);
if (ret) {
iounmap(mbox_base);
return ret;
mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL);
if (!mboxblk) {
ret = -ENOMEM;
goto free_list;
}
privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL);
if (!privblk) {
ret = -ENOMEM;
goto free_mboxblk;
}
info = pdata->info;
for (i = 0; i < pdata->info_cnt; i++, info++, priv++) {
priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id);
priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id);
priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id);
priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id);
priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id);
priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id);
if (pdata->intr_type) {
priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id);
priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id);
priv->irqdisable =
OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id);
} else {
priv->irqenable = MAILBOX_IRQENABLE(info->usr_id);
priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id);
priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id);
}
priv->intr_type = pdata->intr_type;
mbox->priv = priv;
mbox->name = info->name;
mbox->ops = &omap2_mbox_ops;
mbox->irq = platform_get_irq(pdev, info->irq_id);
if (mbox->irq < 0) {
ret = mbox->irq;
goto free_privblk;
}
list[i] = mbox++;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
ret = -ENOENT;
goto free_privblk;
}
mbox_base = ioremap(mem->start, resource_size(mem));
if (!mbox_base) {
ret = -ENOMEM;
goto free_privblk;
}
ret = omap_mbox_register(&pdev->dev, list);
if (ret)
goto unmap_mbox;
platform_set_drvdata(pdev, list);
return 0;
unmap_mbox:
iounmap(mbox_base);
free_privblk:
kfree(privblk);
free_mboxblk:
kfree(mboxblk);
free_list:
kfree(list);
return ret;
}
static int omap2_mbox_remove(struct platform_device *pdev)
{
struct omap_mbox2_priv *privblk;
struct omap_mbox **list = platform_get_drvdata(pdev);
struct omap_mbox *mboxblk = list[0];
privblk = mboxblk->priv;
omap_mbox_unregister();
iounmap(mbox_base);
kfree(privblk);
kfree(mboxblk);
kfree(list);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver omap2_mbox_driver = {
.probe = omap2_mbox_probe,
.remove = omap2_mbox_remove,
.driver = {
.probe = omap2_mbox_probe,
.remove = omap2_mbox_remove,
.driver = {
.name = "omap-mailbox",
},
};

View file

@ -31,7 +31,7 @@
#include <linux/notifier.h>
#include <linux/module.h>
#include <plat/mailbox.h>
#include "omap-mbox.h"
static struct omap_mbox **mboxes;
@ -116,6 +116,40 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
}
EXPORT_SYMBOL(omap_mbox_msg_send);
void omap_mbox_save_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->save_ctx) {
dev_err(mbox->dev, "%s:\tno save\n", __func__);
return;
}
mbox->ops->save_ctx(mbox);
}
EXPORT_SYMBOL(omap_mbox_save_ctx);
void omap_mbox_restore_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->restore_ctx) {
dev_err(mbox->dev, "%s:\tno restore\n", __func__);
return;
}
mbox->ops->restore_ctx(mbox);
}
EXPORT_SYMBOL(omap_mbox_restore_ctx);
void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->enable_irq(mbox, irq);
}
EXPORT_SYMBOL(omap_mbox_enable_irq);
void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->disable_irq(mbox, irq);
}
EXPORT_SYMBOL(omap_mbox_disable_irq);
static void mbox_tx_tasklet(unsigned long tx_data)
{
struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
@ -261,13 +295,6 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
}
if (!mbox->use_count++) {
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
mbox->name, mbox);
if (unlikely(ret)) {
pr_err("failed to register mailbox interrupt:%d\n",
ret);
goto fail_request_irq;
}
mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
if (!mq) {
ret = -ENOMEM;
@ -282,17 +309,24 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
}
mbox->rxq = mq;
mq->mbox = mbox;
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
mbox->name, mbox);
if (unlikely(ret)) {
pr_err("failed to register mailbox interrupt:%d\n",
ret);
goto fail_request_irq;
}
omap_mbox_enable_irq(mbox, IRQ_RX);
}
mutex_unlock(&mbox_configured_lock);
return 0;
fail_request_irq:
mbox_queue_free(mbox->rxq);
fail_alloc_rxq:
mbox_queue_free(mbox->txq);
fail_alloc_txq:
free_irq(mbox->irq, mbox);
fail_request_irq:
if (mbox->ops->shutdown)
mbox->ops->shutdown(mbox);
mbox->use_count--;

View file

@ -1,20 +1,20 @@
/* mailbox.h */
/*
* omap-mbox.h: OMAP mailbox internal definitions
*
* 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.
*/
#ifndef MAILBOX_H
#define MAILBOX_H
#ifndef OMAP_MBOX_H
#define OMAP_MBOX_H
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/kfifo.h>
typedef u32 mbox_msg_t;
struct omap_mbox;
typedef int __bitwise omap_mbox_irq_t;
#define IRQ_TX ((__force omap_mbox_irq_t) 1)
#define IRQ_RX ((__force omap_mbox_irq_t) 2)
#include <linux/omap-mailbox.h>
typedef int __bitwise omap_mbox_type_t;
#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
@ -51,55 +51,17 @@ struct omap_mbox_queue {
};
struct omap_mbox {
char *name;
const char *name;
unsigned int irq;
struct omap_mbox_queue *txq, *rxq;
struct omap_mbox_ops *ops;
struct device *dev;
void *priv;
int use_count;
struct blocking_notifier_head notifier;
struct blocking_notifier_head notifier;
};
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
void omap_mbox_init_seq(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
int omap_mbox_register(struct device *parent, struct omap_mbox **);
int omap_mbox_unregister(void);
static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->save_ctx) {
dev_err(mbox->dev, "%s:\tno save\n", __func__);
return;
}
mbox->ops->save_ctx(mbox);
}
static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->restore_ctx) {
dev_err(mbox->dev, "%s:\tno restore\n", __func__);
return;
}
mbox->ops->restore_ctx(mbox);
}
static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_irq_t irq)
{
mbox->ops->enable_irq(mbox, irq);
}
static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
omap_mbox_irq_t irq)
{
mbox->ops->disable_irq(mbox, irq);
}
#endif /* MAILBOX_H */
#endif /* OMAP_MBOX_H */

View file

@ -217,6 +217,11 @@ config PINCTRL_EXYNOS5440
select PINMUX
select PINCONF
config PINCTRL_S3C24XX
bool "Samsung S3C24XX SoC pinctrl driver"
depends on ARCH_S3C24XX
select PINCTRL_SAMSUNG
config PINCTRL_S3C64XX
bool "Samsung S3C64XX SoC pinctrl driver"
depends on ARCH_S3C64XX

View file

@ -42,6 +42,7 @@ obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o

View file

@ -0,0 +1,651 @@
/*
* S3C24XX specific support for Samsung pinctrl/gpiolib driver.
*
* Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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 file contains the SamsungS3C24XX specific information required by the
* Samsung pinctrl/gpiolib driver. It also includes the implementation of
* external gpio and wakeup interrupt support.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/of_irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include "pinctrl-samsung.h"
#define NUM_EINT 24
#define NUM_EINT_IRQ 6
#define EINT_MAX_PER_GROUP 8
#define EINTPEND_REG 0xa8
#define EINTMASK_REG 0xa4
#define EINT_GROUP(i) ((int)((i) / EINT_MAX_PER_GROUP))
#define EINT_REG(i) ((EINT_GROUP(i) * 4) + 0x88)
#define EINT_OFFS(i) ((i) % EINT_MAX_PER_GROUP * 4)
#define EINT_LEVEL_LOW 0
#define EINT_LEVEL_HIGH 1
#define EINT_EDGE_FALLING 2
#define EINT_EDGE_RISING 4
#define EINT_EDGE_BOTH 6
#define EINT_MASK 0xf
static struct samsung_pin_bank_type bank_type_1bit = {
.fld_width = { 1, 1, },
.reg_offset = { 0x00, 0x04, },
};
static struct samsung_pin_bank_type bank_type_2bit = {
.fld_width = { 2, 1, 2, },
.reg_offset = { 0x00, 0x04, 0x08, },
};
#define PIN_BANK_A(pins, reg, id) \
{ \
.type = &bank_type_1bit, \
.pctl_offset = reg, \
.nr_pins = pins, \
.eint_type = EINT_TYPE_NONE, \
.name = id \
}
#define PIN_BANK_2BIT(pins, reg, id) \
{ \
.type = &bank_type_2bit, \
.pctl_offset = reg, \
.nr_pins = pins, \
.eint_type = EINT_TYPE_NONE, \
.name = id \
}
#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
{ \
.type = &bank_type_2bit, \
.pctl_offset = reg, \
.nr_pins = pins, \
.eint_type = EINT_TYPE_WKUP, \
.eint_func = 2, \
.eint_mask = emask, \
.eint_offset = eoffs, \
.name = id \
}
/**
* struct s3c24xx_eint_data: EINT common data
* @drvdata: pin controller driver data
* @domains: IRQ domains of particular EINT interrupts
* @parents: mapped parent irqs in the main interrupt controller
*/
struct s3c24xx_eint_data {
struct samsung_pinctrl_drv_data *drvdata;
struct irq_domain *domains[NUM_EINT];
int parents[NUM_EINT_IRQ];
};
/**
* struct s3c24xx_eint_domain_data: per irq-domain data
* @bank: pin bank related to the domain
* @eint_data: common data
* eint0_3_parent_only: live eints 0-3 only in the main intc
*/
struct s3c24xx_eint_domain_data {
struct samsung_pin_bank *bank;
struct s3c24xx_eint_data *eint_data;
bool eint0_3_parent_only;
};
static int s3c24xx_eint_get_trigger(unsigned int type)
{
switch (type) {
case IRQ_TYPE_EDGE_RISING:
return EINT_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
return EINT_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
return EINT_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_HIGH:
return EINT_LEVEL_HIGH;
break;
case IRQ_TYPE_LEVEL_LOW:
return EINT_LEVEL_LOW;
break;
default:
return -EINVAL;
}
}
static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type)
{
/* Edge- and level-triggered interrupts need different handlers */
if (type & IRQ_TYPE_EDGE_BOTH)
__irq_set_handler_locked(irq, handle_edge_irq);
else
__irq_set_handler_locked(irq, handle_level_irq);
}
static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
struct samsung_pin_bank *bank, int pin)
{
struct samsung_pin_bank_type *bank_type = bank->type;
unsigned long flags;
void __iomem *reg;
u8 shift;
u32 mask;
u32 val;
/* Make sure that pin is configured as interrupt */
reg = d->virt_base + bank->pctl_offset;
shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
spin_lock_irqsave(&bank->slock, flags);
val = readl(reg);
val &= ~(mask << shift);
val |= bank->eint_func << shift;
writel(val, reg);
spin_unlock_irqrestore(&bank->slock, flags);
}
static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
int index = bank->eint_offset + data->hwirq;
void __iomem *reg;
int trigger;
u8 shift;
u32 val;
trigger = s3c24xx_eint_get_trigger(type);
if (trigger < 0) {
dev_err(d->dev, "unsupported external interrupt type\n");
return -EINVAL;
}
s3c24xx_eint_set_handler(data->irq, type);
/* Set up interrupt trigger */
reg = d->virt_base + EINT_REG(index);
shift = EINT_OFFS(index);
val = readl(reg);
val &= ~(EINT_MASK << shift);
val |= trigger << shift;
writel(val, reg);
s3c24xx_eint_set_function(d, bank, data->hwirq);
return 0;
}
/* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
static void s3c2410_eint0_3_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
struct s3c24xx_eint_data *eint_data = ddata->eint_data;
int parent_irq = eint_data->parents[data->hwirq];
struct irq_chip *parent_chip = irq_get_chip(parent_irq);
parent_chip->irq_ack(irq_get_irq_data(parent_irq));
}
static void s3c2410_eint0_3_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
struct s3c24xx_eint_data *eint_data = ddata->eint_data;
int parent_irq = eint_data->parents[data->hwirq];
struct irq_chip *parent_chip = irq_get_chip(parent_irq);
parent_chip->irq_mask(irq_get_irq_data(parent_irq));
}
static void s3c2410_eint0_3_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
struct s3c24xx_eint_data *eint_data = ddata->eint_data;
int parent_irq = eint_data->parents[data->hwirq];
struct irq_chip *parent_chip = irq_get_chip(parent_irq);
parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
}
static struct irq_chip s3c2410_eint0_3_chip = {
.name = "s3c2410-eint0_3",
.irq_ack = s3c2410_eint0_3_ack,
.irq_mask = s3c2410_eint0_3_mask,
.irq_unmask = s3c2410_eint0_3_unmask,
.irq_set_type = s3c24xx_eint_type,
};
static void s3c2410_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
{
struct irq_data *data = irq_desc_get_irq_data(desc);
struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
unsigned int virq;
/* the first 4 eints have a simple 1 to 1 mapping */
virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
/* Something must be really wrong if an unmapped EINT is unmasked */
BUG_ON(!virq);
generic_handle_irq(virq);
}
/* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
static void s3c2412_eint0_3_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long bitval = 1UL << data->hwirq;
writel(bitval, d->virt_base + EINTPEND_REG);
}
static void s3c2412_eint0_3_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask |= (1UL << data->hwirq);
writel(mask, d->virt_base + EINTMASK_REG);
}
static void s3c2412_eint0_3_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask &= ~(1UL << data->hwirq);
writel(mask, d->virt_base + EINTMASK_REG);
}
static struct irq_chip s3c2412_eint0_3_chip = {
.name = "s3c2412-eint0_3",
.irq_ack = s3c2412_eint0_3_ack,
.irq_mask = s3c2412_eint0_3_mask,
.irq_unmask = s3c2412_eint0_3_unmask,
.irq_set_type = s3c24xx_eint_type,
};
static void s3c2412_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
struct irq_data *data = irq_desc_get_irq_data(desc);
struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
unsigned int virq;
chained_irq_enter(chip, desc);
/* the first 4 eints have a simple 1 to 1 mapping */
virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
/* Something must be really wrong if an unmapped EINT is unmasked */
BUG_ON(!virq);
generic_handle_irq(virq);
chained_irq_exit(chip, desc);
}
/* Handling of all other eints */
static void s3c24xx_eint_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
writel(1UL << index, d->virt_base + EINTPEND_REG);
}
static void s3c24xx_eint_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask |= (1UL << index);
writel(mask, d->virt_base + EINTMASK_REG);
}
static void s3c24xx_eint_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask &= ~(1UL << index);
writel(mask, d->virt_base + EINTMASK_REG);
}
static struct irq_chip s3c24xx_eint_chip = {
.name = "s3c-eint",
.irq_ack = s3c24xx_eint_ack,
.irq_mask = s3c24xx_eint_mask,
.irq_unmask = s3c24xx_eint_unmask,
.irq_set_type = s3c24xx_eint_type,
};
static inline void s3c24xx_demux_eint(unsigned int irq, struct irq_desc *desc,
u32 offset, u32 range)
{
struct irq_chip *chip = irq_get_chip(irq);
struct s3c24xx_eint_data *data = irq_get_handler_data(irq);
struct samsung_pinctrl_drv_data *d = data->drvdata;
unsigned int pend, mask;
chained_irq_enter(chip, desc);
pend = readl(d->virt_base + EINTPEND_REG);
mask = readl(d->virt_base + EINTMASK_REG);
pend &= ~mask;
pend &= range;
while (pend) {
unsigned int virq;
irq = __ffs(pend);
pend &= ~(1 << irq);
virq = irq_linear_revmap(data->domains[irq], irq - offset);
/* Something is really wrong if an unmapped EINT is unmasked */
BUG_ON(!virq);
generic_handle_irq(virq);
}
chained_irq_exit(chip, desc);
}
static void s3c24xx_demux_eint4_7(unsigned int irq, struct irq_desc *desc)
{
s3c24xx_demux_eint(irq, desc, 0, 0xf0);
}
static void s3c24xx_demux_eint8_23(unsigned int irq, struct irq_desc *desc)
{
s3c24xx_demux_eint(irq, desc, 8, 0xffff00);
}
static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
s3c2410_demux_eint0_3,
s3c2410_demux_eint0_3,
s3c2410_demux_eint0_3,
s3c2410_demux_eint0_3,
s3c24xx_demux_eint4_7,
s3c24xx_demux_eint8_23,
};
static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
s3c2412_demux_eint0_3,
s3c2412_demux_eint0_3,
s3c2412_demux_eint0_3,
s3c2412_demux_eint0_3,
s3c24xx_demux_eint4_7,
s3c24xx_demux_eint8_23,
};
static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct s3c24xx_eint_domain_data *ddata = h->host_data;
struct samsung_pin_bank *bank = ddata->bank;
if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
return -EINVAL;
if (hw <= 3) {
if (ddata->eint0_3_parent_only)
irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
handle_edge_irq);
else
irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
handle_edge_irq);
} else {
irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
handle_edge_irq);
}
irq_set_chip_data(virq, bank);
set_irq_flags(virq, IRQF_VALID);
return 0;
}
static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
.map = s3c24xx_gpf_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct s3c24xx_eint_domain_data *ddata = h->host_data;
struct samsung_pin_bank *bank = ddata->bank;
if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
return -EINVAL;
irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
irq_set_chip_data(virq, bank);
set_irq_flags(virq, IRQF_VALID);
return 0;
}
static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
.map = s3c24xx_gpg_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static const struct of_device_id s3c24xx_eint_irq_ids[] = {
{ .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
{ .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
{ }
};
static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
{
struct device *dev = d->dev;
const struct of_device_id *match;
struct device_node *eint_np = NULL;
struct device_node *np;
struct samsung_pin_bank *bank;
struct s3c24xx_eint_data *eint_data;
const struct irq_domain_ops *ops;
unsigned int i;
bool eint0_3_parent_only;
irq_flow_handler_t *handlers;
for_each_child_of_node(dev->of_node, np) {
match = of_match_node(s3c24xx_eint_irq_ids, np);
if (match) {
eint_np = np;
eint0_3_parent_only = (bool)match->data;
break;
}
}
if (!eint_np)
return -ENODEV;
eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
if (!eint_data)
return -ENOMEM;
eint_data->drvdata = d;
handlers = eint0_3_parent_only ? s3c2410_eint_handlers
: s3c2412_eint_handlers;
for (i = 0; i < NUM_EINT_IRQ; ++i) {
unsigned int irq;
irq = irq_of_parse_and_map(eint_np, i);
if (!irq) {
dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
return -ENXIO;
}
eint_data->parents[i] = irq;
irq_set_chained_handler(irq, handlers[i]);
irq_set_handler_data(irq, eint_data);
}
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
struct s3c24xx_eint_domain_data *ddata;
unsigned int mask;
unsigned int irq;
unsigned int pin;
if (bank->eint_type != EINT_TYPE_WKUP)
continue;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
ddata->bank = bank;
ddata->eint_data = eint_data;
ddata->eint0_3_parent_only = eint0_3_parent_only;
ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
: &s3c24xx_gpg_irq_ops;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, ops, ddata);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");
return -ENXIO;
}
irq = bank->eint_offset;
mask = bank->eint_mask;
for (pin = 0; mask; ++pin, mask >>= 1) {
if (irq > NUM_EINT)
break;
if (!(mask & 1))
continue;
eint_data->domains[irq] = bank->irq_domain;
++irq;
}
}
return 0;
}
static struct samsung_pin_bank s3c2412_pin_banks[] = {
PIN_BANK_A(23, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
PIN_BANK_2BIT(16, 0x030, "gpd"),
PIN_BANK_2BIT(16, 0x040, "gpe"),
PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
PIN_BANK_2BIT(11, 0x070, "gph"),
PIN_BANK_2BIT(13, 0x080, "gpj"),
};
struct samsung_pin_ctrl s3c2412_pin_ctrl[] = {
{
.pin_banks = s3c2412_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2412_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2412-GPIO",
},
};
static struct samsung_pin_bank s3c2416_pin_banks[] = {
PIN_BANK_A(27, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
PIN_BANK_2BIT(16, 0x030, "gpd"),
PIN_BANK_2BIT(16, 0x040, "gpe"),
PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
PIN_BANK_2BIT(15, 0x070, "gph"),
PIN_BANK_2BIT(16, 0x0e0, "gpk"),
PIN_BANK_2BIT(14, 0x0f0, "gpl"),
PIN_BANK_2BIT(2, 0x100, "gpm"),
};
struct samsung_pin_ctrl s3c2416_pin_ctrl[] = {
{
.pin_banks = s3c2416_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2416_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2416-GPIO",
},
};
static struct samsung_pin_bank s3c2440_pin_banks[] = {
PIN_BANK_A(25, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
PIN_BANK_2BIT(16, 0x030, "gpd"),
PIN_BANK_2BIT(16, 0x040, "gpe"),
PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
PIN_BANK_2BIT(11, 0x070, "gph"),
PIN_BANK_2BIT(13, 0x0d0, "gpj"),
};
struct samsung_pin_ctrl s3c2440_pin_ctrl[] = {
{
.pin_banks = s3c2440_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2440_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2440-GPIO",
},
};
static struct samsung_pin_bank s3c2450_pin_banks[] = {
PIN_BANK_A(28, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
PIN_BANK_2BIT(16, 0x030, "gpd"),
PIN_BANK_2BIT(16, 0x040, "gpe"),
PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
PIN_BANK_2BIT(15, 0x070, "gph"),
PIN_BANK_2BIT(16, 0x0d0, "gpj"),
PIN_BANK_2BIT(16, 0x0e0, "gpk"),
PIN_BANK_2BIT(15, 0x0f0, "gpl"),
PIN_BANK_2BIT(2, 0x100, "gpm"),
};
struct samsung_pin_ctrl s3c2450_pin_ctrl[] = {
{
.pin_banks = s3c2450_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2450_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2450-GPIO",
},
};

View file

@ -1117,6 +1117,16 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
#ifdef CONFIG_PINCTRL_S3C64XX
{ .compatible = "samsung,s3c64xx-pinctrl",
.data = s3c64xx_pin_ctrl },
#endif
#ifdef CONFIG_PINCTRL_S3C24XX
{ .compatible = "samsung,s3c2412-pinctrl",
.data = s3c2412_pin_ctrl },
{ .compatible = "samsung,s3c2416-pinctrl",
.data = s3c2416_pin_ctrl },
{ .compatible = "samsung,s3c2440-pinctrl",
.data = s3c2440_pin_ctrl },
{ .compatible = "samsung,s3c2450-pinctrl",
.data = s3c2450_pin_ctrl },
#endif
{},
};

View file

@ -255,5 +255,9 @@ extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2440_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2450_pin_ctrl[];
#endif /* __PINCTRL_SAMSUNG_H */

View file

@ -1488,6 +1488,66 @@ IRQC_PINS_MUX(326, 54);
IRQC_PINS_MUX(327, 55);
IRQC_PINS_MUX(328, 56);
IRQC_PINS_MUX(329, 57);
/* - MMCIF0 ----------------------------------------------------------------- */
static const unsigned int mmc0_data1_pins[] = {
/* D[0] */
164,
};
static const unsigned int mmc0_data1_mux[] = {
MMCD0_0_MARK,
};
static const unsigned int mmc0_data4_pins[] = {
/* D[0:3] */
164, 165, 166, 167,
};
static const unsigned int mmc0_data4_mux[] = {
MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
};
static const unsigned int mmc0_data8_pins[] = {
/* D[0:7] */
164, 165, 166, 167, 168, 169, 170, 171,
};
static const unsigned int mmc0_data8_mux[] = {
MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK,
};
static const unsigned int mmc0_ctrl_pins[] = {
/* CMD, CLK */
172, 173,
};
static const unsigned int mmc0_ctrl_mux[] = {
MMCCMD0_MARK, MMCCLK0_MARK,
};
/* - MMCIF1 ----------------------------------------------------------------- */
static const unsigned int mmc1_data1_pins[] = {
/* D[0] */
199,
};
static const unsigned int mmc1_data1_mux[] = {
MMCD1_0_MARK,
};
static const unsigned int mmc1_data4_pins[] = {
/* D[0:3] */
199, 198, 197, 196,
};
static const unsigned int mmc1_data4_mux[] = {
MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
};
static const unsigned int mmc1_data8_pins[] = {
/* D[0:7] */
199, 198, 197, 196, 195, 194, 193, 192,
};
static const unsigned int mmc1_data8_mux[] = {
MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK,
};
static const unsigned int mmc1_ctrl_pins[] = {
/* CMD, CLK */
200, 203,
};
static const unsigned int mmc1_ctrl_mux[] = {
MMCCMD1_MARK, MMCCLK1_MARK,
};
/* - SCIFA0 ----------------------------------------------------------------- */
static const unsigned int scifa0_data_pins[] = {
/* SCIFA0_RXD, SCIFA0_TXD */
@ -1683,6 +1743,86 @@ static const unsigned int scifb3_ctrl_b_pins[] = {
static const unsigned int scifb3_ctrl_b_mux[] = {
SCIFB3_RTS_38_MARK, SCIFB3_CTS_39_MARK,
};
/* - SDHI0 ------------------------------------------------------------------ */
static const unsigned int sdhi0_data1_pins[] = {
/* D0 */
302,
};
static const unsigned int sdhi0_data1_mux[] = {
SDHID0_0_MARK,
};
static const unsigned int sdhi0_data4_pins[] = {
/* D[0:3] */
302, 303, 304, 305,
};
static const unsigned int sdhi0_data4_mux[] = {
SDHID0_0_MARK, SDHID0_1_MARK, SDHID0_2_MARK, SDHID0_3_MARK,
};
static const unsigned int sdhi0_ctrl_pins[] = {
/* CLK, CMD */
308, 306,
};
static const unsigned int sdhi0_ctrl_mux[] = {
SDHICLK0_MARK, SDHICMD0_MARK,
};
static const unsigned int sdhi0_cd_pins[] = {
/* CD */
301,
};
static const unsigned int sdhi0_cd_mux[] = {
SDHICD0_MARK,
};
static const unsigned int sdhi0_wp_pins[] = {
/* WP */
307,
};
static const unsigned int sdhi0_wp_mux[] = {
SDHIWP0_MARK,
};
/* - SDHI1 ------------------------------------------------------------------ */
static const unsigned int sdhi1_data1_pins[] = {
/* D0 */
289,
};
static const unsigned int sdhi1_data1_mux[] = {
SDHID1_0_MARK,
};
static const unsigned int sdhi1_data4_pins[] = {
/* D[0:3] */
289, 290, 291, 292,
};
static const unsigned int sdhi1_data4_mux[] = {
SDHID1_0_MARK, SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK,
};
static const unsigned int sdhi1_ctrl_pins[] = {
/* CLK, CMD */
293, 294,
};
static const unsigned int sdhi1_ctrl_mux[] = {
SDHICLK1_MARK, SDHICMD1_MARK,
};
/* - SDHI2 ------------------------------------------------------------------ */
static const unsigned int sdhi2_data1_pins[] = {
/* D0 */
295,
};
static const unsigned int sdhi2_data1_mux[] = {
SDHID2_0_MARK,
};
static const unsigned int sdhi2_data4_pins[] = {
/* D[0:3] */
295, 296, 297, 298,
};
static const unsigned int sdhi2_data4_mux[] = {
SDHID2_0_MARK, SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK,
};
static const unsigned int sdhi2_ctrl_pins[] = {
/* CLK, CMD */
299, 300,
};
static const unsigned int sdhi2_ctrl_mux[] = {
SDHICLK2_MARK, SDHICMD2_MARK,
};
static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(irqc_irq0),
@ -1743,6 +1883,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(irqc_irq55),
SH_PFC_PIN_GROUP(irqc_irq56),
SH_PFC_PIN_GROUP(irqc_irq57),
SH_PFC_PIN_GROUP(mmc0_data1),
SH_PFC_PIN_GROUP(mmc0_data4),
SH_PFC_PIN_GROUP(mmc0_data8),
SH_PFC_PIN_GROUP(mmc0_ctrl),
SH_PFC_PIN_GROUP(mmc1_data1),
SH_PFC_PIN_GROUP(mmc1_data4),
SH_PFC_PIN_GROUP(mmc1_data8),
SH_PFC_PIN_GROUP(mmc1_ctrl),
SH_PFC_PIN_GROUP(scifa0_data),
SH_PFC_PIN_GROUP(scifa0_clk),
SH_PFC_PIN_GROUP(scifa0_ctrl),
@ -1770,6 +1918,17 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(scifb3_data_b),
SH_PFC_PIN_GROUP(scifb3_clk_b),
SH_PFC_PIN_GROUP(scifb3_ctrl_b),
SH_PFC_PIN_GROUP(sdhi0_data1),
SH_PFC_PIN_GROUP(sdhi0_data4),
SH_PFC_PIN_GROUP(sdhi0_ctrl),
SH_PFC_PIN_GROUP(sdhi0_cd),
SH_PFC_PIN_GROUP(sdhi0_wp),
SH_PFC_PIN_GROUP(sdhi1_data1),
SH_PFC_PIN_GROUP(sdhi1_data4),
SH_PFC_PIN_GROUP(sdhi1_ctrl),
SH_PFC_PIN_GROUP(sdhi2_data1),
SH_PFC_PIN_GROUP(sdhi2_data4),
SH_PFC_PIN_GROUP(sdhi2_ctrl),
};
static const char * const irqc_groups[] = {
@ -1833,6 +1992,20 @@ static const char * const irqc_groups[] = {
"irqc_irq57",
};
static const char * const mmc0_groups[] = {
"mmc0_data1",
"mmc0_data4",
"mmc0_data8",
"mmc0_ctrl",
};
static const char * const mmc1_groups[] = {
"mmc1_data1",
"mmc1_data4",
"mmc1_data8",
"mmc1_ctrl",
};
static const char * const scifa0_groups[] = {
"scifa0_data",
"scifa0_clk",
@ -1878,14 +2051,39 @@ static const char * const scifb3_groups[] = {
"scifb3_ctrl_b",
};
static const char * const sdhi0_groups[] = {
"sdhi0_data1",
"sdhi0_data4",
"sdhi0_ctrl",
"sdhi0_cd",
"sdhi0_wp",
};
static const char * const sdhi1_groups[] = {
"sdhi1_data1",
"sdhi1_data4",
"sdhi1_ctrl",
};
static const char * const sdhi2_groups[] = {
"sdhi2_data1",
"sdhi2_data4",
"sdhi2_ctrl",
};
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(irqc),
SH_PFC_FUNCTION(mmc0),
SH_PFC_FUNCTION(mmc1),
SH_PFC_FUNCTION(scifa0),
SH_PFC_FUNCTION(scifa1),
SH_PFC_FUNCTION(scifb0),
SH_PFC_FUNCTION(scifb1),
SH_PFC_FUNCTION(scifb2),
SH_PFC_FUNCTION(scifb3),
SH_PFC_FUNCTION(sdhi0),
SH_PFC_FUNCTION(sdhi1),
SH_PFC_FUNCTION(sdhi2),
};
#undef PORTCR

View file

@ -1447,11 +1447,11 @@ MMC_PFC_PINS(mmc_ctrl, RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6));
MMC_PFC_CTRL(mmc_ctrl, MMC_CLK, MMC_CMD);
MMC_PFC_PINS(mmc_data1, RCAR_GP_PIN(1, 7));
MMC_PFC_DAT1(mmc_data1, MMC_D0);
MMC_PFC_PINS(mmc_data4, RCAR_GP_PIN(1, 7), RCAR_GP_PIN(2, 8),
MMC_PFC_PINS(mmc_data4, RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 8),
RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 6));
MMC_PFC_DAT4(mmc_data4, MMC_D0, MMC_D1,
MMC_D2, MMC_D3);
MMC_PFC_PINS(mmc_data8, RCAR_GP_PIN(1, 7), RCAR_GP_PIN(2, 8),
MMC_PFC_PINS(mmc_data8, RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 8),
RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 6),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 0),
RCAR_GP_PIN(0, 30), RCAR_GP_PIN(0, 31));

View file

@ -1979,6 +1979,141 @@ static const unsigned int scif1_clk_e_pins[] = {
static const unsigned int scif1_clk_e_mux[] = {
SCK1_E_MARK,
};
/* - HSCIF0 ----------------------------------------------------------------- */
static const unsigned int hscif0_data_pins[] = {
/* RX, TX */
RCAR_GP_PIN(5, 8), RCAR_GP_PIN(5, 9),
};
static const unsigned int hscif0_data_mux[] = {
HRX0_MARK, HTX0_MARK,
};
static const unsigned int hscif0_clk_pins[] = {
/* SCK */
RCAR_GP_PIN(5, 7),
};
static const unsigned int hscif0_clk_mux[] = {
HSCK0_MARK,
};
static const unsigned int hscif0_ctrl_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 10),
};
static const unsigned int hscif0_ctrl_mux[] = {
HRTS0_N_MARK, HCTS0_N_MARK,
};
static const unsigned int hscif0_data_b_pins[] = {
/* RX, TX */
RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 12),
};
static const unsigned int hscif0_data_b_mux[] = {
HRX0_B_MARK, HTX0_B_MARK,
};
static const unsigned int hscif0_ctrl_b_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 28),
};
static const unsigned int hscif0_ctrl_b_mux[] = {
HRTS0_N_B_MARK, HCTS0_N_B_MARK,
};
static const unsigned int hscif0_data_c_pins[] = {
/* RX, TX */
RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 16),
};
static const unsigned int hscif0_data_c_mux[] = {
HRX0_C_MARK, HTX0_C_MARK,
};
static const unsigned int hscif0_ctrl_c_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 7),
};
static const unsigned int hscif0_ctrl_c_mux[] = {
HRTS0_N_C_MARK, HCTS0_N_C_MARK,
};
static const unsigned int hscif0_data_d_pins[] = {
/* RX, TX */
RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 21),
};
static const unsigned int hscif0_data_d_mux[] = {
HRX0_D_MARK, HTX0_D_MARK,
};
static const unsigned int hscif0_ctrl_d_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(3, 23), RCAR_GP_PIN(3, 22),
};
static const unsigned int hscif0_ctrl_d_mux[] = {
HRTS0_N_D_MARK, HCTS0_N_D_MARK,
};
static const unsigned int hscif0_data_e_pins[] = {
/* RX, TX */
RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
};
static const unsigned int hscif0_data_e_mux[] = {
HRX0_E_MARK, HTX0_E_MARK,
};
static const unsigned int hscif0_ctrl_e_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(2, 24), RCAR_GP_PIN(2, 23),
};
static const unsigned int hscif0_ctrl_e_mux[] = {
HRTS0_N_E_MARK, HCTS0_N_E_MARK,
};
static const unsigned int hscif0_data_f_pins[] = {
/* RX, TX */
RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 25),
};
static const unsigned int hscif0_data_f_mux[] = {
HRX0_F_MARK, HTX0_F_MARK,
};
static const unsigned int hscif0_ctrl_f_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 24),
};
static const unsigned int hscif0_ctrl_f_mux[] = {
HRTS0_N_F_MARK, HCTS0_N_F_MARK,
};
/* - HSCIF1 ----------------------------------------------------------------- */
static const unsigned int hscif1_data_pins[] = {
/* RX, TX */
RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 29),
};
static const unsigned int hscif1_data_mux[] = {
HRX1_MARK, HTX1_MARK,
};
static const unsigned int hscif1_clk_pins[] = {
/* SCK */
RCAR_GP_PIN(4, 27),
};
static const unsigned int hscif1_clk_mux[] = {
HSCK1_MARK,
};
static const unsigned int hscif1_ctrl_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(4, 31), RCAR_GP_PIN(4, 30),
};
static const unsigned int hscif1_ctrl_mux[] = {
HRTS1_N_MARK, HCTS1_N_MARK,
};
static const unsigned int hscif1_data_b_pins[] = {
/* RX, TX */
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 18),
};
static const unsigned int hscif1_data_b_mux[] = {
HRX1_B_MARK, HTX1_B_MARK,
};
static const unsigned int hscif1_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(1, 28),
};
static const unsigned int hscif1_clk_b_mux[] = {
HSCK1_B_MARK,
};
static const unsigned int hscif1_ctrl_b_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
};
static const unsigned int hscif1_ctrl_b_mux[] = {
HRTS1_N_B_MARK, HCTS1_N_B_MARK,
};
/* - SCIFA0 ----------------------------------------------------------------- */
static const unsigned int scifa0_data_pins[] = {
/* RXD, TXD */
@ -2371,8 +2506,7 @@ static const unsigned int tpu0_to3_pins[] = {
static const unsigned int tpu0_to3_mux[] = {
TPU0TO3_MARK,
};
/* - MMCIF ------------------------------------------------------------------ */
/* - MMCIF0 ----------------------------------------------------------------- */
static const unsigned int mmc0_data1_pins[] = {
/* D[0] */
RCAR_GP_PIN(3, 18),
@ -2406,7 +2540,7 @@ static const unsigned int mmc0_ctrl_pins[] = {
static const unsigned int mmc0_ctrl_mux[] = {
MMC0_CLK_MARK, MMC0_CMD_MARK,
};
/* - MMCIF1 ----------------------------------------------------------------- */
static const unsigned int mmc1_data1_pins[] = {
/* D[0] */
RCAR_GP_PIN(3, 26),
@ -2427,7 +2561,7 @@ static const unsigned int mmc1_data8_pins[] = {
RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 27),
RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 29),
RCAR_GP_PIN(3, 30), RCAR_GP_PIN(3, 31),
RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14),
RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
};
static const unsigned int mmc1_data8_mux[] = {
MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK,
@ -2440,8 +2574,7 @@ static const unsigned int mmc1_ctrl_pins[] = {
static const unsigned int mmc1_ctrl_mux[] = {
MMC1_CLK_MARK, MMC1_CMD_MARK,
};
/* - SDHI ------------------------------------------------------------------- */
/* - SDHI0 ------------------------------------------------------------------ */
static const unsigned int sdhi0_data1_pins[] = {
/* D0 */
RCAR_GP_PIN(3, 2),
@ -2477,7 +2610,7 @@ static const unsigned int sdhi0_wp_pins[] = {
static const unsigned int sdhi0_wp_mux[] = {
SD0_WP_MARK,
};
/* - SDHI1 ------------------------------------------------------------------ */
static const unsigned int sdhi1_data1_pins[] = {
/* D0 */
RCAR_GP_PIN(3, 10),
@ -2513,7 +2646,7 @@ static const unsigned int sdhi1_wp_pins[] = {
static const unsigned int sdhi1_wp_mux[] = {
SD1_WP_MARK,
};
/* - SDHI2 ------------------------------------------------------------------ */
static const unsigned int sdhi2_data1_pins[] = {
/* D0 */
RCAR_GP_PIN(3, 18),
@ -2549,7 +2682,7 @@ static const unsigned int sdhi2_wp_pins[] = {
static const unsigned int sdhi2_wp_mux[] = {
SD2_WP_MARK,
};
/* - SDHI3 ------------------------------------------------------------------ */
static const unsigned int sdhi3_data1_pins[] = {
/* D0 */
RCAR_GP_PIN(3, 26),
@ -2591,10 +2724,37 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
SH_PFC_PIN_GROUP(eth_rmii),
SH_PFC_PIN_GROUP(hscif0_data),
SH_PFC_PIN_GROUP(hscif0_clk),
SH_PFC_PIN_GROUP(hscif0_ctrl),
SH_PFC_PIN_GROUP(hscif0_data_b),
SH_PFC_PIN_GROUP(hscif0_ctrl_b),
SH_PFC_PIN_GROUP(hscif0_data_c),
SH_PFC_PIN_GROUP(hscif0_ctrl_c),
SH_PFC_PIN_GROUP(hscif0_data_d),
SH_PFC_PIN_GROUP(hscif0_ctrl_d),
SH_PFC_PIN_GROUP(hscif0_data_e),
SH_PFC_PIN_GROUP(hscif0_ctrl_e),
SH_PFC_PIN_GROUP(hscif0_data_f),
SH_PFC_PIN_GROUP(hscif0_ctrl_f),
SH_PFC_PIN_GROUP(hscif1_data),
SH_PFC_PIN_GROUP(hscif1_clk),
SH_PFC_PIN_GROUP(hscif1_ctrl),
SH_PFC_PIN_GROUP(hscif1_data_b),
SH_PFC_PIN_GROUP(hscif1_clk_b),
SH_PFC_PIN_GROUP(hscif1_ctrl_b),
SH_PFC_PIN_GROUP(intc_irq0),
SH_PFC_PIN_GROUP(intc_irq1),
SH_PFC_PIN_GROUP(intc_irq2),
SH_PFC_PIN_GROUP(intc_irq3),
SH_PFC_PIN_GROUP(mmc0_data1),
SH_PFC_PIN_GROUP(mmc0_data4),
SH_PFC_PIN_GROUP(mmc0_data8),
SH_PFC_PIN_GROUP(mmc0_ctrl),
SH_PFC_PIN_GROUP(mmc1_data1),
SH_PFC_PIN_GROUP(mmc1_data4),
SH_PFC_PIN_GROUP(mmc1_data8),
SH_PFC_PIN_GROUP(mmc1_ctrl),
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_clk),
SH_PFC_PIN_GROUP(scif0_ctrl),
@ -2659,18 +2819,6 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(scifb2_clk_b),
SH_PFC_PIN_GROUP(scifb2_ctrl_b),
SH_PFC_PIN_GROUP(scifb2_data_c),
SH_PFC_PIN_GROUP(tpu0_to0),
SH_PFC_PIN_GROUP(tpu0_to1),
SH_PFC_PIN_GROUP(tpu0_to2),
SH_PFC_PIN_GROUP(tpu0_to3),
SH_PFC_PIN_GROUP(mmc0_data1),
SH_PFC_PIN_GROUP(mmc0_data4),
SH_PFC_PIN_GROUP(mmc0_data8),
SH_PFC_PIN_GROUP(mmc0_ctrl),
SH_PFC_PIN_GROUP(mmc1_data1),
SH_PFC_PIN_GROUP(mmc1_data4),
SH_PFC_PIN_GROUP(mmc1_data8),
SH_PFC_PIN_GROUP(mmc1_ctrl),
SH_PFC_PIN_GROUP(sdhi0_data1),
SH_PFC_PIN_GROUP(sdhi0_data4),
SH_PFC_PIN_GROUP(sdhi0_ctrl),
@ -2691,6 +2839,10 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(sdhi3_ctrl),
SH_PFC_PIN_GROUP(sdhi3_cd),
SH_PFC_PIN_GROUP(sdhi3_wp),
SH_PFC_PIN_GROUP(tpu0_to0),
SH_PFC_PIN_GROUP(tpu0_to1),
SH_PFC_PIN_GROUP(tpu0_to2),
SH_PFC_PIN_GROUP(tpu0_to3),
};
static const char * const eth_groups[] = {
@ -2726,6 +2878,31 @@ static const char * const scif1_groups[] = {
"scif1_clk_e",
};
static const char * const hscif0_groups[] = {
"hscif0_data",
"hscif0_clk",
"hscif0_ctrl",
"hscif0_data_b",
"hscif0_ctrl_b",
"hscif0_data_c",
"hscif0_ctrl_c",
"hscif0_data_d",
"hscif0_ctrl_d",
"hscif0_data_e",
"hscif0_ctrl_e",
"hscif0_data_f",
"hscif0_ctrl_f",
};
static const char * const hscif1_groups[] = {
"hscif1_data",
"hscif1_clk",
"hscif1_ctrl",
"hscif1_data_b",
"hscif1_clk_b",
"hscif1_ctrl_b",
};
static const char * const scifa0_groups[] = {
"scifa0_data",
"scifa0_clk",
@ -2850,7 +3027,11 @@ static const char * const sdhi3_groups[] = {
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(eth),
SH_PFC_FUNCTION(hscif0),
SH_PFC_FUNCTION(hscif1),
SH_PFC_FUNCTION(intc),
SH_PFC_FUNCTION(mmc0),
SH_PFC_FUNCTION(mmc1),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scifa0),
@ -2859,13 +3040,11 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(scifb0),
SH_PFC_FUNCTION(scifb1),
SH_PFC_FUNCTION(scifb2),
SH_PFC_FUNCTION(tpu0),
SH_PFC_FUNCTION(mmc0),
SH_PFC_FUNCTION(mmc1),
SH_PFC_FUNCTION(sdhi0),
SH_PFC_FUNCTION(sdhi1),
SH_PFC_FUNCTION(sdhi2),
SH_PFC_FUNCTION(sdhi3),
SH_PFC_FUNCTION(tpu0),
};
static struct pinmux_cfg_reg pinmux_config_regs[] = {

View file

@ -14,8 +14,9 @@ config OMAP_REMOTEPROC
depends on HAS_DMA
depends on ARCH_OMAP4 || SOC_OMAP5
depends on OMAP_IOMMU
depends on OMAP_MBOX_FWK
select REMOTEPROC
select MAILBOX
select OMAP2PLUS_MBOX
select RPMSG
help
Say y here to support OMAP's remote processors (dual M3

View file

@ -27,8 +27,8 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/remoteproc.h>
#include <linux/omap-mailbox.h>
#include <plat/mailbox.h>
#include <linux/platform_data/remoteproc-omap.h>
#include "omap_remoteproc.h"

View file

@ -5,7 +5,8 @@
menuconfig TIDSPBRIDGE
tristate "DSP Bridge driver"
depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM
select OMAP_MBOX_FWK
select MAILBOX
select OMAP2PLUS_MBOX
help
DSP/BIOS Bridge is designed for platforms that contain a GPP and
one or more attached DSPs. The GPP is considered the master or

Some files were not shown because too many files have changed in this diff Show more