提交 d0440c59 编写于 作者: L Linus Torvalds

Merge tag 'armsoc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC cleanups from Olof Johansson:
 "We've got a fairly large cleanup branch this time.  The bulk of this
  is removal of non-DT platforms of several flavors:

   - Atmel at91 platforms go full-DT, with removal of remaining
     board-file based support

   - OMAP removes legacy board files for three more platforms

   - removal of non-DT mach-msm, newer Qualcomm platforms now live in
     mach-qcom

   - Freescale i.MX25 also removes non-DT platform support"

Most of the rest of the changes here are fallout from the above, i.e. for
example removal of drivers that now lack platforms, etc.

* tag 'armsoc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (58 commits)
  mmc: Remove msm_sdcc driver
  gpio: Remove gpio-msm-v1 driver
  ARM: Remove mach-msm and associated ARM architecture code
  ARM: shmobile: cpuidle: Remove the pointless default driver
  ARM: davinci: dm646x: Add interrupt resource for McASPs
  ARM: davinci: irqs: Correct McASP1 TX interrupt definition for DM646x
  ARM: davinci: dm646x: Clean up the McASP DMA resources
  ARM: davinci: devices-da8xx: Add support for McASP2 on da830
  ARM: davinci: devices-da8xx: Clean up and correct the McASP device creation
  ARM: davinci: devices-da8xx: Add interrupt resource to McASP structs
  ARM: davinci: devices-da8xx: Add resource name for the McASP DMA request
  ARM: OMAP2+: Remove legacy support for omap3 TouchBook
  ARM: OMAP3: Remove legacy support for devkit8000
  ARM: OMAP3: Remove legacy support for EMA-Tech Stalker board
  ARM: shmobile: Consolidate the pm code for R-Car Gen2
  ARM: shmobile: r8a7791: Correct SYSCIER value
  ARM: shmobile: r8a7790: Correct SYSCIER value
  ARM: at91: remove old setup
  ARM: at91: sama5d4: remove useless map_io
  ARM: at91: sama5 use SoC detection infrastructure
  ...
...@@ -10,8 +10,6 @@ IXP4xx ...@@ -10,8 +10,6 @@ IXP4xx
- Intel IXP4xx Network processor. - Intel IXP4xx Network processor.
Makefile Makefile
- Build sourcefiles as part of the Documentation-build for arm - Build sourcefiles as part of the Documentation-build for arm
msm/
- MSM specific documentation
Netwinder Netwinder
- Netwinder specific documentation - Netwinder specific documentation
Porting Porting
......
This document provides an overview of the msm_gpiomux interface, which
is used to provide gpio pin multiplexing and configuration on mach-msm
targets.
History
=======
The first-generation API for gpio configuration & multiplexing on msm
is the function gpio_tlmm_config(). This function has a few notable
shortcomings, which led to its deprecation and replacement by gpiomux:
The 'disable' parameter: Setting the second parameter to
gpio_tlmm_config to GPIO_CFG_DISABLE tells the peripheral
processor in charge of the subsystem to perform a look-up into a
low-power table and apply the low-power/sleep setting for the pin.
As the msm family evolved this became problematic. Not all pins
have sleep settings, not all peripheral processors will accept requests
to apply said sleep settings, and not all msm targets have their gpio
subsystems managed by a peripheral processor. In order to get consistent
behavior on all targets, drivers are forced to ignore this parameter,
rendering it useless.
The 'direction' flag: for all mux-settings other than raw-gpio (0),
the output-enable bit of a gpio is hard-wired to a known
input (usually VDD or ground). For those settings, the direction flag
is meaningless at best, and deceptive at worst. In addition, using the
direction flag to change output-enable (OE) directly can cause trouble in
gpiolib, which has no visibility into gpio direction changes made
in this way. Direction control in gpio mode should be made through gpiolib.
Key Features of gpiomux
=======================
- A consistent interface across all generations of msm. Drivers can expect
the same results on every target.
- gpiomux plays nicely with gpiolib. Functions that should belong to gpiolib
are left to gpiolib and not duplicated here. gpiomux is written with the
intent that gpio_chips will call gpiomux reference-counting methods
from their request() and free() hooks, providing full integration.
- Tabular configuration. Instead of having to call gpio_tlmm_config
hundreds of times, gpio configuration is placed in a single table.
- Per-gpio sleep. Each gpio is individually reference counted, allowing only
those lines which are in use to be put in high-power states.
- 0 means 'do nothing': all flags are designed so that the default memset-zero
equates to a sensible default of 'no configuration', preventing users
from having to provide hundreds of 'no-op' configs for unused or
unwanted lines.
Usage
=====
To use gpiomux, provide configuration information for relevant gpio lines
in the msm_gpiomux_configs table. Since a 0 equates to "unconfigured",
only those lines to be managed by gpiomux need to be specified. Here
is a completely fictional example:
struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
[12] = {
.active = GPIOMUX_VALID | GPIOMUX_DRV_8MA | GPIOMUX_FUNC_1,
.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
},
[34] = {
.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
},
};
To indicate that a gpio is in use, call msm_gpiomux_get() to increase
its reference count. To decrease the reference count, call msm_gpiomux_put().
The effect of this configuration is as follows:
When the system boots, gpios 12 and 34 will be initialized with their
'suspended' configurations. All other gpios, which were left unconfigured,
will not be touched.
When msm_gpiomux_get() is called on gpio 12 to raise its reference count
above 0, its active configuration will be applied. Since no other gpio
line has a valid active configuration, msm_gpiomux_get() will have no
effect on any other line.
When msm_gpiomux_put() is called on gpio 12 or 34 to drop their reference
count to 0, their suspended configurations will be applied.
Since no other gpio line has a valid suspended configuration, no other
gpio line will be effected by msm_gpiomux_put(). Since gpio 34 has no valid
active configuration, this is effectively a no-op for gpio 34 as well,
with one small caveat, see the section "About Output-Enable Settings".
All of the GPIOMUX_VALID flags may seem like unnecessary overhead, but
they address some important issues. As unused entries (all those
except 12 and 34) are zero-filled, gpiomux needs a way to distinguish
the used fields from the unused. In addition, the all-zero pattern
is a valid configuration! Therefore, gpiomux defines an additional bit
which is used to indicate when a field is used. This has the pleasant
side-effect of allowing calls to msm_gpiomux_write to use '0' to indicate
that a value should not be changed:
msm_gpiomux_write(0, GPIOMUX_VALID, 0);
replaces the active configuration of gpio 0 with an all-zero configuration,
but leaves the suspended configuration as it was.
Static Configurations
=====================
To install a static configuration, which is applied at boot and does
not change after that, install a configuration with a suspended component
but no active component, as in the previous example:
[34] = {
.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
},
The suspended setting is applied during boot, and the lack of any valid
active setting prevents any other setting from being applied at runtime.
If other subsystems attempting to access the line is a concern, one could
*really* anchor the configuration down by calling msm_gpiomux_get on the
line at initialization to move the line into active mode. With the line
held, it will never be re-suspended, and with no valid active configuration,
no new configurations will be applied.
But then, if having other subsystems grabbing for the line is truly a concern,
it should be reserved with gpio_request instead, which carries an implicit
msm_gpiomux_get.
gpiomux and gpiolib
===================
It is expected that msm gpio_chips will call msm_gpiomux_get() and
msm_gpiomux_put() from their request and free hooks, like this fictional
example:
static int request(struct gpio_chip *chip, unsigned offset)
{
return msm_gpiomux_get(chip->base + offset);
}
static void free(struct gpio_chip *chip, unsigned offset)
{
msm_gpiomux_put(chip->base + offset);
}
...somewhere in a gpio_chip declaration...
.request = request,
.free = free,
This provides important functionality:
- It guarantees that a gpio line will have its 'active' config applied
when the line is requested, and will not be suspended while the line
remains requested; and
- It guarantees that gpio-direction settings from gpiolib behave sensibly.
See "About Output-Enable Settings."
This mechanism allows for "auto-request" of gpiomux lines via gpiolib
when it is suitable. Drivers wishing more exact control are, of course,
free to also use msm_gpiomux_set and msm_gpiomux_get.
About Output-Enable Settings
============================
Some msm targets do not have the ability to query the current gpio
configuration setting. This means that changes made to the output-enable
(OE) bit by gpiolib cannot be consistently detected and preserved by gpiomux.
Therefore, when gpiomux applies a configuration setting, any direction
settings which may have been applied by gpiolib are lost and the default
input settings are re-applied.
For this reason, drivers should not assume that gpio direction settings
continue to hold if they free and then re-request a gpio. This seems like
common sense - after all, anybody could have obtained the line in the
meantime - but it needs saying.
This also means that calls to msm_gpiomux_write will reset the OE bit,
which means that if the gpio line is held by a client of gpiolib and
msm_gpiomux_write is called, the direction setting has been lost and
gpiolib's internal state has been broken.
Release gpio lines before reconfiguring them.
* Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART) * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
Required properties: Required properties:
- compatible: Should be "atmel,<chip>-usart" - compatible: Should be "atmel,<chip>-usart" or "atmel,<chip>-dbgu"
The compatible <chip> indicated will be the first SoC to support an The compatible <chip> indicated will be the first SoC to support an
additional mode or an USART new feature. additional mode or an USART new feature.
For the dbgu UART, use "atmel,<chip>-dbgu", "atmel,<chip>-usart"
- reg: Should contain registers location and length - reg: Should contain registers location and length
- interrupts: Should contain interrupt - interrupts: Should contain interrupt
- clock-names: tuple listing input clock names. - clock-names: tuple listing input clock names.
......
...@@ -1261,22 +1261,6 @@ L: openmoko-kernel@lists.openmoko.org (subscribers-only) ...@@ -1261,22 +1261,6 @@ L: openmoko-kernel@lists.openmoko.org (subscribers-only)
W: http://wiki.openmoko.org/wiki/Neo_FreeRunner W: http://wiki.openmoko.org/wiki/Neo_FreeRunner
S: Supported S: Supported
ARM/QUALCOMM MSM MACHINE SUPPORT
M: David Brown <davidb@codeaurora.org>
M: Daniel Walker <dwalker@fifo99.com>
M: Bryan Huntsman <bryanh@codeaurora.org>
L: linux-arm-msm@vger.kernel.org
F: arch/arm/mach-msm/
F: drivers/video/fbdev/msm/
F: drivers/mmc/host/msm_sdcc.c
F: drivers/mmc/host/msm_sdcc.h
F: drivers/tty/serial/msm_serial.h
F: drivers/tty/serial/msm_serial.c
F: drivers/*/pm8???-*
F: drivers/mfd/ssbi.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm.git
S: Maintained
ARM/TOSA MACHINE SUPPORT ARM/TOSA MACHINE SUPPORT
M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
M: Dirk Opfer <dirk@opfer-online.de> M: Dirk Opfer <dirk@opfer-online.de>
...@@ -1334,6 +1318,10 @@ L: linux-soc@vger.kernel.org ...@@ -1334,6 +1318,10 @@ L: linux-soc@vger.kernel.org
S: Maintained S: Maintained
F: arch/arm/mach-qcom/ F: arch/arm/mach-qcom/
F: drivers/soc/qcom/ F: drivers/soc/qcom/
F: drivers/tty/serial/msm_serial.h
F: drivers/tty/serial/msm_serial.c
F: drivers/*/pm8???-*
F: drivers/mfd/ssbi.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
ARM/RADISYS ENP2611 MACHINE SUPPORT ARM/RADISYS ENP2611 MACHINE SUPPORT
......
...@@ -367,9 +367,9 @@ config ARCH_AT91 ...@@ -367,9 +367,9 @@ config ARCH_AT91
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select IRQ_DOMAIN select IRQ_DOMAIN
select NEED_MACH_IO_H if PCCARD
select PINCTRL select PINCTRL
select PINCTRL_AT91 select PINCTRL_AT91
select SOC_BUS
select USE_OF select USE_OF
help help
This enables support for systems based on Atmel This enables support for systems based on Atmel
...@@ -632,18 +632,6 @@ config ARCH_PXA ...@@ -632,18 +632,6 @@ config ARCH_PXA
help help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line. Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_MSM
bool "Qualcomm MSM (non-multiplatform)"
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLK
select GENERIC_CLOCKEVENTS
help
Support for Qualcomm MSM/QSD based systems. This runs on the
apps processor of the MSM/QSD and depends on a shared memory
interface to the modem processor which runs the baseband
stack and controls some vital subsystems
(clock and power control, etc).
config ARCH_SHMOBILE_LEGACY config ARCH_SHMOBILE_LEGACY
bool "Renesas ARM SoCs (non-multiplatform)" bool "Renesas ARM SoCs (non-multiplatform)"
select ARCH_SHMOBILE select ARCH_SHMOBILE
...@@ -897,8 +885,6 @@ source "arch/arm/mach-ks8695/Kconfig" ...@@ -897,8 +885,6 @@ source "arch/arm/mach-ks8695/Kconfig"
source "arch/arm/mach-meson/Kconfig" source "arch/arm/mach-meson/Kconfig"
source "arch/arm/mach-msm/Kconfig"
source "arch/arm/mach-moxart/Kconfig" source "arch/arm/mach-moxart/Kconfig"
source "arch/arm/mach-mv78xx0/Kconfig" source "arch/arm/mach-mv78xx0/Kconfig"
......
...@@ -448,25 +448,6 @@ choice ...@@ -448,25 +448,6 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on MMP UART3. on MMP UART3.
config DEBUG_MSM_UART
bool "Kernel low-level debugging messages via MSM UART"
depends on ARCH_MSM
help
Say Y here if you want the debug print routines to direct
their output to the serial port on MSM devices.
ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT #
MSM7X00A, QSD8X50 0xa9a00000 0xe1000000 UART1
MSM7X00A, QSD8X50 0xa9b00000 0xe1000000 UART2
MSM7X00A, QSD8X50 0xa9c00000 0xe1000000 UART3
MSM7X30 0xaca00000 0xe1000000 UART1
MSM7X30 0xacb00000 0xe1000000 UART2
MSM7X30 0xacc00000 0xe1000000 UART3
Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
options based on your needs.
config DEBUG_QCOM_UARTDM config DEBUG_QCOM_UARTDM
bool "Kernel low-level debugging messages via QCOM UARTDM" bool "Kernel low-level debugging messages via QCOM UARTDM"
depends on ARCH_QCOM depends on ARCH_QCOM
...@@ -806,7 +787,7 @@ choice ...@@ -806,7 +787,7 @@ choice
via SCIF2 on Renesas R-Car H1 (R8A7779). via SCIF2 on Renesas R-Car H1 (R8A7779).
config DEBUG_RCAR_GEN2_SCIF0 config DEBUG_RCAR_GEN2_SCIF0
bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793)" bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793"
depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793 depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793
help help
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
...@@ -1295,7 +1276,7 @@ config DEBUG_LL_INCLUDE ...@@ -1295,7 +1276,7 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX6SL_UART || \ DEBUG_IMX6SL_UART || \
DEBUG_IMX6SX_UART DEBUG_IMX6SX_UART
default "debug/ks8695.S" if DEBUG_KS8695_UART default "debug/ks8695.S" if DEBUG_KS8695_UART
default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM default "debug/msm.S" if DEBUG_QCOM_UARTDM
default "debug/netx.S" if DEBUG_NETX_UART default "debug/netx.S" if DEBUG_NETX_UART
default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2 default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
...@@ -1388,7 +1369,6 @@ config DEBUG_UART_PHYS ...@@ -1388,7 +1369,6 @@ config DEBUG_UART_PHYS
default 0x80230000 if DEBUG_PICOXCELL_UART default 0x80230000 if DEBUG_PICOXCELL_UART
default 0x808c0000 if ARCH_EP93XX default 0x808c0000 if ARCH_EP93XX
default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xa9a00000 if DEBUG_MSM_UART
default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1 default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1
default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
default 0xc0013000 if DEBUG_U300_UART default 0xc0013000 if DEBUG_U300_UART
...@@ -1433,7 +1413,7 @@ config DEBUG_UART_PHYS ...@@ -1433,7 +1413,7 @@ config DEBUG_UART_PHYS
DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_LL_UART_EFM32 || \ DEBUG_LL_UART_EFM32 || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_MSM_UART || DEBUG_NETX_UART || \ DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \ DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \ DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \ DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
...@@ -1446,7 +1426,6 @@ config DEBUG_UART_VIRT ...@@ -1446,7 +1426,6 @@ config DEBUG_UART_VIRT
hex "Virtual base address of debug UART" hex "Virtual base address of debug UART"
default 0xe0000a00 if DEBUG_NETX_UART default 0xe0000a00 if DEBUG_NETX_UART
default 0xe0010fe0 if ARCH_RPC default 0xe0010fe0 if ARCH_RPC
default 0xe1000000 if DEBUG_MSM_UART
default 0xf0000be0 if ARCH_EBSA110 default 0xf0000be0 if ARCH_EBSA110
default 0xf0010000 if DEBUG_ASM9260_UART default 0xf0010000 if DEBUG_ASM9260_UART
default 0xf01fb000 if DEBUG_NOMADIK_UART default 0xf01fb000 if DEBUG_NOMADIK_UART
...@@ -1526,7 +1505,7 @@ config DEBUG_UART_VIRT ...@@ -1526,7 +1505,7 @@ config DEBUG_UART_VIRT
default DEBUG_UART_PHYS if !MMU default DEBUG_UART_PHYS if !MMU
depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_MSM_UART || DEBUG_NETX_UART || \ DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
...@@ -1556,7 +1535,7 @@ config DEBUG_UART_8250_FLOW_CONTROL ...@@ -1556,7 +1535,7 @@ config DEBUG_UART_8250_FLOW_CONTROL
config DEBUG_UNCOMPRESS config DEBUG_UNCOMPRESS
bool bool
depends on ARCH_MULTIPLATFORM || ARCH_MSM || PLAT_SAMSUNG depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG
default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \ default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
(!DEBUG_TEGRA_UART || !ZBOOT_ROM) (!DEBUG_TEGRA_UART || !ZBOOT_ROM)
help help
......
...@@ -136,7 +136,6 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000 ...@@ -136,7 +136,6 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000
ifeq ($(CONFIG_ARCH_SA1100),y) ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000 textofs-$(CONFIG_SA1111) := 0x00208000
endif endif
textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
...@@ -171,7 +170,6 @@ machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx ...@@ -171,7 +170,6 @@ machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
machine-$(CONFIG_ARCH_MESON) += meson machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MMP) += mmp machine-$(CONFIG_ARCH_MMP) += mmp
machine-$(CONFIG_ARCH_MOXART) += moxart machine-$(CONFIG_ARCH_MOXART) += moxart
machine-$(CONFIG_ARCH_MSM) += msm
machine-$(CONFIG_ARCH_MV78XX0) += mv78xx0 machine-$(CONFIG_ARCH_MV78XX0) += mv78xx0
machine-$(CONFIG_ARCH_MVEBU) += mvebu machine-$(CONFIG_ARCH_MVEBU) += mvebu
machine-$(CONFIG_ARCH_MXC) += imx machine-$(CONFIG_ARCH_MXC) += imx
......
...@@ -830,7 +830,7 @@ ...@@ -830,7 +830,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91rm9200-usart"; compatible = "atmel,at91rm9200-dbgu", "atmel,at91rm9200-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -753,7 +753,7 @@ ...@@ -753,7 +753,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -276,7 +276,7 @@ ...@@ -276,7 +276,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -762,7 +762,7 @@ ...@@ -762,7 +762,7 @@
}; };
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>; reg = <0xffffee00 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -893,7 +893,7 @@ ...@@ -893,7 +893,7 @@
}; };
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>; reg = <0xffffee00 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -757,7 +757,7 @@ ...@@ -757,7 +757,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -377,7 +377,7 @@ ...@@ -377,7 +377,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -860,7 +860,7 @@ ...@@ -860,7 +860,7 @@
}; };
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>; reg = <0xfffff200 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -439,7 +439,7 @@ ...@@ -439,7 +439,7 @@
}; };
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>; reg = <0xffffee00 0x200>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(13)>, dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(13)>,
......
...@@ -1064,7 +1064,7 @@ ...@@ -1064,7 +1064,7 @@
}; };
dbgu: serial@fc069000 { dbgu: serial@fc069000 {
compatible = "atmel,at91sam9260-usart"; compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfc069000 0x200>; reg = <0xfc069000 0x200>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -24,9 +24,8 @@ CONFIG_ARCH_MXC=y ...@@ -24,9 +24,8 @@ CONFIG_ARCH_MXC=y
CONFIG_MACH_SCB9328=y CONFIG_MACH_SCB9328=y
CONFIG_MACH_APF9328=y CONFIG_MACH_APF9328=y
CONFIG_MACH_MX21ADS=y CONFIG_MACH_MX21ADS=y
CONFIG_MACH_MX25_3DS=y
CONFIG_MACH_EUKREA_CPUIMX25SD=y CONFIG_MACH_EUKREA_CPUIMX25SD=y
CONFIG_MACH_IMX25_DT=y CONFIG_SOC_IMX25=y
CONFIG_MACH_MX27ADS=y CONFIG_MACH_MX27ADS=y
CONFIG_MACH_MX27_3DS=y CONFIG_MACH_MX27_3DS=y
CONFIG_MACH_IMX27_VISSTRIM_M10=y CONFIG_MACH_IMX27_VISSTRIM_M10=y
......
CONFIG_SYSVIPC=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_CLEANCACHE=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_VFP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
CONFIG_CFG80211=y
CONFIG_RFKILL=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_MODE_SLIP6=y
CONFIG_USB_USBNET=y
# CONFIG_USB_NET_AX8817X is not set
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_SPI=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_THERMAL=y
CONFIG_REGULATOR=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_FB=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_DYNAMIC_MINORS=y
# CONFIG_SND_ARM is not set
# CONFIG_SND_SPI is not set
# CONFIG_SND_USB is not set
CONFIG_SND_SOC=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_ACM=y
CONFIG_USB_SERIAL=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_RTC_CLASS=y
CONFIG_STAGING=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT4_FS=y
CONFIG_FUSE_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_CIFS=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
...@@ -13,7 +13,7 @@ CONFIG_ARCH_MVEBU=y ...@@ -13,7 +13,7 @@ CONFIG_ARCH_MVEBU=y
CONFIG_MACH_KIRKWOOD=y CONFIG_MACH_KIRKWOOD=y
CONFIG_MACH_NETXBIG=y CONFIG_MACH_NETXBIG=y
CONFIG_ARCH_MXC=y CONFIG_ARCH_MXC=y
CONFIG_MACH_IMX25_DT=y CONFIG_SOC_IMX25=y
CONFIG_MACH_IMX27_DT=y CONFIG_MACH_IMX27_DT=y
CONFIG_ARCH_U300=y CONFIG_ARCH_U300=y
CONFIG_PCI_MVEBU=y CONFIG_PCI_MVEBU=y
......
...@@ -16,24 +16,17 @@ ...@@ -16,24 +16,17 @@
*/ */
.macro addruart, rp, rv, tmp .macro addruart, rp, rv, tmp
#ifdef CONFIG_DEBUG_UART_PHYS
ldr \rp, =CONFIG_DEBUG_UART_PHYS ldr \rp, =CONFIG_DEBUG_UART_PHYS
ldr \rv, =CONFIG_DEBUG_UART_VIRT ldr \rv, =CONFIG_DEBUG_UART_VIRT
#endif
.endm .endm
.macro senduart, rd, rx .macro senduart, rd, rx
ARM_BE8(rev \rd, \rd ) ARM_BE8(rev \rd, \rd )
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ Write the 1 character to UARTDM_TF @ Write the 1 character to UARTDM_TF
str \rd, [\rx, #0x70] str \rd, [\rx, #0x70]
#else
str \rd, [\rx, #0x0C]
#endif
.endm .endm
.macro waituart, rd, rx .macro waituart, rd, rx
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ check for TX_EMT in UARTDM_SR @ check for TX_EMT in UARTDM_SR
ldr \rd, [\rx, #0x08] ldr \rd, [\rx, #0x08]
ARM_BE8(rev \rd, \rd ) ARM_BE8(rev \rd, \rd )
...@@ -55,13 +48,6 @@ ARM_BE8(rev \rd, \rd ) ...@@ -55,13 +48,6 @@ ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x40] str \rd, [\rx, #0x40]
@ UARTDM reg. Read to induce delay @ UARTDM reg. Read to induce delay
ldr \rd, [\rx, #0x08] ldr \rd, [\rx, #0x08]
#else
@ wait for TX_READY
1001: ldr \rd, [\rx, #0x08]
ARM_BE8(rev \rd, \rd )
tst \rd, #0x04
beq 1001b
#endif
.endm .endm
.macro busyuart, rd, rx .macro busyuart, rd, rx
......
...@@ -24,7 +24,7 @@ config SOC_SAMA5 ...@@ -24,7 +24,7 @@ config SOC_SAMA5
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select MEMORY select MEMORY
select ATMEL_SDRAMC select ATMEL_SDRAMC
select PHYLIB if NETDEVICES select SRAM if PM
menu "Atmel AT91 System-on-Chip" menu "Atmel AT91 System-on-Chip"
...@@ -81,6 +81,8 @@ config SOC_AT91RM9200 ...@@ -81,6 +81,8 @@ config SOC_AT91RM9200
select CPU_ARM920T select CPU_ARM920T
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_AT91_USB_CLK select HAVE_AT91_USB_CLK
select MIGHT_HAVE_PCI
select SRAM if PM
config SOC_AT91SAM9 config SOC_AT91SAM9
bool "AT91SAM9" bool "AT91SAM9"
...@@ -94,6 +96,7 @@ config SOC_AT91SAM9 ...@@ -94,6 +96,7 @@ config SOC_AT91SAM9
select HAVE_AT91_UTMI select HAVE_AT91_UTMI
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select MEMORY select MEMORY
select SRAM if PM
help help
Select this if you are using one of those Atmel SoC: Select this if you are using one of those Atmel SoC:
AT91SAM9260 AT91SAM9260
...@@ -116,20 +119,6 @@ endif # SOC_SAM_V4_V5 ...@@ -116,20 +119,6 @@ endif # SOC_SAM_V4_V5
comment "AT91 Feature Selections" comment "AT91 Feature Selections"
config AT91_SLOW_CLOCK
bool "Suspend-to-RAM disables main oscillator"
select SRAM
depends on SUSPEND
help
Select this if you want Suspend-to-RAM to save the most power
possible (without powering off the CPU) by disabling the PLLs
and main oscillator so that only the 32 KiHz clock is available.
When only that slow-clock is available, some peripherals lose
functionality. Many can't issue wakeup events unless faster
clocks are available. Some lose their operating state and
need to be completely re-initialized.
config AT91_TIMER_HZ config AT91_TIMER_HZ
int "Kernel HZ (jiffies per second)" int "Kernel HZ (jiffies per second)"
range 32 1024 range 32 1024
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := setup.o obj-y := soc.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
...@@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o ...@@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o obj-$(CONFIG_PM) += pm_suspend.o
ifeq ($(CONFIG_PM_DEBUG),y) ifeq ($(CONFIG_PM_DEBUG),y)
CFLAGS_pm.o += -DDEBUG CFLAGS_pm.o += -DDEBUG
......
...@@ -8,25 +8,22 @@ ...@@ -8,25 +8,22 @@
* Licensed under GPLv2 or later. * Licensed under GPLv2 or later.
*/ */
#include <linux/types.h> #include <linux/clk-provider.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
#include <mach/at91_st.h> #include <mach/at91_st.h>
#include "generic.h" #include "generic.h"
#include "soc.h"
static const struct at91_soc rm9200_socs[] = {
AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"),
{ /* sentinel */ },
};
static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd) static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
{ {
...@@ -45,15 +42,20 @@ static void __init at91rm9200_dt_timer_init(void) ...@@ -45,15 +42,20 @@ static void __init at91rm9200_dt_timer_init(void)
static void __init at91rm9200_dt_device_init(void) static void __init at91rm9200_dt_device_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); struct soc_device *soc;
struct device *soc_dev = NULL;
soc = at91_soc_init(rm9200_socs);
if (soc != NULL)
soc_dev = soc_device_to_device(soc);
of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
arm_pm_idle = at91rm9200_idle; arm_pm_idle = at91rm9200_idle;
arm_pm_restart = at91rm9200_restart; arm_pm_restart = at91rm9200_restart;
at91rm9200_pm_init(); at91rm9200_pm_init();
} }
static const char *at91rm9200_dt_board_compat[] __initconst = { static const char *at91rm9200_dt_board_compat[] __initconst = {
"atmel,at91rm9200", "atmel,at91rm9200",
NULL NULL
...@@ -61,7 +63,6 @@ static const char *at91rm9200_dt_board_compat[] __initconst = { ...@@ -61,7 +63,6 @@ static const char *at91rm9200_dt_board_compat[] __initconst = {
DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200") DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200")
.init_time = at91rm9200_dt_timer_init, .init_time = at91rm9200_dt_timer_init,
.map_io = at91_map_io,
.init_machine = at91rm9200_dt_device_init, .init_machine = at91rm9200_dt_device_init,
.dt_compat = at91rm9200_dt_board_compat, .dt_compat = at91rm9200_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -7,29 +7,68 @@ ...@@ -7,29 +7,68 @@
* Licensed under GPLv2 or later. * Licensed under GPLv2 or later.
*/ */
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <asm/system_misc.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/system_misc.h>
#include <asm/mach/irq.h>
#include "generic.h" #include "generic.h"
#include "soc.h"
static void __init at91sam9_dt_device_init(void) static const struct at91_soc at91sam9_socs[] = {
AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL),
AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL),
AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL),
AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL),
AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL),
AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH,
"at91sam9m11", "at91sam9g45"),
AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH,
"at91sam9m10", "at91sam9g45"),
AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH,
"at91sam9g46", "at91sam9g45"),
AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH,
"at91sam9g45", "at91sam9g45"),
AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH,
"at91sam9g15", "at91sam9x5"),
AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH,
"at91sam9g35", "at91sam9x5"),
AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH,
"at91sam9x35", "at91sam9x5"),
AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH,
"at91sam9g25", "at91sam9x5"),
AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH,
"at91sam9x25", "at91sam9x5"),
AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH,
"at91sam9cn12", "at91sam9n12"),
AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH,
"at91sam9n12", "at91sam9n12"),
AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH,
"at91sam9cn11", "at91sam9n12"),
AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"),
AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"),
AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"),
{ /* sentinel */ },
};
static void __init at91sam9_common_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); struct soc_device *soc;
struct device *soc_dev = NULL;
soc = at91_soc_init(at91sam9_socs);
if (soc != NULL)
soc_dev = soc_device_to_device(soc);
of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
}
static void __init at91sam9_dt_device_init(void)
{
at91sam9_common_init();
at91sam9260_pm_init(); at91sam9260_pm_init();
} }
...@@ -40,16 +79,13 @@ static const char *at91_dt_board_compat[] __initconst = { ...@@ -40,16 +79,13 @@ static const char *at91_dt_board_compat[] __initconst = {
DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9") DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.map_io = at91_map_io,
.init_machine = at91sam9_dt_device_init, .init_machine = at91sam9_dt_device_init,
.dt_compat = at91_dt_board_compat, .dt_compat = at91_dt_board_compat,
MACHINE_END MACHINE_END
static void __init at91sam9g45_dt_device_init(void) static void __init at91sam9g45_dt_device_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); at91sam9_common_init();
arm_pm_idle = at91sam9_idle;
at91sam9g45_pm_init(); at91sam9g45_pm_init();
} }
...@@ -60,16 +96,13 @@ static const char *at91sam9g45_board_compat[] __initconst = { ...@@ -60,16 +96,13 @@ static const char *at91sam9g45_board_compat[] __initconst = {
DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45") DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.map_io = at91_map_io,
.init_machine = at91sam9g45_dt_device_init, .init_machine = at91sam9g45_dt_device_init,
.dt_compat = at91sam9g45_board_compat, .dt_compat = at91sam9g45_board_compat,
MACHINE_END MACHINE_END
static void __init at91sam9x5_dt_device_init(void) static void __init at91sam9x5_dt_device_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); at91sam9_common_init();
arm_pm_idle = at91sam9_idle;
at91sam9x5_pm_init(); at91sam9x5_pm_init();
} }
...@@ -81,7 +114,6 @@ static const char *at91sam9x5_board_compat[] __initconst = { ...@@ -81,7 +114,6 @@ static const char *at91sam9x5_board_compat[] __initconst = {
DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9") DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.map_io = at91_map_io,
.init_machine = at91sam9x5_dt_device_init, .init_machine = at91sam9x5_dt_device_init,
.dt_compat = at91sam9x5_board_compat, .dt_compat = at91sam9x5_board_compat,
MACHINE_END MACHINE_END
...@@ -25,10 +25,6 @@ extern void at91rm9200_timer_init(void); ...@@ -25,10 +25,6 @@ extern void at91rm9200_timer_init(void);
extern void at91rm9200_idle(void); extern void at91rm9200_idle(void);
extern void at91sam9_idle(void); extern void at91sam9_idle(void);
/* Matrix */
extern void at91_ioremap_matrix(u32 base_addr);
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern void __init at91rm9200_pm_init(void); extern void __init at91rm9200_pm_init(void);
extern void __init at91sam9260_pm_init(void); extern void __init at91sam9260_pm_init(void);
......
/*
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* Under GPLv2
*/
#ifndef __MACH_AT91_MATRIX_H__
#define __MACH_AT91_MATRIX_H__
#ifndef __ASSEMBLY__
extern void __iomem *at91_matrix_base;
#define at91_matrix_read(field) \
__raw_readl(at91_matrix_base + field)
#define at91_matrix_write(field, value) \
__raw_writel(value, at91_matrix_base + field)
#else
.extern at91_matrix_base
#endif
#endif /* __MACH_AT91_MATRIX_H__ */
/*
* arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
*
* Copyright (C) 2007 Atmel Corporation.
*
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
* Based on AT91SAM9260 datasheet revision B.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef AT91SAM9260_MATRIX_H
#define AT91SAM9260_MATRIX_H
#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */
#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */
#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */
#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */
#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */
#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */
#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */
#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */
#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */
#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */
#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */
#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */
#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */
#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */
#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
#define AT91_MATRIX_EBICSA 0x11C /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_CS1A_SMC (0 << 1)
#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_CS3A_SMC (0 << 3)
#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
#define AT91_MATRIX_CS4A_SMC (0 << 4)
#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
#define AT91_MATRIX_CS5A_SMC (0 << 5)
#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
#endif
/*
* arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
*
* Copyright (C) 2007 Atmel Corporation.
*
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
* Based on AT91SAM9261 datasheet revision D.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef AT91SAM9261_MATRIX_H
#define AT91SAM9261_MATRIX_H
#define AT91_MATRIX_MCFG 0x00 /* Master Configuration Register */
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
#define AT91_MATRIX_SCFG0 0x04 /* Slave Configuration Register 0 */
#define AT91_MATRIX_SCFG1 0x08 /* Slave Configuration Register 1 */
#define AT91_MATRIX_SCFG2 0x0C /* Slave Configuration Register 2 */
#define AT91_MATRIX_SCFG3 0x10 /* Slave Configuration Register 3 */
#define AT91_MATRIX_SCFG4 0x14 /* Slave Configuration Register 4 */
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */
#define AT91_MATRIX_TCR 0x24 /* TCM Configuration Register */
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
#define AT91_MATRIX_ITCM_0 (0 << 0)
#define AT91_MATRIX_ITCM_16 (5 << 0)
#define AT91_MATRIX_ITCM_32 (6 << 0)
#define AT91_MATRIX_ITCM_64 (7 << 0)
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
#define AT91_MATRIX_DTCM_0 (0 << 4)
#define AT91_MATRIX_DTCM_16 (5 << 4)
#define AT91_MATRIX_DTCM_32 (6 << 4)
#define AT91_MATRIX_DTCM_64 (7 << 4)
#define AT91_MATRIX_EBICSA 0x30 /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_CS1A_SMC (0 << 1)
#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_CS3A_SMC (0 << 3)
#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
#define AT91_MATRIX_CS4A_SMC (0 << 4)
#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
#define AT91_MATRIX_CS5A_SMC (0 << 5)
#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_USBPUCR 0x34 /* USB Pad Pull-Up Control Register */
#define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */
#endif
/*
* arch/arm/mach-at91/include/mach/at91sam9263_matrix.h
*
* Copyright (C) 2006 Atmel Corporation.
*
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
* Based on AT91SAM9263 datasheet revision B (Preliminary).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef AT91SAM9263_MATRIX_H
#define AT91SAM9263_MATRIX_H
#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */
#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */
#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */
#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */
#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */
#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */
#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */
#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */
#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */
#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */
#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */
#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */
#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */
#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */
#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */
#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */
#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */
#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */
#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */
#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */
#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */
#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */
#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */
#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */
#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */
#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */
#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */
#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */
#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */
#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */
#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
#define AT91_MATRIX_RCB2 (1 << 2)
#define AT91_MATRIX_RCB3 (1 << 3)
#define AT91_MATRIX_RCB4 (1 << 4)
#define AT91_MATRIX_RCB5 (1 << 5)
#define AT91_MATRIX_RCB6 (1 << 6)
#define AT91_MATRIX_RCB7 (1 << 7)
#define AT91_MATRIX_RCB8 (1 << 8)
#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
#define AT91_MATRIX_ITCM_0 (0 << 0)
#define AT91_MATRIX_ITCM_16 (5 << 0)
#define AT91_MATRIX_ITCM_32 (6 << 0)
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
#define AT91_MATRIX_DTCM_0 (0 << 4)
#define AT91_MATRIX_DTCM_16 (5 << 4)
#define AT91_MATRIX_DTCM_32 (6 << 4)
#define AT91_MATRIX_EBI0CSA 0x120 /* EBI0 Chip Select Assignment Register */
#define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1)
#define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_EBI0_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_EBI0_CS3A_SMC (0 << 3)
#define AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_EBI0_CS4A (1 << 4) /* Chip Select 4 Assignment */
#define AT91_MATRIX_EBI0_CS4A_SMC (0 << 4)
#define AT91_MATRIX_EBI0_CS4A_SMC_CF1 (1 << 4)
#define AT91_MATRIX_EBI0_CS5A (1 << 5) /* Chip Select 5 Assignment */
#define AT91_MATRIX_EBI0_CS5A_SMC (0 << 5)
#define AT91_MATRIX_EBI0_CS5A_SMC_CF2 (1 << 5)
#define AT91_MATRIX_EBI0_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_EBI0_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16)
#define AT91_MATRIX_EBI1CSA 0x124 /* EBI1 Chip Select Assignment Register */
#define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1)
#define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_EBI1_CS2A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_EBI1_CS2A_SMC (0 << 3)
#define AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_EBI1_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_EBI1_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_EBI1_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_EBI1_VDDIOMSEL_3_3V (1 << 16)
#endif
/*
* Matrix-centric header file for the AT91SAM9G45 family
*
* Copyright (C) 2008-2009 Atmel Corporation.
*
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
* Based on AT91SAM9G45 preliminary datasheet.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef AT91SAM9G45_MATRIX_H
#define AT91SAM9G45_MATRIX_H
#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */
#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */
#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */
#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */
#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */
#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */
#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */
#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */
#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */
#define AT91_MATRIX_MCFG9 0x24 /* Master Configuration Register 9 */
#define AT91_MATRIX_MCFG10 0x28 /* Master Configuration Register 10 */
#define AT91_MATRIX_MCFG11 0x2C /* Master Configuration Register 11 */
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0)
#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0)
#define AT91_MATRIX_ULBT_128 (7 << 0)
#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */
#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */
#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */
#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */
#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */
#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */
#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */
#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */
#define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */
#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */
#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */
#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */
#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */
#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */
#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */
#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */
#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */
#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */
#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */
#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */
#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */
#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */
#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */
#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
#define AT91_MATRIX_RCB2 (1 << 2)
#define AT91_MATRIX_RCB3 (1 << 3)
#define AT91_MATRIX_RCB4 (1 << 4)
#define AT91_MATRIX_RCB5 (1 << 5)
#define AT91_MATRIX_RCB6 (1 << 6)
#define AT91_MATRIX_RCB7 (1 << 7)
#define AT91_MATRIX_RCB8 (1 << 8)
#define AT91_MATRIX_RCB9 (1 << 9)
#define AT91_MATRIX_RCB10 (1 << 10)
#define AT91_MATRIX_RCB11 (1 << 11)
#define AT91_MATRIX_TCMR 0x110 /* TCM Configuration Register */
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
#define AT91_MATRIX_ITCM_0 (0 << 0)
#define AT91_MATRIX_ITCM_32 (6 << 0)
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
#define AT91_MATRIX_DTCM_0 (0 << 4)
#define AT91_MATRIX_DTCM_32 (6 << 4)
#define AT91_MATRIX_DTCM_64 (7 << 4)
#define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */
#define AT91_MATRIX_TCM_NO_WS (0x0 << 11)
#define AT91_MATRIX_TCM_ONE_WS (0x1 << 11)
#define AT91_MATRIX_VIDEO 0x118 /* Video Mode Configuration Register */
#define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */
#define AT91C_VDEC_SEL_OFF (0 << 0)
#define AT91C_VDEC_SEL_ON (1 << 0)
#define AT91_MATRIX_EBICSA 0x128 /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4)
#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5)
#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
#define AT91_MATRIX_WPMR 0x1E4 /* Write Protect Mode Register */
#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
#define AT91_MATRIX_WPSR 0x1E8 /* Write Protect Status Register */
#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
#define AT91_MATRIX_WPSR_WPV (1 << 0)
#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
#endif
/*
* Matrix-centric header file for the AT91SAM9N12
*
* Copyright (C) 2012 Atmel Corporation.
*
* Only EBI related registers.
* Write Protect register definitions may be useful.
*
* Licensed under GPLv2 or later.
*/
#ifndef _AT91SAM9N12_MATRIX_H_
#define _AT91SAM9N12_MATRIX_H_
#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x118) /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3)
#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */
#define AT91_MATRIX_NFD0_ON_D0 (0 << 24)
#define AT91_MATRIX_NFD0_ON_D16 (1 << 24)
#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */
#define AT91_MATRIX_MP_OFF (0 << 25)
#define AT91_MATRIX_MP_ON (1 << 25)
#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
#define AT91_MATRIX_WPSR_WPV (1 << 0)
#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
#endif
/*
* arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h
*
* Copyright (C) 2007 Atmel Corporation
*
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
* Based on AT91SAM9RL datasheet revision A. (Preliminary)
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#ifndef AT91SAM9RL_MATRIX_H
#define AT91SAM9RL_MATRIX_H
#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */
#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */
#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */
#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */
#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */
#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */
#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */
#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */
#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */
#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */
#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */
#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */
#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */
#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */
#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */
#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
#define AT91_MATRIX_RCB2 (1 << 2)
#define AT91_MATRIX_RCB3 (1 << 3)
#define AT91_MATRIX_RCB4 (1 << 4)
#define AT91_MATRIX_RCB5 (1 << 5)
#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
#define AT91_MATRIX_ITCM_0 (0 << 0)
#define AT91_MATRIX_ITCM_16 (5 << 0)
#define AT91_MATRIX_ITCM_32 (6 << 0)
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
#define AT91_MATRIX_DTCM_0 (0 << 4)
#define AT91_MATRIX_DTCM_16 (5 << 4)
#define AT91_MATRIX_DTCM_32 (6 << 4)
#define AT91_MATRIX_EBICSA 0x120 /* EBI0 Chip Select Assignment Register */
#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_CS1A_SMC (0 << 1)
#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_CS3A_SMC (0 << 3)
#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
#define AT91_MATRIX_CS4A_SMC (0 << 4)
#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
#define AT91_MATRIX_CS5A_SMC (0 << 5)
#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
#endif
/*
* Matrix-centric header file for the AT91SAM9x5 family
*
* Copyright (C) 2009-2012 Atmel Corporation.
*
* Only EBI related registers.
* Write Protect register definitions may be useful.
*
* Licensed under GPLv2 or later.
*/
#ifndef AT91SAM9X5_MATRIX_H
#define AT91SAM9X5_MATRIX_H
#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3)
#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */
#define AT91_MATRIX_NFD0_ON_D0 (0 << 24)
#define AT91_MATRIX_NFD0_ON_D16 (1 << 24)
#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */
#define AT91_MATRIX_MP_OFF (0 << 25)
#define AT91_MATRIX_MP_ON (1 << 25)
#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
#define AT91_MATRIX_WPSR_WPV (1 << 0)
#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
#endif
/*
* arch/arm/mach-at91/include/mach/io.h
*
* Copyright (C) 2003 SAN People
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xFFFFFFFF
#define __io(a) __typesafe_io(a)
#endif
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/fncpy.h>
#include <asm/cacheflush.h>
#include <mach/cpu.h> #include <mach/cpu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -41,7 +43,6 @@ static struct { ...@@ -41,7 +43,6 @@ static struct {
int memctrl; int memctrl;
} at91_pm_data; } at91_pm_data;
static void (*at91_pm_standby)(void);
void __iomem *at91_ramc_base[2]; void __iomem *at91_ramc_base[2];
static int at91_pm_valid_state(suspend_state_t state) static int at91_pm_valid_state(suspend_state_t state)
...@@ -119,76 +120,67 @@ int at91_suspend_entering_slow_clock(void) ...@@ -119,76 +120,67 @@ int at91_suspend_entering_slow_clock(void)
} }
EXPORT_SYMBOL(at91_suspend_entering_slow_clock); EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl); void __iomem *ramc1, int memctrl);
#ifdef CONFIG_AT91_SLOW_CLOCK extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl); void __iomem *ramc1, int memctrl);
extern u32 at91_slow_clock_sz; extern u32 at91_pm_suspend_in_sram_sz;
#endif
static void at91_pm_suspend(suspend_state_t state)
{
unsigned int pm_data = at91_pm_data.memctrl;
pm_data |= (state == PM_SUSPEND_MEM) ?
AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
flush_cache_all();
outer_disable();
at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0],
at91_ramc_base[1], pm_data);
outer_resume();
}
static int at91_pm_enter(suspend_state_t state) static int at91_pm_enter(suspend_state_t state)
{ {
at91_pinctrl_gpio_suspend(); at91_pinctrl_gpio_suspend();
switch (state) { switch (state) {
/*
* Suspend-to-RAM is like STANDBY plus slow clock mode, so
* drivers must suspend more deeply, the master clock switches
* to the clk32k and turns off the main oscillator
*/
case PM_SUSPEND_MEM:
/* /*
* Suspend-to-RAM is like STANDBY plus slow clock mode, so * Ensure that clocks are in a valid state.
* drivers must suspend more deeply: only the master clock
* controller may be using the main oscillator.
*/ */
case PM_SUSPEND_MEM: if (!at91_pm_verify_clocks())
/* goto error;
* Ensure that clocks are in a valid state.
*/
if (!at91_pm_verify_clocks())
goto error;
/*
* Enter slow clock mode by switching over to clk32k and
* turning off the main oscillator; reverse on wakeup.
*/
if (slow_clock) {
#ifdef CONFIG_AT91_SLOW_CLOCK
/* copy slow_clock handler to SRAM, and call it */
memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
#endif
slow_clock(at91_pmc_base, at91_ramc_base[0],
at91_ramc_base[1],
at91_pm_data.memctrl);
break;
} else {
pr_info("AT91: PM - no slow clock mode enabled ...\n");
/* FALLTHROUGH leaving master clock alone */
}
/* at91_pm_suspend(state);
* STANDBY mode has *all* drivers suspended; ignores irqs not
* marked as 'wakeup' event sources; and reduces DRAM power.
* But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
* nothing fancy done with main or cpu clocks.
*/
case PM_SUSPEND_STANDBY:
/*
* NOTE: the Wait-for-Interrupt instruction needs to be
* in icache so no SDRAM accesses are needed until the
* wakeup IRQ occurs and self-refresh is terminated.
* For ARM 926 based chips, this requirement is weaker
* as at91sam9 can access a RAM in self-refresh mode.
*/
if (at91_pm_standby)
at91_pm_standby();
break;
case PM_SUSPEND_ON: break;
cpu_do_idle();
break;
default: /*
pr_debug("AT91: PM - bogus suspend state %d\n", state); * STANDBY mode has *all* drivers suspended; ignores irqs not
goto error; * marked as 'wakeup' event sources; and reduces DRAM power.
* But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
* nothing fancy done with main or cpu clocks.
*/
case PM_SUSPEND_STANDBY:
at91_pm_suspend(state);
break;
case PM_SUSPEND_ON:
cpu_do_idle();
break;
default:
pr_debug("AT91: PM - bogus suspend state %d\n", state);
goto error;
} }
error: error:
...@@ -218,12 +210,10 @@ static struct platform_device at91_cpuidle_device = { ...@@ -218,12 +210,10 @@ static struct platform_device at91_cpuidle_device = {
.name = "cpuidle-at91", .name = "cpuidle-at91",
}; };
void at91_pm_set_standby(void (*at91_standby)(void)) static void at91_pm_set_standby(void (*at91_standby)(void))
{ {
if (at91_standby) { if (at91_standby)
at91_cpuidle_device.dev.platform_data = at91_standby; at91_cpuidle_device.dev.platform_data = at91_standby;
at91_pm_standby = at91_standby;
}
} }
static const struct of_device_id ramc_ids[] __initconst = { static const struct of_device_id ramc_ids[] __initconst = {
...@@ -263,7 +253,6 @@ static __init void at91_dt_ramc(void) ...@@ -263,7 +253,6 @@ static __init void at91_dt_ramc(void)
at91_pm_set_standby(standby); at91_pm_set_standby(standby);
} }
#ifdef CONFIG_AT91_SLOW_CLOCK
static void __init at91_pm_sram_init(void) static void __init at91_pm_sram_init(void)
{ {
struct gen_pool *sram_pool; struct gen_pool *sram_pool;
...@@ -291,30 +280,36 @@ static void __init at91_pm_sram_init(void) ...@@ -291,30 +280,36 @@ static void __init at91_pm_sram_init(void)
return; return;
} }
sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz); sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
if (!sram_base) { if (!sram_base) {
pr_warn("%s: unable to alloc ocram!\n", __func__); pr_warn("%s: unable to alloc sram!\n", __func__);
return; return;
} }
sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false); at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
} at91_pm_suspend_in_sram_sz, false);
#endif if (!at91_suspend_sram_fn) {
pr_warn("SRAM: Could not map\n");
return;
}
/* Copy the pm suspend handler to SRAM */
at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
}
static void __init at91_pm_init(void) static void __init at91_pm_init(void)
{ {
#ifdef CONFIG_AT91_SLOW_CLOCK
at91_pm_sram_init(); at91_pm_sram_init();
#endif
pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
if (at91_cpuidle_device.dev.platform_data) if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device); platform_device_register(&at91_cpuidle_device);
suspend_set_ops(&at91_pm_ops); if (at91_suspend_sram_fn)
suspend_set_ops(&at91_pm_ops);
else
pr_info("AT91: PM not supported, due to no SRAM allocated\n");
} }
void __init at91rm9200_pm_init(void) void __init at91rm9200_pm_init(void)
......
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
#include <mach/at91_ramc.h> #include <mach/at91_ramc.h>
#ifdef CONFIG_PM #define AT91_PM_MEMTYPE_MASK 0x0f
extern void at91_pm_set_standby(void (*at91_standby)(void));
#else #define AT91_PM_MODE_OFFSET 4
static inline void at91_pm_set_standby(void (*at91_standby)(void)) { } #define AT91_PM_MODE_MASK 0x01
#endif #define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
#define AT91_PM_SLOW_CLOCK 0x01
/* /*
* The AT91RM9200 goes into self-refresh mode with this command, and will * The AT91RM9200 goes into self-refresh mode with this command, and will
...@@ -31,6 +33,7 @@ static inline void at91_pm_set_standby(void (*at91_standby)(void)) { } ...@@ -31,6 +33,7 @@ static inline void at91_pm_set_standby(void (*at91_standby)(void)) { }
* still in self-refresh is "not recommended", but seems to work. * still in self-refresh is "not recommended", but seems to work.
*/ */
#ifndef __ASSEMBLY__
static inline void at91rm9200_standby(void) static inline void at91rm9200_standby(void)
{ {
u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR); u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
...@@ -112,3 +115,4 @@ static inline void at91sam9_sdram_standby(void) ...@@ -112,3 +115,4 @@ static inline void at91sam9_sdram_standby(void)
} }
#endif #endif
#endif
...@@ -11,24 +11,16 @@ ...@@ -11,24 +11,16 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/at91_ramc.h> #include <mach/at91_ramc.h>
#include "pm.h"
/* #define SRAMC_SELF_FRESH_ACTIVE 0x01
* When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master #define SRAMC_SELF_FRESH_EXIT 0x00
* clock during suspend by adjusting its prescalar and divisor.
* NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
* are errata regarding adjusting the prescalar and divisor.
*/
#undef SLOWDOWN_MASTER_CLOCK
pmc .req r0 pmc .req r0
sdramc .req r1
ramc1 .req r2
memctrl .req r3
tmp1 .req r4 tmp1 .req r4
tmp2 .req r5 tmp2 .req r5
...@@ -60,111 +52,65 @@ tmp2 .req r5 ...@@ -60,111 +52,65 @@ tmp2 .req r5
.endm .endm
/* /*
* Wait until PLLB has locked. * Put the processor to enter the idle state
*/ */
.macro wait_pllblock .macro at91_cpu_idle
1: ldr tmp1, [pmc, #AT91_PMC_SR]
tst tmp1, #AT91_PMC_LOCKB #if defined(CONFIG_CPU_V7)
beq 1b mov tmp1, #AT91_PMC_PCK
str tmp1, [pmc, #AT91_PMC_SCDR]
dsb
wfi @ Wait For Interrupt
#else
mcr p15, 0, tmp1, c7, c0, 4
#endif
.endm .endm
.text .text
.arm .arm
/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, /*
* void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
* void __iomem *ramc1, int memctrl) * void __iomem *ramc1, int memctrl)
* @input param:
* @r0: base address of AT91_PMC
* @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
* @r2: base address of second SDRAM Controller or 0 if not present
* @r3: pm information
*/ */
ENTRY(at91_slow_clock) ENTRY(at91_pm_suspend_in_sram)
/* Save registers on stack */ /* Save registers on stack */
stmfd sp!, {r4 - r12, lr} stmfd sp!, {r4 - r12, lr}
/*
* Register usage:
* R0 = Base address of AT91_PMC
* R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
* R2 = Base address of second RAM Controller or 0 if not present
* R3 = Memory controller
* R4 = temporary register
* R5 = temporary register
*/
/* Drain write buffer */ /* Drain write buffer */
mov tmp1, #0 mov tmp1, #0
mcr p15, 0, tmp1, c7, c10, 4 mcr p15, 0, tmp1, c7, c10, 4
cmp memctrl, #AT91_MEMCTRL_MC str r0, .pmc_base
bne ddr_sr_enable str r1, .sramc_base
str r2, .sramc1_base
/* and r0, r3, #AT91_PM_MEMTYPE_MASK
* at91rm9200 Memory controller str r0, .memtype
*/
/* Put SDRAM in self-refresh mode */
mov tmp1, #1
str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
b sdr_sr_done
/* lsr r0, r3, #AT91_PM_MODE_OFFSET
* DDRSDR Memory controller and r0, r0, #AT91_PM_MODE_MASK
*/ str r0, .pm_mode
ddr_sr_enable:
cmp memctrl, #AT91_MEMCTRL_DDRSDR
bne sdr_sr_enable
/* LPDDR1 --> force DDR2 mode during self-refresh */ /* Active the self-refresh mode */
ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR] mov r0, #SRAMC_SELF_FRESH_ACTIVE
str tmp1, .saved_sam9_mdr bl at91_sramc_self_refresh
bic tmp1, tmp1, #~AT91_DDRSDRC_MD
cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
biceq tmp1, tmp1, #AT91_DDRSDRC_MD
orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
/* prepare for DDRAM self-refresh mode */
ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
str tmp1, .saved_sam9_lpr
bic tmp1, #AT91_DDRSDRC_LPCB
orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
/* figure out if we use the second ram controller */
cmp ramc1, #0
beq ddr_no_2nd_ctrl
ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
str tmp2, .saved_sam9_mdr1
bic tmp2, tmp2, #~AT91_DDRSDRC_MD
cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
biceq tmp2, tmp2, #AT91_DDRSDRC_MD
orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
str tmp2, .saved_sam9_lpr1
bic tmp2, #AT91_DDRSDRC_LPCB
orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
/* Enable DDRAM self-refresh mode */
str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
ddr_no_2nd_ctrl:
str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
b sdr_sr_done
/* ldr r0, .pm_mode
* SDRAMC Memory controller tst r0, #AT91_PM_SLOW_CLOCK
*/ beq skip_disable_main_clock
sdr_sr_enable:
/* Enable SDRAM self-refresh mode */
ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
str tmp1, .saved_sam9_lpr
bic tmp1, #AT91_SDRAMC_LPCB ldr pmc, .pmc_base
orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
str tmp1, [sdramc, #AT91_SDRAMC_LPR]
sdr_sr_done:
/* Save Master clock setting */ /* Save Master clock setting */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, #AT91_PMC_MCKR]
str tmp1, .saved_mckr str tmp1, .saved_mckr
...@@ -177,18 +123,6 @@ sdr_sr_done: ...@@ -177,18 +123,6 @@ sdr_sr_done:
wait_mckrdy wait_mckrdy
#ifdef SLOWDOWN_MASTER_CLOCK
/*
* Set the Master Clock PRES and MDIV fields.
*
* See AT91RM9200 errata #27 and #28 for details.
*/
mov tmp1, #0
str tmp1, [pmc, #AT91_PMC_MCKR]
wait_mckrdy
#endif
/* Save PLLA setting and disable it */ /* Save PLLA setting and disable it */
ldr tmp1, [pmc, #AT91_CKGR_PLLAR] ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
str tmp1, .saved_pllar str tmp1, .saved_pllar
...@@ -197,21 +131,23 @@ sdr_sr_done: ...@@ -197,21 +131,23 @@ sdr_sr_done:
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
str tmp1, [pmc, #AT91_CKGR_PLLAR] str tmp1, [pmc, #AT91_CKGR_PLLAR]
/* Save PLLB setting and disable it */
ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
str tmp1, .saved_pllbr
mov tmp1, #AT91_PMC_PLLCOUNT
str tmp1, [pmc, #AT91_CKGR_PLLBR]
/* Turn off the main oscillator */ /* Turn off the main oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR] ldr tmp1, [pmc, #AT91_CKGR_MOR]
bic tmp1, tmp1, #AT91_PMC_MOSCEN bic tmp1, tmp1, #AT91_PMC_MOSCEN
orr tmp1, tmp1, #AT91_PMC_KEY orr tmp1, tmp1, #AT91_PMC_KEY
str tmp1, [pmc, #AT91_CKGR_MOR] str tmp1, [pmc, #AT91_CKGR_MOR]
skip_disable_main_clock:
ldr pmc, .pmc_base
/* Wait for interrupt */ /* Wait for interrupt */
mcr p15, 0, tmp1, c7, c0, 4 at91_cpu_idle
ldr r0, .pm_mode
tst r0, #AT91_PM_SLOW_CLOCK
beq skip_enable_main_clock
ldr pmc, .pmc_base
/* Turn on the main oscillator */ /* Turn on the main oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR] ldr tmp1, [pmc, #AT91_CKGR_MOR]
...@@ -221,18 +157,6 @@ sdr_sr_done: ...@@ -221,18 +157,6 @@ sdr_sr_done:
wait_moscrdy wait_moscrdy
/* Restore PLLB setting */
ldr tmp1, .saved_pllbr
str tmp1, [pmc, #AT91_CKGR_PLLBR]
tst tmp1, #(AT91_PMC_MUL & 0xff0000)
bne 1f
tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
beq 2f
1:
wait_pllblock
2:
/* Restore PLLA setting */ /* Restore PLLA setting */
ldr tmp1, .saved_pllar ldr tmp1, .saved_pllar
str tmp1, [pmc, #AT91_CKGR_PLLAR] str tmp1, [pmc, #AT91_CKGR_PLLAR]
...@@ -245,91 +169,170 @@ sdr_sr_done: ...@@ -245,91 +169,170 @@ sdr_sr_done:
wait_pllalock wait_pllalock
4: 4:
#ifdef SLOWDOWN_MASTER_CLOCK
/* /*
* First set PRES if it was not 0, * Restore master clock setting
* than set CSS and MDIV fields.
*
* See AT91RM9200 errata #27 and #28 for details.
*/ */
ldr tmp1, .saved_mckr ldr tmp1, .saved_mckr
tst tmp1, #AT91_PMC_PRES
beq 2f
and tmp1, tmp1, #AT91_PMC_PRES
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, #AT91_PMC_MCKR]
wait_mckrdy wait_mckrdy
#endif
/* skip_enable_main_clock:
* Restore master clock setting /* Exit the self-refresh mode */
*/ mov r0, #SRAMC_SELF_FRESH_EXIT
2: ldr tmp1, .saved_mckr bl at91_sramc_self_refresh
str tmp1, [pmc, #AT91_PMC_MCKR]
wait_mckrdy /* Restore registers, and return */
ldmfd sp!, {r4 - r12, pc}
ENDPROC(at91_pm_suspend_in_sram)
/*
* void at91_sramc_self_refresh(unsigned int is_active)
*
* @input param:
* @r0: 1 - active self-refresh mode
* 0 - exit self-refresh mode
* register usage:
* @r1: memory type
* @r2: base address of the sram controller
*/
ENTRY(at91_sramc_self_refresh)
ldr r1, .memtype
ldr r2, .sramc_base
cmp r1, #AT91_MEMCTRL_MC
bne ddrc_sf
/* /*
* at91rm9200 Memory controller * at91rm9200 Memory controller
* Do nothing - self-refresh is automatically disabled.
*/ */
cmp memctrl, #AT91_MEMCTRL_MC
beq ram_restored /*
* For exiting the self-refresh mode, do nothing,
* automatically exit the self-refresh mode.
*/
tst r0, #SRAMC_SELF_FRESH_ACTIVE
beq exit_sramc_sf
/* Active SDRAM self-refresh mode */
mov r3, #1
str r3, [r2, #AT91RM9200_SDRAMC_SRR]
b exit_sramc_sf
ddrc_sf:
cmp r1, #AT91_MEMCTRL_DDRSDR
bne sdramc_sf
/* /*
* DDRSDR Memory controller * DDR Memory controller
*/ */
cmp memctrl, #AT91_MEMCTRL_DDRSDR tst r0, #SRAMC_SELF_FRESH_ACTIVE
bne sdr_en_restore beq ddrc_exit_sf
/* LPDDR1 --> force DDR2 mode during self-refresh */
ldr r3, [r2, #AT91_DDRSDRC_MDR]
str r3, .saved_sam9_mdr
bic r3, r3, #~AT91_DDRSDRC_MD
cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
ldreq r3, [r2, #AT91_DDRSDRC_MDR]
biceq r3, r3, #AT91_DDRSDRC_MD
orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
streq r3, [r2, #AT91_DDRSDRC_MDR]
/* Active DDRC self-refresh mode */
ldr r3, [r2, #AT91_DDRSDRC_LPR]
str r3, .saved_sam9_lpr
bic r3, r3, #AT91_DDRSDRC_LPCB
orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
str r3, [r2, #AT91_DDRSDRC_LPR]
/* If using the 2nd ddr controller */
ldr r2, .sramc1_base
cmp r2, #0
beq no_2nd_ddrc
ldr r3, [r2, #AT91_DDRSDRC_MDR]
str r3, .saved_sam9_mdr1
bic r3, r3, #~AT91_DDRSDRC_MD
cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
ldreq r3, [r2, #AT91_DDRSDRC_MDR]
biceq r3, r3, #AT91_DDRSDRC_MD
orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
streq r3, [r2, #AT91_DDRSDRC_MDR]
/* Active DDRC self-refresh mode */
ldr r3, [r2, #AT91_DDRSDRC_LPR]
str r3, .saved_sam9_lpr1
bic r3, r3, #AT91_DDRSDRC_LPCB
orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
str r3, [r2, #AT91_DDRSDRC_LPR]
no_2nd_ddrc:
b exit_sramc_sf
ddrc_exit_sf:
/* Restore MDR in case of LPDDR1 */ /* Restore MDR in case of LPDDR1 */
ldr tmp1, .saved_sam9_mdr ldr r3, .saved_sam9_mdr
str tmp1, [sdramc, #AT91_DDRSDRC_MDR] str r3, [r2, #AT91_DDRSDRC_MDR]
/* Restore LPR on AT91 with DDRAM */ /* Restore LPR on AT91 with DDRAM */
ldr tmp1, .saved_sam9_lpr ldr r3, .saved_sam9_lpr
str tmp1, [sdramc, #AT91_DDRSDRC_LPR] str r3, [r2, #AT91_DDRSDRC_LPR]
/* if we use the second ram controller */ /* If using the 2nd ddr controller */
cmp ramc1, #0 ldr r2, .sramc1_base
ldrne tmp2, .saved_sam9_mdr1 cmp r2, #0
strne tmp2, [ramc1, #AT91_DDRSDRC_MDR] ldrne r3, .saved_sam9_mdr1
ldrne tmp2, .saved_sam9_lpr1 strne r3, [r2, #AT91_DDRSDRC_MDR]
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] ldrne r3, .saved_sam9_lpr1
strne r3, [r2, #AT91_DDRSDRC_LPR]
b ram_restored b exit_sramc_sf
/* /*
* SDRAMC Memory controller * SDRAMC Memory controller
*/ */
sdr_en_restore: sdramc_sf:
/* Restore LPR on AT91 with SDRAM */ tst r0, #SRAMC_SELF_FRESH_ACTIVE
ldr tmp1, .saved_sam9_lpr beq sdramc_exit_sf
str tmp1, [sdramc, #AT91_SDRAMC_LPR]
/* Active SDRAMC self-refresh mode */
ram_restored: ldr r3, [r2, #AT91_SDRAMC_LPR]
/* Restore registers, and return */ str r3, .saved_sam9_lpr
ldmfd sp!, {r4 - r12, pc} bic r3, r3, #AT91_SDRAMC_LPCB
orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
str r3, [r2, #AT91_SDRAMC_LPR]
sdramc_exit_sf:
ldr r3, .saved_sam9_lpr
str r3, [r2, #AT91_SDRAMC_LPR]
exit_sramc_sf:
mov pc, lr
ENDPROC(at91_sramc_self_refresh)
.pmc_base:
.word 0
.sramc_base:
.word 0
.sramc1_base:
.word 0
.memtype:
.word 0
.pm_mode:
.word 0
.saved_mckr: .saved_mckr:
.word 0 .word 0
.saved_pllar: .saved_pllar:
.word 0 .word 0
.saved_pllbr:
.word 0
.saved_sam9_lpr: .saved_sam9_lpr:
.word 0 .word 0
.saved_sam9_lpr1: .saved_sam9_lpr1:
.word 0 .word 0
.saved_sam9_mdr: .saved_sam9_mdr:
.word 0 .word 0
.saved_sam9_mdr1: .saved_sam9_mdr1:
.word 0 .word 0
ENTRY(at91_slow_clock_sz) ENTRY(at91_pm_suspend_in_sram_sz)
.word .-at91_slow_clock .word .-at91_pm_suspend_in_sram
...@@ -7,48 +7,50 @@ ...@@ -7,48 +7,50 @@
* Licensed under GPLv2 or later. * Licensed under GPLv2 or later.
*/ */
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/micrel_phy.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/clk-provider.h>
#include <linux/phy.h>
#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h> #include <asm/system_misc.h>
#include "generic.h"
static int ksz8081_phy_fixup(struct phy_device *phy) #include <mach/hardware.h>
{
int value;
value = phy_read(phy, 0x16); #include "generic.h"
value &= ~0x20; #include "soc.h"
phy_write(phy, 0x16, value);
return 0; static const struct at91_soc sama5_socs[] = {
} AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH,
"sama5d31", "sama5d3"),
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH,
"sama5d33", "sama5d3"),
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH,
"sama5d34", "sama5d3"),
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH,
"sama5d35", "sama5d3"),
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH,
"sama5d36", "sama5d3"),
AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH,
"sama5d41", "sama5d4"),
AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH,
"sama5d42", "sama5d4"),
AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH,
"sama5d43", "sama5d4"),
AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH,
"sama5d44", "sama5d4"),
{ /* sentinel */ },
};
static void __init sama5_dt_device_init(void) static void __init sama5_dt_device_init(void)
{ {
if (of_machine_is_compatible("atmel,sama5d4ek") && struct soc_device *soc;
IS_ENABLED(CONFIG_PHYLIB)) { struct device *soc_dev = NULL;
phy_register_fixup_for_id("fc028000.etherne:00",
ksz8081_phy_fixup); soc = at91_soc_init(sama5_socs);
} if (soc != NULL)
soc_dev = soc_device_to_device(soc);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
at91sam9x5_pm_init(); at91sam9x5_pm_init();
} }
...@@ -59,44 +61,10 @@ static const char *sama5_dt_board_compat[] __initconst = { ...@@ -59,44 +61,10 @@ static const char *sama5_dt_board_compat[] __initconst = {
DT_MACHINE_START(sama5_dt, "Atmel SAMA5") DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.map_io = at91_map_io,
.init_machine = sama5_dt_device_init, .init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat, .dt_compat = sama5_dt_board_compat,
MACHINE_END MACHINE_END
static struct map_desc at91_io_desc[] __initdata = {
{
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
.pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
.length = SZ_512,
.type = MT_DEVICE,
},
{
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
.pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
.length = SZ_512,
.type = MT_DEVICE,
},
{ /* On sama5d4, we use USART3 as serial console */
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
.pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
.length = SZ_256,
.type = MT_DEVICE,
},
{ /* A bunch of peripheral with fine grained IO space */
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
.pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
.length = SZ_2K,
.type = MT_DEVICE,
},
};
static void __init sama5_alt_map_io(void)
{
at91_alt_map_io();
iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
}
static const char *sama5_alt_dt_board_compat[] __initconst = { static const char *sama5_alt_dt_board_compat[] __initconst = {
"atmel,sama5d4", "atmel,sama5d4",
NULL NULL
...@@ -104,7 +72,6 @@ static const char *sama5_alt_dt_board_compat[] __initconst = { ...@@ -104,7 +72,6 @@ static const char *sama5_alt_dt_board_compat[] __initconst = {
DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.map_io = sama5_alt_map_io,
.init_machine = sama5_dt_device_init, .init_machine = sama5_dt_device_init,
.dt_compat = sama5_alt_dt_board_compat, .dt_compat = sama5_alt_dt_board_compat,
.l2c_aux_mask = ~0UL, .l2c_aux_mask = ~0UL,
......
/*
* Copyright (C) 2007 Atmel Corporation.
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* Under GPLv2
*/
#define pr_fmt(fmt) "AT91: " fmt
#include <linux/module.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/of_address.h>
#include <linux/pinctrl/machine.h>
#include <linux/clk/at91_pmc.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include "generic.h"
#include "pm.h"
struct at91_socinfo at91_soc_initdata;
EXPORT_SYMBOL(at91_soc_initdata);
static struct map_desc at91_io_desc __initdata __maybe_unused = {
.virtual = (unsigned long)AT91_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_BASE_SYS),
.length = SZ_16K,
.type = MT_DEVICE,
};
static struct map_desc at91_alt_io_desc __initdata __maybe_unused = {
.virtual = (unsigned long)AT91_ALT_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_ALT_BASE_SYS),
.length = 24 * SZ_1K,
.type = MT_DEVICE,
};
static void __init soc_detect(u32 dbgu_base)
{
u32 cidr, socid;
cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
socid = cidr & ~AT91_CIDR_VERSION;
switch (socid) {
case ARCH_ID_AT91RM9200:
at91_soc_initdata.type = AT91_SOC_RM9200;
if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_UNKNOWN)
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
break;
case ARCH_ID_AT91SAM9260:
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
break;
case ARCH_ID_AT91SAM9261:
at91_soc_initdata.type = AT91_SOC_SAM9261;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
break;
case ARCH_ID_AT91SAM9263:
at91_soc_initdata.type = AT91_SOC_SAM9263;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
break;
case ARCH_ID_AT91SAM9G20:
at91_soc_initdata.type = AT91_SOC_SAM9G20;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
break;
case ARCH_ID_AT91SAM9G45:
at91_soc_initdata.type = AT91_SOC_SAM9G45;
if (cidr == ARCH_ID_AT91SAM9G45ES)
at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
break;
case ARCH_ID_AT91SAM9RL64:
at91_soc_initdata.type = AT91_SOC_SAM9RL;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
break;
case ARCH_ID_AT91SAM9X5:
at91_soc_initdata.type = AT91_SOC_SAM9X5;
break;
case ARCH_ID_AT91SAM9N12:
at91_soc_initdata.type = AT91_SOC_SAM9N12;
break;
case ARCH_ID_SAMA5:
at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
}
break;
}
/* at91sam9g10 */
if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
at91_soc_initdata.type = AT91_SOC_SAM9G10;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
}
/* at91sam9xe */
else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
}
if (!at91_soc_is_detected())
return;
at91_soc_initdata.cidr = cidr;
/* sub version of soc */
if (!at91_soc_initdata.exid)
at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
switch (at91_soc_initdata.exid) {
case ARCH_EXID_AT91SAM9M10:
at91_soc_initdata.subtype = AT91_SOC_SAM9M10;
break;
case ARCH_EXID_AT91SAM9G46:
at91_soc_initdata.subtype = AT91_SOC_SAM9G46;
break;
case ARCH_EXID_AT91SAM9M11:
at91_soc_initdata.subtype = AT91_SOC_SAM9M11;
break;
}
}
if (at91_soc_initdata.type == AT91_SOC_SAM9X5) {
switch (at91_soc_initdata.exid) {
case ARCH_EXID_AT91SAM9G15:
at91_soc_initdata.subtype = AT91_SOC_SAM9G15;
break;
case ARCH_EXID_AT91SAM9G35:
at91_soc_initdata.subtype = AT91_SOC_SAM9G35;
break;
case ARCH_EXID_AT91SAM9X35:
at91_soc_initdata.subtype = AT91_SOC_SAM9X35;
break;
case ARCH_EXID_AT91SAM9G25:
at91_soc_initdata.subtype = AT91_SOC_SAM9G25;
break;
case ARCH_EXID_AT91SAM9X25:
at91_soc_initdata.subtype = AT91_SOC_SAM9X25;
break;
}
}
if (at91_soc_initdata.type == AT91_SOC_SAMA5D3) {
switch (at91_soc_initdata.exid) {
case ARCH_EXID_SAMA5D31:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D31;
break;
case ARCH_EXID_SAMA5D33:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D33;
break;
case ARCH_EXID_SAMA5D34:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D34;
break;
case ARCH_EXID_SAMA5D35:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D35;
break;
case ARCH_EXID_SAMA5D36:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D36;
break;
}
}
}
static void __init alt_soc_detect(u32 dbgu_base)
{
u32 cidr, socid;
/* SoC ID */
cidr = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
socid = cidr & ~AT91_CIDR_VERSION;
switch (socid) {
case ARCH_ID_SAMA5:
at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
} else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
at91_soc_initdata.type = AT91_SOC_SAMA5D4;
}
break;
}
if (!at91_soc_is_detected())
return;
at91_soc_initdata.cidr = cidr;
/* sub version of soc */
if (!at91_soc_initdata.exid)
at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) {
switch (at91_soc_initdata.exid) {
case ARCH_EXID_SAMA5D41:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D41;
break;
case ARCH_EXID_SAMA5D42:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D42;
break;
case ARCH_EXID_SAMA5D43:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D43;
break;
case ARCH_EXID_SAMA5D44:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D44;
break;
}
}
}
static const char *soc_name[] = {
[AT91_SOC_RM9200] = "at91rm9200",
[AT91_SOC_SAM9260] = "at91sam9260",
[AT91_SOC_SAM9261] = "at91sam9261",
[AT91_SOC_SAM9263] = "at91sam9263",
[AT91_SOC_SAM9G10] = "at91sam9g10",
[AT91_SOC_SAM9G20] = "at91sam9g20",
[AT91_SOC_SAM9G45] = "at91sam9g45",
[AT91_SOC_SAM9RL] = "at91sam9rl",
[AT91_SOC_SAM9X5] = "at91sam9x5",
[AT91_SOC_SAM9N12] = "at91sam9n12",
[AT91_SOC_SAMA5D3] = "sama5d3",
[AT91_SOC_SAMA5D4] = "sama5d4",
[AT91_SOC_UNKNOWN] = "Unknown",
};
const char *at91_get_soc_type(struct at91_socinfo *c)
{
return soc_name[c->type];
}
EXPORT_SYMBOL(at91_get_soc_type);
static const char *soc_subtype_name[] = {
[AT91_SOC_RM9200_BGA] = "at91rm9200 BGA",
[AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP",
[AT91_SOC_SAM9XE] = "at91sam9xe",
[AT91_SOC_SAM9G45ES] = "at91sam9g45es",
[AT91_SOC_SAM9M10] = "at91sam9m10",
[AT91_SOC_SAM9G46] = "at91sam9g46",
[AT91_SOC_SAM9M11] = "at91sam9m11",
[AT91_SOC_SAM9G15] = "at91sam9g15",
[AT91_SOC_SAM9G35] = "at91sam9g35",
[AT91_SOC_SAM9X35] = "at91sam9x35",
[AT91_SOC_SAM9G25] = "at91sam9g25",
[AT91_SOC_SAM9X25] = "at91sam9x25",
[AT91_SOC_SAMA5D31] = "sama5d31",
[AT91_SOC_SAMA5D33] = "sama5d33",
[AT91_SOC_SAMA5D34] = "sama5d34",
[AT91_SOC_SAMA5D35] = "sama5d35",
[AT91_SOC_SAMA5D36] = "sama5d36",
[AT91_SOC_SAMA5D41] = "sama5d41",
[AT91_SOC_SAMA5D42] = "sama5d42",
[AT91_SOC_SAMA5D43] = "sama5d43",
[AT91_SOC_SAMA5D44] = "sama5d44",
[AT91_SOC_SUBTYPE_NONE] = "None",
[AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
};
const char *at91_get_soc_subtype(struct at91_socinfo *c)
{
return soc_subtype_name[c->subtype];
}
EXPORT_SYMBOL(at91_get_soc_subtype);
void __init at91_map_io(void)
{
/* Map peripherals */
iotable_init(&at91_io_desc, 1);
at91_soc_initdata.type = AT91_SOC_UNKNOWN;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
soc_detect(AT91_BASE_DBGU0);
if (!at91_soc_is_detected())
soc_detect(AT91_BASE_DBGU1);
if (!at91_soc_is_detected())
panic(pr_fmt("Impossible to detect the SOC type"));
pr_info("Detected soc type: %s\n",
at91_get_soc_type(&at91_soc_initdata));
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
}
void __init at91_alt_map_io(void)
{
/* Map peripherals */
iotable_init(&at91_alt_io_desc, 1);
at91_soc_initdata.type = AT91_SOC_UNKNOWN;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
alt_soc_detect(AT91_BASE_DBGU2);
if (!at91_soc_is_detected())
panic("AT91: Impossible to detect the SOC type");
pr_info("AT91: Detected soc type: %s\n",
at91_get_soc_type(&at91_soc_initdata));
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("AT91: Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
}
void __iomem *at91_matrix_base;
EXPORT_SYMBOL_GPL(at91_matrix_base);
void __init at91_ioremap_matrix(u32 base_addr)
{
at91_matrix_base = ioremap(base_addr, 512);
if (!at91_matrix_base)
panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
}
/*
* Copyright (C) 2015 Atmel
*
* Alexandre Belloni <alexandre.belloni@free-electrons.com
* Boris Brezillon <boris.brezillon@free-electrons.com
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
*/
#define pr_fmt(fmt) "AT91: " fmt
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include "soc.h"
#define AT91_DBGU_CIDR 0x40
#define AT91_DBGU_CIDR_VERSION(x) ((x) & 0x1f)
#define AT91_DBGU_CIDR_EXT BIT(31)
#define AT91_DBGU_CIDR_MATCH_MASK 0x7fffffe0
#define AT91_DBGU_EXID 0x44
struct soc_device * __init at91_soc_init(const struct at91_soc *socs)
{
struct soc_device_attribute *soc_dev_attr;
const struct at91_soc *soc;
struct soc_device *soc_dev;
struct device_node *np;
void __iomem *regs;
u32 cidr, exid;
np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-dbgu");
if (!np)
np = of_find_compatible_node(NULL, NULL,
"atmel,at91sam9260-dbgu");
if (!np) {
pr_warn("Could not find DBGU node");
return NULL;
}
regs = of_iomap(np, 0);
of_node_put(np);
if (!regs) {
pr_warn("Could not map DBGU iomem range");
return NULL;
}
cidr = readl(regs + AT91_DBGU_CIDR);
exid = readl(regs + AT91_DBGU_EXID);
iounmap(regs);
for (soc = socs; soc->name; soc++) {
if (soc->cidr_match != (cidr & AT91_DBGU_CIDR_MATCH_MASK))
continue;
if (!(cidr & AT91_DBGU_CIDR_EXT) || soc->exid_match == exid)
break;
}
if (!soc->name) {
pr_warn("Could not find matching SoC description\n");
return NULL;
}
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr)
return NULL;
soc_dev_attr->family = soc->family;
soc_dev_attr->soc_id = soc->name;
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X",
AT91_DBGU_CIDR_VERSION(cidr));
soc_dev = soc_device_register(soc_dev_attr);
if (IS_ERR(soc_dev)) {
kfree(soc_dev_attr->revision);
kfree(soc_dev_attr);
pr_warn("Could not register SoC device\n");
return NULL;
}
if (soc->family)
pr_info("Detected SoC family: %s\n", soc->family);
pr_info("Detected SoC: %s, revision %X\n", soc->name,
AT91_DBGU_CIDR_VERSION(cidr));
return soc_dev;
}
/*
* Copyright (C) 2015 Atmel
*
* Boris Brezillon <boris.brezillon@free-electrons.com
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
*/
#ifndef __AT91_SOC_H
#define __AT91_SOC_H
#include <linux/sys_soc.h>
struct at91_soc {
u32 cidr_match;
u32 exid_match;
const char *name;
const char *family;
};
#define AT91_SOC(__cidr, __exid, __name, __family) \
{ \
.cidr_match = (__cidr), \
.exid_match = (__exid), \
.name = (__name), \
.family = (__family), \
}
struct soc_device * __init
at91_soc_init(const struct at91_soc *socs);
#define AT91RM9200_CIDR_MATCH 0x09290780
#define AT91SAM9260_CIDR_MATCH 0x019803a0
#define AT91SAM9261_CIDR_MATCH 0x019703a0
#define AT91SAM9263_CIDR_MATCH 0x019607a0
#define AT91SAM9G20_CIDR_MATCH 0x019905a0
#define AT91SAM9RL64_CIDR_MATCH 0x019b03a0
#define AT91SAM9G45_CIDR_MATCH 0x019b05a0
#define AT91SAM9X5_CIDR_MATCH 0x019a05a0
#define AT91SAM9N12_CIDR_MATCH 0x019a07a0
#define AT91SAM9M11_EXID_MATCH 0x00000001
#define AT91SAM9M10_EXID_MATCH 0x00000002
#define AT91SAM9G46_EXID_MATCH 0x00000003
#define AT91SAM9G45_EXID_MATCH 0x00000004
#define AT91SAM9G15_EXID_MATCH 0x00000000
#define AT91SAM9G35_EXID_MATCH 0x00000001
#define AT91SAM9X35_EXID_MATCH 0x00000002
#define AT91SAM9G25_EXID_MATCH 0x00000003
#define AT91SAM9X25_EXID_MATCH 0x00000004
#define AT91SAM9CN12_EXID_MATCH 0x00000005
#define AT91SAM9N12_EXID_MATCH 0x00000006
#define AT91SAM9CN11_EXID_MATCH 0x00000009
#define AT91SAM9XE128_CIDR_MATCH 0x329973a0
#define AT91SAM9XE256_CIDR_MATCH 0x329a93a0
#define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0
#define SAMA5D3_CIDR_MATCH 0x0a5c07c0
#define SAMA5D31_EXID_MATCH 0x00444300
#define SAMA5D33_EXID_MATCH 0x00414300
#define SAMA5D34_EXID_MATCH 0x00414301
#define SAMA5D35_EXID_MATCH 0x00584300
#define SAMA5D36_EXID_MATCH 0x00004301
#define SAMA5D4_CIDR_MATCH 0x0a5c07c0
#define SAMA5D41_EXID_MATCH 0x00000001
#define SAMA5D42_EXID_MATCH 0x00000002
#define SAMA5D43_EXID_MATCH 0x00000003
#define SAMA5D44_EXID_MATCH 0x00000004
#endif /* __AT91_SOC_H */
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
/* Bases of da830 McASP1 register banks */ /* Bases of da830 McASP1 register banks */
#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000 #define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000
/* Bases of da830 McASP2 register banks */
#define DAVINCI_DA830_MCASP2_REG_BASE 0x01D08000
/* EDMA channels of dm644x and dm355 */ /* EDMA channels of dm644x and dm355 */
#define DAVINCI_DMA_ASP0_TX 2 #define DAVINCI_DMA_ASP0_TX 2
#define DAVINCI_DMA_ASP0_RX 3 #define DAVINCI_DMA_ASP0_RX 3
...@@ -40,6 +43,10 @@ ...@@ -40,6 +43,10 @@
#define DAVINCI_DA830_DMA_MCASP1_AREVT 2 #define DAVINCI_DA830_DMA_MCASP1_AREVT 2
#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3 #define DAVINCI_DA830_DMA_MCASP1_AXEVT 3
/* EDMA channels of da830 McASP2 */
#define DAVINCI_DA830_DMA_MCASP2_AREVT 4
#define DAVINCI_DA830_DMA_MCASP2_AXEVT 5
/* Interrupts */ /* Interrupts */
#define DAVINCI_ASP0_RX_INT IRQ_MBRINT #define DAVINCI_ASP0_RX_INT IRQ_MBRINT
#define DAVINCI_ASP0_TX_INT IRQ_MBXINT #define DAVINCI_ASP0_TX_INT IRQ_MBXINT
......
...@@ -463,16 +463,23 @@ static struct resource da830_mcasp1_resources[] = { ...@@ -463,16 +463,23 @@ static struct resource da830_mcasp1_resources[] = {
}, },
/* TX event */ /* TX event */
{ {
.name = "tx",
.start = DAVINCI_DA830_DMA_MCASP1_AXEVT, .start = DAVINCI_DA830_DMA_MCASP1_AXEVT,
.end = DAVINCI_DA830_DMA_MCASP1_AXEVT, .end = DAVINCI_DA830_DMA_MCASP1_AXEVT,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
/* RX event */ /* RX event */
{ {
.name = "rx",
.start = DAVINCI_DA830_DMA_MCASP1_AREVT, .start = DAVINCI_DA830_DMA_MCASP1_AREVT,
.end = DAVINCI_DA830_DMA_MCASP1_AREVT, .end = DAVINCI_DA830_DMA_MCASP1_AREVT,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
{
.name = "common",
.start = IRQ_DA8XX_MCASPINT,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device da830_mcasp1_device = { static struct platform_device da830_mcasp1_device = {
...@@ -482,6 +489,41 @@ static struct platform_device da830_mcasp1_device = { ...@@ -482,6 +489,41 @@ static struct platform_device da830_mcasp1_device = {
.resource = da830_mcasp1_resources, .resource = da830_mcasp1_resources,
}; };
static struct resource da830_mcasp2_resources[] = {
{
.name = "mpu",
.start = DAVINCI_DA830_MCASP2_REG_BASE,
.end = DAVINCI_DA830_MCASP2_REG_BASE + (SZ_1K * 12) - 1,
.flags = IORESOURCE_MEM,
},
/* TX event */
{
.name = "tx",
.start = DAVINCI_DA830_DMA_MCASP2_AXEVT,
.end = DAVINCI_DA830_DMA_MCASP2_AXEVT,
.flags = IORESOURCE_DMA,
},
/* RX event */
{
.name = "rx",
.start = DAVINCI_DA830_DMA_MCASP2_AREVT,
.end = DAVINCI_DA830_DMA_MCASP2_AREVT,
.flags = IORESOURCE_DMA,
},
{
.name = "common",
.start = IRQ_DA8XX_MCASPINT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device da830_mcasp2_device = {
.name = "davinci-mcasp",
.id = 2,
.num_resources = ARRAY_SIZE(da830_mcasp2_resources),
.resource = da830_mcasp2_resources,
};
static struct resource da850_mcasp_resources[] = { static struct resource da850_mcasp_resources[] = {
{ {
.name = "mpu", .name = "mpu",
...@@ -491,16 +533,23 @@ static struct resource da850_mcasp_resources[] = { ...@@ -491,16 +533,23 @@ static struct resource da850_mcasp_resources[] = {
}, },
/* TX event */ /* TX event */
{ {
.name = "tx",
.start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
.end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
/* RX event */ /* RX event */
{ {
.name = "rx",
.start = DAVINCI_DA8XX_DMA_MCASP0_AREVT, .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
.end = DAVINCI_DA8XX_DMA_MCASP0_AREVT, .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
{
.name = "common",
.start = IRQ_DA8XX_MCASPINT,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device da850_mcasp_device = { static struct platform_device da850_mcasp_device = {
...@@ -512,14 +561,31 @@ static struct platform_device da850_mcasp_device = { ...@@ -512,14 +561,31 @@ static struct platform_device da850_mcasp_device = {
void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata) void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
{ {
/* DA830/OMAP-L137 has 3 instances of McASP */ struct platform_device *pdev;
if (cpu_is_davinci_da830() && id == 1) {
da830_mcasp1_device.dev.platform_data = pdata; switch (id) {
platform_device_register(&da830_mcasp1_device); case 0:
} else if (cpu_is_davinci_da850()) { /* Valid for DA830/OMAP-L137 or DA850/OMAP-L138 */
da850_mcasp_device.dev.platform_data = pdata; pdev = &da850_mcasp_device;
platform_device_register(&da850_mcasp_device); break;
case 1:
/* Valid for DA830/OMAP-L137 only */
if (!cpu_is_davinci_da830())
return;
pdev = &da830_mcasp1_device;
break;
case 2:
/* Valid for DA830/OMAP-L137 only */
if (!cpu_is_davinci_da830())
return;
pdev = &da830_mcasp2_device;
break;
default:
return;
} }
pdev->dev.platform_data = pdata;
platform_device_register(pdev);
} }
static struct resource da8xx_pruss_resources[] = { static struct resource da8xx_pruss_resources[] = {
......
...@@ -493,7 +493,6 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { ...@@ -493,7 +493,6 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
[IRQ_DM646X_EMACMISCINT] = 7, [IRQ_DM646X_EMACMISCINT] = 7,
[IRQ_DM646X_MCASP0TXINT] = 7, [IRQ_DM646X_MCASP0TXINT] = 7,
[IRQ_DM646X_MCASP0RXINT] = 7, [IRQ_DM646X_MCASP0RXINT] = 7,
[IRQ_AEMIFINT] = 7,
[IRQ_DM646X_RESERVED_3] = 7, [IRQ_DM646X_RESERVED_3] = 7,
[IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */
[IRQ_TINT0_TINT34] = 7, /* clocksource */ [IRQ_TINT0_TINT34] = 7, /* clocksource */
...@@ -610,19 +609,31 @@ static struct resource dm646x_mcasp0_resources[] = { ...@@ -610,19 +609,31 @@ static struct resource dm646x_mcasp0_resources[] = {
.end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1, .end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
/* first TX, then RX */
{ {
.name = "tx",
.start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0, .start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
.end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0, .end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
{ {
.name = "rx",
.start = DAVINCI_DM646X_DMA_MCASP0_AREVT0, .start = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
.end = DAVINCI_DM646X_DMA_MCASP0_AREVT0, .end = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
{
.name = "tx",
.start = IRQ_DM646X_MCASP0TXINT,
.flags = IORESOURCE_IRQ,
},
{
.name = "rx",
.start = IRQ_DM646X_MCASP0RXINT,
.flags = IORESOURCE_IRQ,
},
}; };
/* DIT mode only, rx is not supported */
static struct resource dm646x_mcasp1_resources[] = { static struct resource dm646x_mcasp1_resources[] = {
{ {
.name = "mpu", .name = "mpu",
...@@ -630,17 +641,16 @@ static struct resource dm646x_mcasp1_resources[] = { ...@@ -630,17 +641,16 @@ static struct resource dm646x_mcasp1_resources[] = {
.end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1, .end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
/* DIT mode, only TX event */
{ {
.name = "tx",
.start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1, .start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
.end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1, .end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
/* DIT mode, dummy entry */
{ {
.start = -1, .name = "tx",
.end = -1, .start = IRQ_DM646X_MCASP1TXINT,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_IRQ,
}, },
}; };
......
...@@ -129,8 +129,8 @@ ...@@ -129,8 +129,8 @@
#define IRQ_DM646X_EMACMISCINT 27 #define IRQ_DM646X_EMACMISCINT 27
#define IRQ_DM646X_MCASP0TXINT 28 #define IRQ_DM646X_MCASP0TXINT 28
#define IRQ_DM646X_MCASP0RXINT 29 #define IRQ_DM646X_MCASP0RXINT 29
#define IRQ_DM646X_MCASP1TXINT 30
#define IRQ_DM646X_RESERVED_3 31 #define IRQ_DM646X_RESERVED_3 31
#define IRQ_DM646X_MCASP1TXINT 32
#define IRQ_DM646X_VLQINT 38 #define IRQ_DM646X_VLQINT 38
#define IRQ_DM646X_UARTINT2 42 #define IRQ_DM646X_UARTINT2 42
#define IRQ_DM646X_SPINT0 43 #define IRQ_DM646X_SPINT0 43
......
...@@ -77,13 +77,6 @@ config SOC_IMX21 ...@@ -77,13 +77,6 @@ config SOC_IMX21
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
config SOC_IMX25
bool
select ARCH_MXC_IOMUX_V3
select CPU_ARM926T
select MXC_AVIC
select PINCTRL_IMX25
config SOC_IMX27 config SOC_IMX27
bool bool
select CPU_ARM926T select CPU_ARM926T
...@@ -149,62 +142,6 @@ config MACH_MX21ADS ...@@ -149,62 +142,6 @@ config MACH_MX21ADS
Include support for MX21ADS platform. This includes specific Include support for MX21ADS platform. This includes specific
configurations for the board and its peripherals. configurations for the board and its peripherals.
comment "MX25 platforms:"
config MACH_MX25_3DS
bool "Support MX25PDK (3DS) Platform"
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMXDI_RTC
select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select SOC_IMX25
config MACH_EUKREA_CPUIMX25SD
bool "Support Eukrea CPUIMX25 Platform"
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMXDI_RTC
select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select USB_ULPI_VIEWPORT if USB_ULPI
select SOC_IMX25
choice
prompt "Baseboard"
depends on MACH_EUKREA_CPUIMX25SD
default MACH_EUKREA_MBIMXSD25_BASEBOARD
config MACH_EUKREA_MBIMXSD25_BASEBOARD
bool "Eukrea MBIMXSD development board"
select IMX_HAVE_PLATFORM_GPIO_KEYS
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_SPI_IMX
select LEDS_GPIO_REGISTER
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
endchoice
config MACH_IMX25_DT
bool "Support i.MX25 platforms from device tree"
select SOC_IMX25
help
Include support for Freescale i.MX25 based platforms
using the device tree for discovery
comment "MX27 platforms:" comment "MX27 platforms:"
config MACH_MX27ADS config MACH_MX27ADS
...@@ -557,6 +494,20 @@ config MACH_VPR200 ...@@ -557,6 +494,20 @@ config MACH_VPR200
endif endif
if ARCH_MULTI_V5
comment "Device tree only"
config SOC_IMX25
bool "i.MX25 support"
select ARCH_MXC_IOMUX_V3
select CPU_ARM926T
select MXC_AVIC
select PINCTRL_IMX25
help
This enables support for Freescale i.MX25 processor
endif
if ARCH_MULTI_V7 if ARCH_MULTI_V7
comment "Device tree only" comment "Device tree only"
...@@ -637,7 +588,7 @@ config SOC_VF610 ...@@ -637,7 +588,7 @@ config SOC_VF610
select PL310_ERRATA_769419 if CACHE_L2X0 select PL310_ERRATA_769419 if CACHE_L2X0
help help
This enable support for Freescale Vybrid VF610 processor. This enables support for Freescale Vybrid VF610 processor.
choice choice
prompt "Clocksource for scheduler clock" prompt "Clocksource for scheduler clock"
...@@ -667,7 +618,7 @@ config SOC_LS1021A ...@@ -667,7 +618,7 @@ config SOC_LS1021A
select ZONE_DMA if ARM_LPAE select ZONE_DMA if ARM_LPAE
help help
This enable support for Freescale LS1021A processor. This enables support for Freescale LS1021A processor.
endif endif
......
...@@ -3,7 +3,7 @@ obj-y := time.o cpu.o system.o irq-common.o ...@@ -3,7 +3,7 @@ obj-y := time.o cpu.o system.o irq-common.o
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o
obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
...@@ -48,12 +48,6 @@ obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o ...@@ -48,12 +48,6 @@ obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o
# i.MX21 based machines # i.MX21 based machines
obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
# i.MX25 based machines
obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o
obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o
# i.MX27 based machines # i.MX27 based machines
obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "clk.h" #include "clk.h"
#include "common.h" #include "common.h"
#include "hardware.h" #include "hardware.h"
#include "mx25.h"
#define CCM_MPCTL 0x00 #define CCM_MPCTL 0x00
#define CCM_UPCTL 0x04 #define CCM_UPCTL 0x04
...@@ -239,80 +238,6 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, ...@@ -239,80 +238,6 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
return 0; return 0;
} }
int __init mx25_clocks_init(void)
{
void __iomem *ccm;
ccm = ioremap(MX25_CRM_BASE_ADDR, SZ_16K);
__mx25_clocks_init(24000000, ccm);
clk_register_clkdev(clk[gpt1_ipg], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
/* i.mx25 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
clk_register_clkdev(clk[uart2_ipg], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.1");
clk_register_clkdev(clk[uart3_ipg], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.2");
clk_register_clkdev(clk[uart4_ipg], "ipg", "imx21-uart.3");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.1");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0");
/* i.mx25 has the i.mx35 type cspi */
clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2");
clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.0");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.1");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.2");
clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0");
clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0");
clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0");
clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx21-fb.0");
clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx21-fb.0");
clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx21-fb.0");
clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1");
clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[csi_ipg_per], "per", "imx25-camera.0");
clk_register_clkdev(clk[csi_ipg], "ipg", "imx25-camera.0");
clk_register_clkdev(clk[csi_ahb], "ahb", "imx25-camera.0");
clk_register_clkdev(clk[dummy], "audmux", NULL);
clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0");
clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1");
/* i.mx25 has the i.mx35 type sdma */
clk_register_clkdev(clk[sdma_ipg], "ipg", "imx35-sdma");
clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
clk_register_clkdev(clk[iim_ipg], "iim", NULL);
mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
return 0;
}
static void __init mx25_clocks_init_dt(struct device_node *np) static void __init mx25_clocks_init_dt(struct device_node *np)
{ {
struct device_node *refnp; struct device_node *refnp;
......
...@@ -23,13 +23,11 @@ struct of_device_id; ...@@ -23,13 +23,11 @@ struct of_device_id;
void mx1_map_io(void); void mx1_map_io(void);
void mx21_map_io(void); void mx21_map_io(void);
void mx25_map_io(void);
void mx27_map_io(void); void mx27_map_io(void);
void mx31_map_io(void); void mx31_map_io(void);
void mx35_map_io(void); void mx35_map_io(void);
void imx1_init_early(void); void imx1_init_early(void);
void imx21_init_early(void); void imx21_init_early(void);
void imx25_init_early(void);
void imx27_init_early(void); void imx27_init_early(void);
void imx31_init_early(void); void imx31_init_early(void);
void imx35_init_early(void); void imx35_init_early(void);
...@@ -37,13 +35,11 @@ void mxc_init_irq(void __iomem *); ...@@ -37,13 +35,11 @@ void mxc_init_irq(void __iomem *);
void tzic_init_irq(void); void tzic_init_irq(void);
void mx1_init_irq(void); void mx1_init_irq(void);
void mx21_init_irq(void); void mx21_init_irq(void);
void mx25_init_irq(void);
void mx27_init_irq(void); void mx27_init_irq(void);
void mx31_init_irq(void); void mx31_init_irq(void);
void mx35_init_irq(void); void mx35_init_irq(void);
void imx1_soc_init(void); void imx1_soc_init(void);
void imx21_soc_init(void); void imx21_soc_init(void);
void imx25_soc_init(void);
void imx27_soc_init(void); void imx27_soc_init(void);
void imx31_soc_init(void); void imx31_soc_init(void);
void imx35_soc_init(void); void imx35_soc_init(void);
...@@ -51,7 +47,6 @@ void epit_timer_init(void __iomem *base, int irq); ...@@ -51,7 +47,6 @@ void epit_timer_init(void __iomem *base, int irq);
void mxc_timer_init(void __iomem *, int); void mxc_timer_init(void __iomem *, int);
int mx1_clocks_init(unsigned long fref); int mx1_clocks_init(unsigned long fref);
int mx21_clocks_init(unsigned long lref, unsigned long fref); int mx21_clocks_init(unsigned long lref, unsigned long fref);
int mx25_clocks_init(void);
int mx27_clocks_init(unsigned long fref); int mx27_clocks_init(unsigned long fref);
int mx31_clocks_init(unsigned long fref); int mx31_clocks_init(unsigned long fref);
int mx35_clocks_init(void); int mx35_clocks_init(void);
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include "iim.h" #include "iim.h"
#include "hardware.h" #include "hardware.h"
...@@ -20,8 +22,15 @@ static int mx25_cpu_rev = -1; ...@@ -20,8 +22,15 @@ static int mx25_cpu_rev = -1;
static int mx25_read_cpu_rev(void) static int mx25_read_cpu_rev(void)
{ {
u32 rev; u32 rev;
void __iomem *iim_base;
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim");
iim_base = of_iomap(np, 0);
BUG_ON(!iim_base);
rev = readl(iim_base + MXC_IIMSREV);
iounmap(iim_base);
rev = __raw_readl(MX25_IO_ADDRESS(MX25_IIM_BASE_ADDR + MXC_IIMSREV));
switch (rev) { switch (rev) {
case 0x00: case 0x00:
return IMX_CHIP_REVISION_1_0; return IMX_CHIP_REVISION_1_0;
......
/*
* Copyright (C) 2010 Pengutronix
* Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include "devices/devices-common.h"
extern const struct imx_fec_data imx25_fec_data;
#define imx25_add_fec(pdata) \
imx_add_fec(&imx25_fec_data, pdata)
extern const struct imx_flexcan_data imx25_flexcan_data[];
#define imx25_add_flexcan(id) \
imx_add_flexcan(&imx25_flexcan_data[id])
#define imx25_add_flexcan0() imx25_add_flexcan(0)
#define imx25_add_flexcan1() imx25_add_flexcan(1)
extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data;
#define imx25_add_fsl_usb2_udc(pdata) \
imx_add_fsl_usb2_udc(&imx25_fsl_usb2_udc_data, pdata)
extern struct imx_imxdi_rtc_data imx25_imxdi_rtc_data;
#define imx25_add_imxdi_rtc() \
imx_add_imxdi_rtc(&imx25_imxdi_rtc_data)
extern const struct imx_imx2_wdt_data imx25_imx2_wdt_data;
#define imx25_add_imx2_wdt() \
imx_add_imx2_wdt(&imx25_imx2_wdt_data)
extern const struct imx_imx_fb_data imx25_imx_fb_data;
#define imx25_add_imx_fb(pdata) \
imx_add_imx_fb(&imx25_imx_fb_data, pdata)
extern const struct imx_imx_i2c_data imx25_imx_i2c_data[];
#define imx25_add_imx_i2c(id, pdata) \
imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
#define imx25_add_imx_i2c0(pdata) imx25_add_imx_i2c(0, pdata)
#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata)
#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata)
extern const struct imx_imx_keypad_data imx25_imx_keypad_data;
#define imx25_add_imx_keypad(pdata) \
imx_add_imx_keypad(&imx25_imx_keypad_data, pdata)
extern const struct imx_imx_ssi_data imx25_imx_ssi_data[];
#define imx25_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[];
#define imx25_add_imx_uart(id, pdata) \
imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata)
#define imx25_add_imx_uart0(pdata) imx25_add_imx_uart(0, pdata)
#define imx25_add_imx_uart1(pdata) imx25_add_imx_uart(1, pdata)
#define imx25_add_imx_uart2(pdata) imx25_add_imx_uart(2, pdata)
#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata)
#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata)
extern const struct imx_mx2_camera_data imx25_mx2_camera_data;
#define imx25_add_mx2_camera(pdata) \
imx_add_mx2_camera(&imx25_mx2_camera_data, pdata)
extern const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data;
#define imx25_add_mxc_ehci_otg(pdata) \
imx_add_mxc_ehci(&imx25_mxc_ehci_otg_data, pdata)
extern const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data;
#define imx25_add_mxc_ehci_hs(pdata) \
imx_add_mxc_ehci(&imx25_mxc_ehci_hs_data, pdata)
extern const struct imx_mxc_nand_data imx25_mxc_nand_data;
#define imx25_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
extern const struct imx_sdhci_esdhc_imx_data imx25_sdhci_esdhc_imx_data[];
#define imx25_add_sdhci_esdhc_imx(id, pdata) \
imx_add_sdhci_esdhc_imx(&imx25_sdhci_esdhc_imx_data[id], pdata)
extern const struct imx_spi_imx_data imx25_cspi_data[];
#define imx25_add_spi_imx(id, pdata) \
imx_add_spi_imx(&imx25_cspi_data[id], pdata)
#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
...@@ -21,9 +21,6 @@ config IMX_HAVE_PLATFORM_IMX27_CODA ...@@ -21,9 +21,6 @@ config IMX_HAVE_PLATFORM_IMX27_CODA
config IMX_HAVE_PLATFORM_IMX2_WDT config IMX_HAVE_PLATFORM_IMX2_WDT
bool bool
config IMX_HAVE_PLATFORM_IMXDI_RTC
bool
config IMX_HAVE_PLATFORM_IMX_FB config IMX_HAVE_PLATFORM_IMX_FB
bool bool
......
...@@ -8,7 +8,6 @@ obj-y += platform-gpio-mxc.o ...@@ -8,7 +8,6 @@ obj-y += platform-gpio-mxc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
obj-y += platform-imx-dma.o obj-y += platform-imx-dma.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FB) += platform-imx-fb.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FB) += platform-imx-fb.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
......
...@@ -19,11 +19,6 @@ ...@@ -19,11 +19,6 @@
.irq = soc ## _INT_FEC, \ .irq = soc ## _INT_FEC, \
} }
#ifdef CONFIG_SOC_IMX25
const struct imx_fec_data imx25_fec_data __initconst =
imx_fec_data_entry_single(MX25, "imx25-fec");
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_fec_data imx27_fec_data __initconst = const struct imx_fec_data imx27_fec_data __initconst =
imx_fec_data_entry_single(MX27, "imx27-fec"); imx_fec_data_entry_single(MX27, "imx27-fec");
......
...@@ -18,11 +18,6 @@ ...@@ -18,11 +18,6 @@
.irq = soc ## _INT_USB_OTG, \ .irq = soc ## _INT_USB_OTG, \
} }
#ifdef CONFIG_SOC_IMX25
const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27"); imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27");
......
...@@ -29,11 +29,6 @@ const struct imx_imx_fb_data imx21_imx_fb_data __initconst = ...@@ -29,11 +29,6 @@ const struct imx_imx_fb_data imx21_imx_fb_data __initconst =
imx_imx_fb_data_entry_single(MX21, "imx21-fb", SZ_4K); imx_imx_fb_data_entry_single(MX21, "imx21-fb", SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_imx_fb_data imx25_imx_fb_data __initconst =
imx_imx_fb_data_entry_single(MX25, "imx21-fb", SZ_16K);
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx_fb_data imx27_imx_fb_data __initconst = const struct imx_imx_fb_data imx27_imx_fb_data __initconst =
imx_imx_fb_data_entry_single(MX27, "imx21-fb", SZ_4K); imx_imx_fb_data_entry_single(MX27, "imx21-fb", SZ_4K);
......
...@@ -31,16 +31,6 @@ const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst = ...@@ -31,16 +31,6 @@ const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
imx_imx_i2c_data_entry_single(MX21, "imx21-i2c", 0, , SZ_4K); imx_imx_i2c_data_entry_single(MX21, "imx21-i2c", 0, , SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
#define imx25_imx_i2c_data_entry(_id, _hwid) \
imx_imx_i2c_data_entry(MX25, "imx21-i2c", _id, _hwid, SZ_16K)
imx25_imx_i2c_data_entry(0, 1),
imx25_imx_i2c_data_entry(1, 2),
imx25_imx_i2c_data_entry(2, 3),
};
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = { const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
#define imx27_imx_i2c_data_entry(_id, _hwid) \ #define imx27_imx_i2c_data_entry(_id, _hwid) \
......
...@@ -21,11 +21,6 @@ const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst = ...@@ -21,11 +21,6 @@ const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst =
imx_imx_keypad_data_entry_single(MX21, SZ_16); imx_imx_keypad_data_entry_single(MX21, SZ_16);
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_imx_keypad_data imx25_imx_keypad_data __initconst =
imx_imx_keypad_data_entry_single(MX25, SZ_16K);
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst = const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst =
imx_imx_keypad_data_entry_single(MX27, SZ_16); imx_imx_keypad_data_entry_single(MX27, SZ_16);
......
...@@ -30,15 +30,6 @@ const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = { ...@@ -30,15 +30,6 @@ const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = {
}; };
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = {
#define imx25_imx_ssi_data_entry(_id, _hwid) \
imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K)
imx25_imx_ssi_data_entry(0, 1),
imx25_imx_ssi_data_entry(1, 2),
};
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = { const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
#define imx27_imx_ssi_data_entry(_id, _hwid) \ #define imx27_imx_ssi_data_entry(_id, _hwid) \
......
...@@ -47,18 +47,6 @@ const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = { ...@@ -47,18 +47,6 @@ const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = {
}; };
#endif #endif
#ifdef CONFIG_SOC_IMX25
const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
#define imx25_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K)
imx25_imx_uart_data_entry(0, 1),
imx25_imx_uart_data_entry(1, 2),
imx25_imx_uart_data_entry(2, 3),
imx25_imx_uart_data_entry(3, 4),
imx25_imx_uart_data_entry(4, 5),
};
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = { const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
#define imx27_imx_uart_data_entry(_id, _hwid) \ #define imx27_imx_uart_data_entry(_id, _hwid) \
......
...@@ -25,11 +25,6 @@ const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst = ...@@ -25,11 +25,6 @@ const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst =
imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K); imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_imx2_wdt_data imx25_imx2_wdt_data __initconst =
imx_imx2_wdt_data_entry_single(MX25, 0, , SZ_16K);
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst = const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst =
imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K); imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K);
......
/*
* Copyright (C) 2010 Pengutronix
* Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <asm/sizes.h>
#include "../hardware.h"
#include "devices-common.h"
#define imx_imxdi_rtc_data_entry_single(soc) \
{ \
.iobase = soc ## _DRYICE_BASE_ADDR, \
.irq = soc ## _INT_DRYICE, \
}
#ifdef CONFIG_SOC_IMX25
const struct imx_imxdi_rtc_data imx25_imxdi_rtc_data __initconst =
imx_imxdi_rtc_data_entry_single(MX25);
#endif /* ifdef CONFIG_SOC_IMX25 */
struct platform_device *__init imx_add_imxdi_rtc(
const struct imx_imxdi_rtc_data *data)
{
struct resource res[] = {
{
.start = data->iobase,
.end = data->iobase + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
.start = data->irq,
.end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
return imx_add_platform_device("imxdi_rtc", 0,
res, ARRAY_SIZE(res), NULL, 0);
}
...@@ -27,11 +27,6 @@ ...@@ -27,11 +27,6 @@
.irqemmaprp = soc ## _INT_EMMAPRP, \ .irqemmaprp = soc ## _INT_EMMAPRP, \
} }
#ifdef CONFIG_SOC_IMX25
const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst =
imx_mx2_camera_data_entry_single(MX25, "imx25-camera");
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst = const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst =
imx_mx2_camera_data_entry_single_emma(MX27, "imx27-camera"); imx_mx2_camera_data_entry_single_emma(MX27, "imx27-camera");
......
...@@ -18,13 +18,6 @@ ...@@ -18,13 +18,6 @@
.irq = soc ## _INT_USB_ ## hs, \ .irq = soc ## _INT_USB_ ## hs, \
} }
#ifdef CONFIG_SOC_IMX25
const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst =
imx_mxc_ehci_data_entry_single(MX25, 0, OTG);
const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data __initconst =
imx_mxc_ehci_data_entry_single(MX25, 1, HS);
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst = const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst =
imx_mxc_ehci_data_entry_single(MX27, 0, OTG); imx_mxc_ehci_data_entry_single(MX27, 0, OTG);
......
...@@ -34,11 +34,6 @@ const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst = ...@@ -34,11 +34,6 @@ const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX21, "imx21-nand", SZ_4K); imx_mxc_nand_data_entry_single(MX21, "imx21-nand", SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */ #endif /* ifdef CONFIG_SOC_IMX21 */
#ifdef CONFIG_SOC_IMX25
const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX25, "imx25-nand", SZ_8K);
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst = const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX27, "imx27-nand", SZ_4K); imx_mxc_nand_data_entry_single(MX27, "imx27-nand", SZ_4K);
......
...@@ -39,17 +39,6 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = { ...@@ -39,17 +39,6 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
}; };
#endif #endif
#ifdef CONFIG_SOC_IMX25
/* i.mx25 has the i.mx35 type cspi */
const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
#define imx25_cspi_data_entry(_id, _hwid) \
imx_spi_imx_data_entry(MX25, CSPI, "imx35-cspi", _id, _hwid, SZ_16K)
imx25_cspi_data_entry(0, 1),
imx25_cspi_data_entry(1, 2),
imx25_cspi_data_entry(2, 3),
};
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_spi_imx_data imx27_cspi_data[] __initconst = { const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
#define imx27_cspi_data_entry(_id, _hwid) \ #define imx27_cspi_data_entry(_id, _hwid) \
......
/*
* Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
* Copyright (C) 2010 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/platform_data/usb-ehci-mxc.h>
#include "ehci.h"
#include "hardware.h"
#define USBCTRL_OTGBASE_OFFSET 0x600
#define MX25_OTG_SIC_SHIFT 29
#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
#define MX25_OTG_PM_BIT (1 << 24)
#define MX25_OTG_PP_BIT (1 << 11)
#define MX25_OTG_OCPOL_BIT (1 << 3)
#define MX25_H1_SIC_SHIFT 21
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
#define MX25_H1_PP_BIT (1 << 18)
#define MX25_H1_PM_BIT (1 << 16)
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX25_H1_TLL_BIT (1 << 5)
#define MX25_H1_USBTE_BIT (1 << 4)
#define MX25_H1_OCPOL_BIT (1 << 2)
int mx25_initialize_usb_hw(int port, unsigned int flags)
{
unsigned int v;
v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
switch (port) {
case 0: /* OTG port */
v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT | MX25_OTG_PP_BIT |
MX25_OTG_OCPOL_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX25_OTG_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX25_OTG_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX25_OTG_OCPOL_BIT;
break;
case 1: /* H1 port */
v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_PP_BIT |
MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | MX25_H1_USBTE_BIT |
MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX25_H1_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX25_H1_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX25_H1_OCPOL_BIT;
if (!(flags & MXC_EHCI_TTL_ENABLED))
v |= MX25_H1_TLL_BIT;
if (flags & MXC_EHCI_INTERNAL_PHY)
v |= MX25_H1_USBTE_BIT;
if (flags & MXC_EHCI_IPPUE_DOWN)
v |= MX25_H1_IPPUE_DOWN_BIT;
if (flags & MXC_EHCI_IPPUE_UP)
v |= MX25_H1_IPPUE_UP_BIT;
break;
default:
return -EINVAL;
}
writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
return 0;
}
/*
* Copyright (C) 2010 Eric Benard - eric@eukrea.com
*
* Based on pcm970-baseboard.c which is :
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/spi/spi.h>
#include <video/platform_lcd.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
#include "devices-imx25.h"
#include "hardware.h"
#include "iomux-mx25.h"
#include "mx25.h"
static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
/* LCD */
MX25_PAD_LD0__LD0,
MX25_PAD_LD1__LD1,
MX25_PAD_LD2__LD2,
MX25_PAD_LD3__LD3,
MX25_PAD_LD4__LD4,
MX25_PAD_LD5__LD5,
MX25_PAD_LD6__LD6,
MX25_PAD_LD7__LD7,
MX25_PAD_LD8__LD8,
MX25_PAD_LD9__LD9,
MX25_PAD_LD10__LD10,
MX25_PAD_LD11__LD11,
MX25_PAD_LD12__LD12,
MX25_PAD_LD13__LD13,
MX25_PAD_LD14__LD14,
MX25_PAD_LD15__LD15,
MX25_PAD_GPIO_E__LD16,
MX25_PAD_GPIO_F__LD17,
MX25_PAD_HSYNC__HSYNC,
MX25_PAD_VSYNC__VSYNC,
MX25_PAD_LSCLK__LSCLK,
MX25_PAD_OE_ACD__OE_ACD,
MX25_PAD_CONTRAST__CONTRAST,
/* LCD_PWR */
MX25_PAD_PWM__GPIO_1_26,
/* LED */
MX25_PAD_POWER_FAIL__GPIO_3_19,
/* SWITCH */
MX25_PAD_VSTBY_ACK__GPIO_3_18,
/* UART2 */
MX25_PAD_UART2_RTS__UART2_RTS,
MX25_PAD_UART2_CTS__UART2_CTS,
MX25_PAD_UART2_TXD__UART2_TXD,
MX25_PAD_UART2_RXD__UART2_RXD,
/* SD1 */
MX25_PAD_SD1_CMD__SD1_CMD,
MX25_PAD_SD1_CLK__SD1_CLK,
MX25_PAD_SD1_DATA0__SD1_DATA0,
MX25_PAD_SD1_DATA1__SD1_DATA1,
MX25_PAD_SD1_DATA2__SD1_DATA2,
MX25_PAD_SD1_DATA3__SD1_DATA3,
/* SD1 CD */
MX25_PAD_DE_B__GPIO_2_20,
/* I2S */
MX25_PAD_KPP_COL3__AUD5_TXFS,
MX25_PAD_KPP_COL2__AUD5_TXC,
MX25_PAD_KPP_COL1__AUD5_RXD,
MX25_PAD_KPP_COL0__AUD5_TXD,
/* CAN */
MX25_PAD_GPIO_D__CAN2_RX,
MX25_PAD_GPIO_C__CAN2_TX,
/* SPI1 */
MX25_PAD_CSPI1_MOSI__CSPI1_MOSI,
MX25_PAD_CSPI1_MISO__CSPI1_MISO,
MX25_PAD_CSPI1_SS0__GPIO_1_16,
MX25_PAD_CSPI1_SS1__GPIO_1_17,
MX25_PAD_CSPI1_SCLK__CSPI1_SCLK,
MX25_PAD_CSPI1_RDY__GPIO_2_22,
};
#define GPIO_LED1 IMX_GPIO_NR(3, 19)
#define GPIO_SWITCH1 IMX_GPIO_NR(3, 18)
#define GPIO_SD1CD IMX_GPIO_NR(2, 20)
#define GPIO_LCDPWR IMX_GPIO_NR(1, 26)
#define GPIO_SPI1_SS0 IMX_GPIO_NR(1, 16)
#define GPIO_SPI1_SS1 IMX_GPIO_NR(1, 17)
#define GPIO_SPI1_IRQ IMX_GPIO_NR(2, 22)
static struct imx_fb_videomode eukrea_mximxsd_modes[] = {
{
.mode = {
.name = "CMO-QVGA",
.refresh = 60,
.xres = 320,
.yres = 240,
.pixclock = KHZ2PICOS(6500),
.left_margin = 30,
.right_margin = 38,
.upper_margin = 20,
.lower_margin = 3,
.hsync_len = 15,
.vsync_len = 4,
},
.bpp = 16,
.pcr = 0xCAD08B80,
}, {
.mode = {
.name = "DVI-VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 32000,
.hsync_len = 7,
.left_margin = 100,
.right_margin = 100,
.vsync_len = 7,
.upper_margin = 7,
.lower_margin = 100,
},
.pcr = 0xFA208B80,
.bpp = 16,
}, {
.mode = {
.name = "DVI-SVGA",
.refresh = 60,
.xres = 800,
.yres = 600,
.pixclock = 25000,
.hsync_len = 7,
.left_margin = 75,
.right_margin = 75,
.vsync_len = 7,
.upper_margin = 7,
.lower_margin = 75,
},
.pcr = 0xFA208B80,
.bpp = 16,
},
};
static const struct imx_fb_platform_data eukrea_mximxsd_fb_pdata __initconst = {
.mode = eukrea_mximxsd_modes,
.num_modes = ARRAY_SIZE(eukrea_mximxsd_modes),
.pwmr = 0x00A903FF,
.lscr1 = 0x00120300,
.dmacr = 0x00040060,
};
static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
unsigned int power)
{
if (power)
gpio_direction_output(GPIO_LCDPWR, 1);
else
gpio_direction_output(GPIO_LCDPWR, 0);
}
static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
.set_power = eukrea_mbimxsd_lcd_power_set,
};
static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
.name = "platform-lcd",
.dev.platform_data = &eukrea_mbimxsd_lcd_power_data,
};
static const struct gpio_led eukrea_mbimxsd_leds[] __initconst = {
{
.name = "led1",
.default_trigger = "heartbeat",
.active_low = 1,
.gpio = GPIO_LED1,
},
};
static const struct gpio_led_platform_data
eukrea_mbimxsd_led_info __initconst = {
.leds = eukrea_mbimxsd_leds,
.num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
};
static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
{
.gpio = GPIO_SWITCH1,
.code = BTN_0,
.desc = "BP1",
.active_low = 1,
.wakeup = 1,
},
};
static const struct gpio_keys_platform_data
eukrea_mbimxsd_button_data __initconst = {
.buttons = eukrea_mbimxsd_gpio_buttons,
.nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
};
static struct platform_device *platform_devices[] __initdata = {
&eukrea_mbimxsd_lcd_powerdev,
};
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
{
I2C_BOARD_INFO("tlv320aic23", 0x1a),
},
};
static const
struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
static struct esdhc_platform_data sd1_pdata = {
.cd_gpio = GPIO_SD1CD,
.cd_type = ESDHC_CD_GPIO,
.wp_type = ESDHC_WP_NONE,
};
static struct spi_board_info eukrea_mbimxsd25_spi_board_info[] __initdata = {
{
.modalias = "spidev",
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
},
{
.modalias = "spidev",
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 1,
.mode = SPI_MODE_0,
},
};
static int eukrea_mbimxsd25_spi_cs[] = {GPIO_SPI1_SS0, GPIO_SPI1_SS1};
static const struct spi_imx_master eukrea_mbimxsd25_spi0_data __initconst = {
.chipselect = eukrea_mbimxsd25_spi_cs,
.num_chipselect = ARRAY_SIZE(eukrea_mbimxsd25_spi_cs),
};
/*
* system init for baseboard usage. Will be called by cpuimx25 init.
*
* Add platform devices present on this baseboard and init
* them from CPU side as far as required to use them later on
*/
void __init eukrea_mbimxsd25_baseboard_init(void)
{
if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
ARRAY_SIZE(eukrea_mbimxsd_pads)))
printk(KERN_ERR "error setting mbimxsd pads !\n");
imx25_add_imx_uart1(&uart_pdata);
imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
imx25_add_flexcan1();
imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
gpio_free(GPIO_LED1);
gpio_request(GPIO_SWITCH1, "SWITCH1");
gpio_direction_input(GPIO_SWITCH1);
gpio_free(GPIO_SWITCH1);
gpio_request(GPIO_LCDPWR, "LCDPWR");
gpio_direction_output(GPIO_LCDPWR, 1);
i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
gpio_request(GPIO_SPI1_IRQ, "SPI1_IRQ");
gpio_direction_input(GPIO_SPI1_IRQ);
gpio_free(GPIO_SPI1_IRQ);
imx25_add_spi_imx0(&eukrea_mbimxsd25_spi0_data);
spi_register_board_info(eukrea_mbimxsd25_spi_board_info,
ARRAY_SIZE(eukrea_mbimxsd25_spi_board_info));
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
}
...@@ -100,7 +100,7 @@ static struct mx3fb_platform_data mx3fb_pdata __initdata = { ...@@ -100,7 +100,7 @@ static struct mx3fb_platform_data mx3fb_pdata __initdata = {
.num_modes = ARRAY_SIZE(fb_modedb), .num_modes = ARRAY_SIZE(fb_modedb),
}; };
static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = { static const iomux_v3_cfg_t eukrea_mbimxsd_pads[] __initconst = {
/* LCD */ /* LCD */
MX35_PAD_LD0__IPU_DISPB_DAT_0, MX35_PAD_LD0__IPU_DISPB_DAT_0,
MX35_PAD_LD1__IPU_DISPB_DAT_1, MX35_PAD_LD1__IPU_DISPB_DAT_1,
......
...@@ -112,7 +112,6 @@ ...@@ -112,7 +112,6 @@
#include "mx21.h" #include "mx21.h"
#include "mx27.h" #include "mx27.h"
#include "mx1.h" #include "mx1.h"
#include "mx25.h"
#define imx_map_entry(soc, name, _type) { \ #define imx_map_entry(soc, name, _type) { \
.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
......
/*
* arch/arm/plat-mxc/include/mach/iomux-mx25.h
*
* Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de>
*
* based on arch/arm/mach-mx25/mx25_pins.h
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
* and
* arch/arm/plat-mxc/include/mach/iomux-mx35.h
* Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#ifndef __MACH_IOMUX_MX25_H__
#define __MACH_IOMUX_MX25_H__
#include "iomux-v3.h"
/*
* IOMUX/PAD Bit field definitions
*/
#define MX25_PAD_A10__A10 IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A13__A13 IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A14__A14 IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A15__A15 IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A16__A16 IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A17__A17 IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL)
#define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL)
#define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL)
#define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL)
#define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A23__A23 IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL)
#define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL)
#define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL)
#define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_EB1__EB1 IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL)
#define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_OE__OE IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS0__CS0 IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS1__CS1 IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS1__NF_CE3 IOMUX_PAD(0x000, 0x050, 0x01, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS4__CS4 IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS4__NF_CE1 IOMUX_PAD(0x264, 0x054, 0x01, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS5__CS5 IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS5__NF_CE2 IOMUX_PAD(0x268, 0x058, 0x01, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
#define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LBA__LBA IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL)
#define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BCLK__BCLK IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_RW__RW IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL)
#define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFALE__NFALE IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_NFRB__NFRB IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE)
#define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D15__D15 IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D14__D14 IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D13__D13 IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D12__D12 IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D11__D11 IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D10__D10 IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_D9__D9 IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE)
#define MX25_PAD_D8__D8 IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_D7__D7 IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D6__D6 IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D5__D5 IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D4__D4 IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D3__D3 IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D2__D2 IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D1__D1 IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D0__D0 IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL)
#define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL)
#define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL)
#define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL)
#define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL)
#define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL)
#define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL)
#define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CONTRAST__PWM4_PWMO IOMUX_PAD(0x310, 0x118, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL)
#define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL)
#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D2__CSPI3_MOSI IOMUX_PAD(0x318, 0x120, 0x17, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D3__CSPI3_MISO IOMUX_PAD(0x31c, 0x124, 0x17, 0x4b4, 1, NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__CSPI3_SCLK IOMUX_PAD(0x320, 0x128, 0x17, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D5__CSPI3_RDY IOMUX_PAD(0x324, 0x12c, 0x17, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE)
#define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL)
#define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL)
#define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL)
#define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL)
#define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL)
#define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL)
#define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
#define KPP_CTL_ROW (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
#define KPP_CTL_COL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, KPP_CTL_COL)
#define MX25_PAD_KPP_COL0__UART4_RXD_MUX IOMUX_PAD(0x3b0, 0x1b8, 0x11, 0x570, 1, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL0__AUD5_TXD IOMUX_PAD(0x3b0, 0x1b8, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, KPP_CTL_COL)
#define MX25_PAD_KPP_COL1__UART4_TXD_MUX IOMUX_PAD(0x3b4, 0x1bc, 0x11, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL1__AUD5_RXD IOMUX_PAD(0x3b4, 0x1bc, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, KPP_CTL_COL)
#define MX25_PAD_KPP_COL2__UART4_RTS IOMUX_PAD(0x3b8, 0x1c0, 0x11, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL2__AUD5_TXC IOMUX_PAD(0x3b8, 0x1c0, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, KPP_CTL_COL)
#define MX25_PAD_KPP_COL3__UART4_CTS IOMUX_PAD(0x3bc, 0x1c4, 0x11, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_KPP_COL3__AUD5_TXFS IOMUX_PAD(0x3bc, 0x1c4, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP)
#define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL)
#define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
#define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
#define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
#define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_RTCK__RTCK IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_RTCK__OWIRE IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_DE_B__DE_B IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_TDO__TDO IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_A__CAN1_TX IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE)
#define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP)
#define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__LD16 IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__LD17 IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, PAD_CTL_SRE_FAST)
#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL)
#define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CLKO__CLKO IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
#endif /* __MACH_IOMUX_MX25_H__ */
...@@ -114,7 +114,7 @@ enum iomux_gp_func { ...@@ -114,7 +114,7 @@ enum iomux_gp_func {
*/ */
int mxc_iomux_alloc_pin(unsigned int pin, const char *label); int mxc_iomux_alloc_pin(unsigned int pin, const char *label);
/* /*
* setups mutliple pins * setups multiple pins
* convenient way to call the above function with tables * convenient way to call the above function with tables
*/ */
int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count, int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
......
...@@ -56,9 +56,10 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) ...@@ -56,9 +56,10 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
return 0; return 0;
} }
int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count) int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list,
unsigned count)
{ {
iomux_v3_cfg_t *p = pad_list; const iomux_v3_cfg_t *p = pad_list;
int i; int i;
int ret; int ret;
......
...@@ -128,10 +128,11 @@ typedef u64 iomux_v3_cfg_t; ...@@ -128,10 +128,11 @@ typedef u64 iomux_v3_cfg_t;
int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad); int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
/* /*
* setups mutliple pads * setups multiple pads
* convenient way to call the above function with tables * convenient way to call the above function with tables
*/ */
int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count); int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list,
unsigned count);
/* /*
* Initialise the iomux controller * Initialise the iomux controller
......
...@@ -75,7 +75,7 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { ...@@ -75,7 +75,7 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
}, },
}; };
static iomux_v3_cfg_t eukrea_cpuimx35_pads[] = { static const iomux_v3_cfg_t eukrea_cpuimx35_pads[] __initconst = {
/* UART1 */ /* UART1 */
MX35_PAD_CTS1__UART1_CTS, MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS, MX35_PAD_RTS1__UART1_RTS,
......
/*
* Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
* Copyright 2010 Eric Bénard - Eukréa Electromatique, <eric@eukrea.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/memory.h>
#include <asm/mach/map.h>
#include "common.h"
#include "devices-imx25.h"
#include "ehci.h"
#include "eukrea-baseboards.h"
#include "hardware.h"
#include "iomux-mx25.h"
#include "mx25.h"
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static iomux_v3_cfg_t eukrea_cpuimx25_pads[] = {
/* FEC - RMII */
MX25_PAD_FEC_MDC__FEC_MDC,
MX25_PAD_FEC_MDIO__FEC_MDIO,
MX25_PAD_FEC_TDATA0__FEC_TDATA0,
MX25_PAD_FEC_TDATA1__FEC_TDATA1,
MX25_PAD_FEC_TX_EN__FEC_TX_EN,
MX25_PAD_FEC_RDATA0__FEC_RDATA0,
MX25_PAD_FEC_RDATA1__FEC_RDATA1,
MX25_PAD_FEC_RX_DV__FEC_RX_DV,
MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
/* I2C1 */
MX25_PAD_I2C1_CLK__I2C1_CLK,
MX25_PAD_I2C1_DAT__I2C1_DAT,
};
static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
static const struct mxc_nand_platform_data
eukrea_cpuimx25_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
.flash_bbt = 1,
};
static const struct imxi2c_platform_data
eukrea_cpuimx25_i2c0_data __initconst = {
.bitrate = 100000,
};
static struct i2c_board_info eukrea_cpuimx25_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
},
};
static int eukrea_cpuimx25_otg_init(struct platform_device *pdev)
{
return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
}
static const struct mxc_usbh_platform_data otg_pdata __initconst = {
.init = eukrea_cpuimx25_otg_init,
.portsc = MXC_EHCI_MODE_UTMI,
};
static int eukrea_cpuimx25_usbh2_init(struct platform_device *pdev)
{
return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
}
static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
.init = eukrea_cpuimx25_usbh2_init,
.portsc = MXC_EHCI_MODE_SERIAL,
};
static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
.workaround = FLS_USB2_WORKAROUND_ENGCM09152,
};
static bool otg_mode_host __initdata;
static int __init eukrea_cpuimx25_otg_mode(char *options)
{
if (!strcmp(options, "host"))
otg_mode_host = true;
else if (!strcmp(options, "device"))
otg_mode_host = false;
else
pr_info("otg_mode neither \"host\" nor \"device\". "
"Defaulting to device\n");
return 1;
}
__setup("otg_mode=", eukrea_cpuimx25_otg_mode);
static void __init eukrea_cpuimx25_init(void)
{
imx25_soc_init();
if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
ARRAY_SIZE(eukrea_cpuimx25_pads)))
printk(KERN_ERR "error setting cpuimx25 pads !\n");
imx25_add_imx_uart0(&uart_pdata);
imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
imx25_add_imxdi_rtc();
imx25_add_fec(&mx25_fec_pdata);
imx25_add_imx2_wdt();
i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx25_i2c_devices));
imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data);
if (otg_mode_host)
imx25_add_mxc_ehci_otg(&otg_pdata);
else
imx25_add_fsl_usb2_udc(&otg_device_pdata);
imx25_add_mxc_ehci_hs(&usbh2_pdata);
#ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD
eukrea_mbimxsd25_baseboard_init();
#endif
}
static void __init eukrea_cpuimx25_timer_init(void)
{
mx25_clocks_init();
}
MACHINE_START(EUKREA_CPUIMX25SD, "Eukrea CPUIMX25")
/* Maintainer: Eukrea Electromatique */
.atag_offset = 0x100,
.map_io = mx25_map_io,
.init_early = imx25_init_early,
.init_irq = mx25_init_irq,
.init_time = eukrea_cpuimx25_timer_init,
.init_machine = eukrea_cpuimx25_init,
.restart = mxc_restart,
MACHINE_END
...@@ -10,12 +10,29 @@ ...@@ -10,12 +10,29 @@
*/ */
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include "common.h" #include "common.h"
#include "mx25.h" #include "hardware.h"
static void __init imx25_init_early(void)
{
mxc_set_cpu_type(MXC_CPU_MX25);
}
static void __init mx25_init_irq(void)
{
struct device_node *np;
void __iomem *avic_base;
np = of_find_compatible_node(NULL, NULL, "fsl,avic");
avic_base = of_iomap(np, 0);
BUG_ON(!avic_base);
mxc_init_irq(avic_base);
}
static const char * const imx25_dt_board_compat[] __initconst = { static const char * const imx25_dt_board_compat[] __initconst = {
"fsl,imx25", "fsl,imx25",
...@@ -23,7 +40,6 @@ static const char * const imx25_dt_board_compat[] __initconst = { ...@@ -23,7 +40,6 @@ static const char * const imx25_dt_board_compat[] __initconst = {
}; };
DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
.map_io = mx25_map_io,
.init_early = imx25_init_early, .init_early = imx25_init_early,
.init_irq = mx25_init_irq, .init_irq = mx25_init_irq,
.dt_compat = imx25_dt_board_compat, .dt_compat = imx25_dt_board_compat,
......
/*
* Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* This machine is known as:
* - i.MX25 3-Stack Development System
* - i.MX25 Platform Development Kit (i.MX25 PDK)
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/memory.h>
#include <asm/mach/map.h>
#include "common.h"
#include "devices-imx25.h"
#include "ehci.h"
#include "hardware.h"
#include "iomux-mx25.h"
#include "mx25.h"
#define MX25PDK_CAN_PWDN IMX_GPIO_NR(4, 6)
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static iomux_v3_cfg_t mx25pdk_pads[] = {
MX25_PAD_FEC_MDC__FEC_MDC,
MX25_PAD_FEC_MDIO__FEC_MDIO,
MX25_PAD_FEC_TDATA0__FEC_TDATA0,
MX25_PAD_FEC_TDATA1__FEC_TDATA1,
MX25_PAD_FEC_TX_EN__FEC_TX_EN,
MX25_PAD_FEC_RDATA0__FEC_RDATA0,
MX25_PAD_FEC_RDATA1__FEC_RDATA1,
MX25_PAD_FEC_RX_DV__FEC_RX_DV,
MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
/* LCD */
MX25_PAD_LD0__LD0,
MX25_PAD_LD1__LD1,
MX25_PAD_LD2__LD2,
MX25_PAD_LD3__LD3,
MX25_PAD_LD4__LD4,
MX25_PAD_LD5__LD5,
MX25_PAD_LD6__LD6,
MX25_PAD_LD7__LD7,
MX25_PAD_LD8__LD8,
MX25_PAD_LD9__LD9,
MX25_PAD_LD10__LD10,
MX25_PAD_LD11__LD11,
MX25_PAD_LD12__LD12,
MX25_PAD_LD13__LD13,
MX25_PAD_LD14__LD14,
MX25_PAD_LD15__LD15,
MX25_PAD_GPIO_E__LD16,
MX25_PAD_GPIO_F__LD17,
MX25_PAD_HSYNC__HSYNC,
MX25_PAD_VSYNC__VSYNC,
MX25_PAD_LSCLK__LSCLK,
MX25_PAD_OE_ACD__OE_ACD,
MX25_PAD_CONTRAST__CONTRAST,
/* Keypad */
MX25_PAD_KPP_ROW0__KPP_ROW0,
MX25_PAD_KPP_ROW1__KPP_ROW1,
MX25_PAD_KPP_ROW2__KPP_ROW2,
MX25_PAD_KPP_ROW3__KPP_ROW3,
MX25_PAD_KPP_COL0__KPP_COL0,
MX25_PAD_KPP_COL1__KPP_COL1,
MX25_PAD_KPP_COL2__KPP_COL2,
MX25_PAD_KPP_COL3__KPP_COL3,
/* SD1 */
MX25_PAD_SD1_CMD__SD1_CMD,
MX25_PAD_SD1_CLK__SD1_CLK,
MX25_PAD_SD1_DATA0__SD1_DATA0,
MX25_PAD_SD1_DATA1__SD1_DATA1,
MX25_PAD_SD1_DATA2__SD1_DATA2,
MX25_PAD_SD1_DATA3__SD1_DATA3,
MX25_PAD_A14__GPIO_2_0, /* WriteProtect */
MX25_PAD_A15__GPIO_2_1, /* CardDetect */
/* I2C1 */
MX25_PAD_I2C1_CLK__I2C1_CLK,
MX25_PAD_I2C1_DAT__I2C1_DAT,
/* CAN1 */
MX25_PAD_GPIO_A__CAN1_TX,
MX25_PAD_GPIO_B__CAN1_RX,
MX25_PAD_D14__GPIO_4_6, /* CAN_PWDN */
};
static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
#define FEC_ENABLE_GPIO IMX_GPIO_NR(2, 3)
#define FEC_RESET_B_GPIO IMX_GPIO_NR(4, 8)
static void __init mx25pdk_fec_reset(void)
{
gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */
gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
udelay(2);
/* turn on PHY power and lift reset */
gpio_set_value(FEC_ENABLE_GPIO, 1);
gpio_set_value(FEC_RESET_B_GPIO, 1);
}
static const struct mxc_nand_platform_data
mx25pdk_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
.flash_bbt = 1,
};
static struct imx_fb_videomode mx25pdk_modes[] = {
{
.mode = {
.name = "CRT-VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39683,
.left_margin = 45,
.right_margin = 114,
.upper_margin = 33,
.lower_margin = 11,
.hsync_len = 1,
.vsync_len = 1,
},
.bpp = 16,
.pcr = 0xFA208B80,
},
};
static const struct imx_fb_platform_data mx25pdk_fb_pdata __initconst = {
.mode = mx25pdk_modes,
.num_modes = ARRAY_SIZE(mx25pdk_modes),
.pwmr = 0x00A903FF,
.lscr1 = 0x00120300,
.dmacr = 0x00020010,
};
static const uint32_t mx25pdk_keymap[] = {
KEY(0, 0, KEY_UP),
KEY(0, 1, KEY_DOWN),
KEY(0, 2, KEY_VOLUMEDOWN),
KEY(0, 3, KEY_HOME),
KEY(1, 0, KEY_RIGHT),
KEY(1, 1, KEY_LEFT),
KEY(1, 2, KEY_ENTER),
KEY(1, 3, KEY_VOLUMEUP),
KEY(2, 0, KEY_F6),
KEY(2, 1, KEY_F8),
KEY(2, 2, KEY_F9),
KEY(2, 3, KEY_F10),
KEY(3, 0, KEY_F1),
KEY(3, 1, KEY_F2),
KEY(3, 2, KEY_F3),
KEY(3, 3, KEY_POWER),
};
static const struct matrix_keymap_data mx25pdk_keymap_data __initconst = {
.keymap = mx25pdk_keymap,
.keymap_size = ARRAY_SIZE(mx25pdk_keymap),
};
static int mx25pdk_usbh2_init(struct platform_device *pdev)
{
return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
}
static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
.init = mx25pdk_usbh2_init,
.portsc = MXC_EHCI_MODE_SERIAL,
};
static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
};
static const struct imxi2c_platform_data mx25_3ds_i2c0_data __initconst = {
.bitrate = 100000,
};
#define SD1_GPIO_WP IMX_GPIO_NR(2, 0)
#define SD1_GPIO_CD IMX_GPIO_NR(2, 1)
static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
.wp_gpio = SD1_GPIO_WP,
.cd_gpio = SD1_GPIO_CD,
.wp_type = ESDHC_WP_GPIO,
.cd_type = ESDHC_CD_GPIO,
};
static void __init mx25pdk_init(void)
{
imx25_soc_init();
mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
ARRAY_SIZE(mx25pdk_pads));
imx25_add_imx_uart0(&uart_pdata);
imx25_add_fsl_usb2_udc(&otg_device_pdata);
imx25_add_mxc_ehci_hs(&usbh2_pdata);
imx25_add_mxc_nand(&mx25pdk_nand_board_info);
imx25_add_imxdi_rtc();
imx25_add_imx_fb(&mx25pdk_fb_pdata);
imx25_add_imx2_wdt();
mx25pdk_fec_reset();
imx25_add_fec(&mx25_fec_pdata);
imx25_add_imx_keypad(&mx25pdk_keymap_data);
imx25_add_sdhci_esdhc_imx(0, &mx25pdk_esdhc_pdata);
imx25_add_imx_i2c0(&mx25_3ds_i2c0_data);
gpio_request_one(MX25PDK_CAN_PWDN, GPIOF_OUT_INIT_LOW, "can-pwdn");
imx25_add_flexcan0();
}
static void __init mx25pdk_timer_init(void)
{
mx25_clocks_init();
}
MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
/* Maintainer: Freescale Semiconductor, Inc. */
.atag_offset = 0x100,
.map_io = mx25_map_io,
.init_early = imx25_init_early,
.init_irq = mx25_init_irq,
.init_time = mx25pdk_timer_init,
.init_machine = mx25pdk_init,
.restart = mxc_restart,
MACHINE_END
...@@ -166,7 +166,7 @@ static struct platform_device *devices[] __initdata = { ...@@ -166,7 +166,7 @@ static struct platform_device *devices[] __initdata = {
&mx35pdk_flash, &mx35pdk_flash,
}; };
static iomux_v3_cfg_t mx35pdk_pads[] = { static const iomux_v3_cfg_t mx35pdk_pads[] __initconst = {
/* UART1 */ /* UART1 */
MX35_PAD_CTS1__UART1_CTS, MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS, MX35_PAD_RTS1__UART1_RTS,
......
...@@ -129,7 +129,7 @@ static struct platform_device *devices[] __initdata = { ...@@ -129,7 +129,7 @@ static struct platform_device *devices[] __initdata = {
&pcm043_flash, &pcm043_flash,
}; };
static iomux_v3_cfg_t pcm043_pads[] = { static const iomux_v3_cfg_t pcm043_pads[] __initconst = {
/* UART1 */ /* UART1 */
MX35_PAD_CTS1__UART1_CTS, MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS, MX35_PAD_RTS1__UART1_RTS,
......
...@@ -161,7 +161,7 @@ static struct i2c_board_info vpr200_i2c_devices[] = { ...@@ -161,7 +161,7 @@ static struct i2c_board_info vpr200_i2c_devices[] = {
} }
}; };
static iomux_v3_cfg_t vpr200_pads[] = { static const iomux_v3_cfg_t vpr200_pads[] __initconst = {
/* UART1 */ /* UART1 */
MX35_PAD_TXD1__UART1_TXD_MUX, MX35_PAD_TXD1__UART1_TXD_MUX,
MX35_PAD_RXD1__UART1_RXD_MUX, MX35_PAD_RXD1__UART1_RXD_MUX,
......
/*
* Copyright (C) 1999,2000 Arm Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* - add MX31 specific definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/pinctrl/machine.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include "common.h"
#include "devices/devices-common.h"
#include "hardware.h"
#include "iomux-v3.h"
#include "mx25.h"
/*
* This table defines static virtual address mappings for I/O regions.
* These are the mappings common across all MX25 boards.
*/
static struct map_desc mx25_io_desc[] __initdata = {
imx_map_entry(MX25, AVIC, MT_DEVICE_NONSHARED),
imx_map_entry(MX25, AIPS1, MT_DEVICE_NONSHARED),
imx_map_entry(MX25, AIPS2, MT_DEVICE_NONSHARED),
};
/*
* This function initializes the memory map. It is called during the
* system startup to create static physical to virtual memory mappings
* for the IO modules.
*/
void __init mx25_map_io(void)
{
iotable_init(mx25_io_desc, ARRAY_SIZE(mx25_io_desc));
}
void __init imx25_init_early(void)
{
mxc_set_cpu_type(MXC_CPU_MX25);
mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
}
void __init mx25_init_irq(void)
{
mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
}
static struct sdma_platform_data imx25_sdma_pdata __initdata = {
.fw_name = "sdma-imx25.bin",
};
static const struct resource imx25_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX25_AUDMUX_BASE_ADDR, SZ_16K),
};
void __init imx25_soc_init(void)
{
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
mxc_device_init();
/* i.mx25 has the i.mx35 type gpio */
mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
pinctrl_provide_dummies();
/* i.mx25 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
/* i.mx25 has the i.mx31 type audmux */
platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
ARRAY_SIZE(imx25_audmux_res));
}
#ifndef __MACH_MX25_H__
#define __MACH_MX25_H__
#define MX25_AIPS1_BASE_ADDR 0x43f00000
#define MX25_AIPS1_SIZE SZ_1M
#define MX25_AIPS2_BASE_ADDR 0x53f00000
#define MX25_AIPS2_SIZE SZ_1M
#define MX25_AVIC_BASE_ADDR 0x68000000
#define MX25_AVIC_SIZE SZ_1M
#define MX25_I2C1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x80000)
#define MX25_I2C3_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x84000)
#define MX25_CAN1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x88000)
#define MX25_CAN2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x8c000)
#define MX25_I2C2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x98000)
#define MX25_CSPI1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xa4000)
#define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000)
#define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
#define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000)
#define MX25_GPIO4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x9c000)
#define MX25_PWM2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa0000)
#define MX25_GPIO3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa4000)
#define MX25_PWM3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa8000)
#define MX25_PWM4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xc8000)
#define MX25_GPIO1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xcc000)
#define MX25_GPIO2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xd0000)
#define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000)
#define MX25_PWM1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xe0000)
#define MX25_UART1_BASE_ADDR 0x43f90000
#define MX25_UART2_BASE_ADDR 0x43f94000
#define MX25_AUDMUX_BASE_ADDR 0x43fb0000
#define MX25_UART3_BASE_ADDR 0x5000c000
#define MX25_UART4_BASE_ADDR 0x50008000
#define MX25_UART5_BASE_ADDR 0x5002c000
#define MX25_CSPI3_BASE_ADDR 0x50004000
#define MX25_CSPI2_BASE_ADDR 0x50010000
#define MX25_FEC_BASE_ADDR 0x50038000
#define MX25_SSI2_BASE_ADDR 0x50014000
#define MX25_SSI1_BASE_ADDR 0x50034000
#define MX25_NFC_BASE_ADDR 0xbb000000
#define MX25_IIM_BASE_ADDR 0x53ff0000
#define MX25_DRYICE_BASE_ADDR 0x53ffc000
#define MX25_ESDHC1_BASE_ADDR 0x53fb4000
#define MX25_ESDHC2_BASE_ADDR 0x53fb8000
#define MX25_LCDC_BASE_ADDR 0x53fbc000
#define MX25_KPP_BASE_ADDR 0x43fa8000
#define MX25_SDMA_BASE_ADDR 0x53fd4000
#define MX25_USB_BASE_ADDR 0x53ff4000
#define MX25_USB_OTG_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0000)
/*
* The reference manual (IMX25RM, Rev. 1, 06/2009) specifies an offset of 0x200
* for the host controller. Early documentation drafts specified 0x400 and
* Freescale internal sources confirm only the latter value to work.
*/
#define MX25_USB_HS_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0400)
#define MX25_CSI_BASE_ADDR 0x53ff8000
#define MX25_IO_P2V(x) IMX_IO_P2V(x)
#define MX25_IO_ADDRESS(x) IOMEM(MX25_IO_P2V(x))
/*
* Interrupt numbers
*/
#include <asm/irq.h>
#define MX25_INT_CSPI3 (NR_IRQS_LEGACY + 0)
#define MX25_INT_I2C1 (NR_IRQS_LEGACY + 3)
#define MX25_INT_I2C2 (NR_IRQS_LEGACY + 4)
#define MX25_INT_UART4 (NR_IRQS_LEGACY + 5)
#define MX25_INT_ESDHC2 (NR_IRQS_LEGACY + 8)
#define MX25_INT_ESDHC1 (NR_IRQS_LEGACY + 9)
#define MX25_INT_I2C3 (NR_IRQS_LEGACY + 10)
#define MX25_INT_SSI2 (NR_IRQS_LEGACY + 11)
#define MX25_INT_SSI1 (NR_IRQS_LEGACY + 12)
#define MX25_INT_CSPI2 (NR_IRQS_LEGACY + 13)
#define MX25_INT_CSPI1 (NR_IRQS_LEGACY + 14)
#define MX25_INT_GPIO3 (NR_IRQS_LEGACY + 16)
#define MX25_INT_CSI (NR_IRQS_LEGACY + 17)
#define MX25_INT_UART3 (NR_IRQS_LEGACY + 18)
#define MX25_INT_GPIO4 (NR_IRQS_LEGACY + 23)
#define MX25_INT_KPP (NR_IRQS_LEGACY + 24)
#define MX25_INT_DRYICE (NR_IRQS_LEGACY + 25)
#define MX25_INT_PWM1 (NR_IRQS_LEGACY + 26)
#define MX25_INT_UART2 (NR_IRQS_LEGACY + 32)
#define MX25_INT_NFC (NR_IRQS_LEGACY + 33)
#define MX25_INT_SDMA (NR_IRQS_LEGACY + 34)
#define MX25_INT_USB_HS (NR_IRQS_LEGACY + 35)
#define MX25_INT_PWM2 (NR_IRQS_LEGACY + 36)
#define MX25_INT_USB_OTG (NR_IRQS_LEGACY + 37)
#define MX25_INT_LCDC (NR_IRQS_LEGACY + 39)
#define MX25_INT_UART5 (NR_IRQS_LEGACY + 40)
#define MX25_INT_PWM3 (NR_IRQS_LEGACY + 41)
#define MX25_INT_PWM4 (NR_IRQS_LEGACY + 42)
#define MX25_INT_CAN1 (NR_IRQS_LEGACY + 43)
#define MX25_INT_CAN2 (NR_IRQS_LEGACY + 44)
#define MX25_INT_UART1 (NR_IRQS_LEGACY + 45)
#define MX25_INT_GPIO2 (NR_IRQS_LEGACY + 51)
#define MX25_INT_GPIO1 (NR_IRQS_LEGACY + 52)
#define MX25_INT_GPT1 (NR_IRQS_LEGACY + 54)
#define MX25_INT_FEC (NR_IRQS_LEGACY + 57)
#define MX25_DMA_REQ_SSI2_RX1 22
#define MX25_DMA_REQ_SSI2_TX1 23
#define MX25_DMA_REQ_SSI2_RX0 24
#define MX25_DMA_REQ_SSI2_TX0 25
#define MX25_DMA_REQ_SSI1_RX1 26
#define MX25_DMA_REQ_SSI1_TX1 27
#define MX25_DMA_REQ_SSI1_RX0 28
#define MX25_DMA_REQ_SSI1_TX0 29
#ifndef __ASSEMBLY__
extern int mx25_revision(void);
#endif
#endif /* ifndef __MACH_MX25_H__ */
if ARCH_MSM
choice
prompt "Qualcomm MSM SoC Type"
default ARCH_MSM7X00A
depends on ARCH_MSM
config ARCH_MSM7X00A
bool "MSM7x00A / MSM7x01A"
select ARCH_MSM_ARM11
select CPU_V6
select GPIO_MSM_V1
select MACH_TROUT if !MACH_HALIBUT
select MSM_PROC_COMM
select MSM_SMD
select CLKSRC_QCOM
select MSM_SMD_PKG3
config ARCH_MSM7X30
bool "MSM7x30"
select ARCH_MSM_SCORPION
select CPU_V7
select GPIO_MSM_V1
select MACH_MSM7X30_SURF # if !
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
select CLKSRC_QCOM
select MSM_VIC
config ARCH_QSD8X50
bool "QSD8X50"
select ARCH_MSM_SCORPION
select CPU_V7
select GPIO_MSM_V1
select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
select CLKSRC_QCOM
select MSM_VIC
endchoice
config MSM_SOC_REV_A
bool
config ARCH_MSM_ARM11
bool
config ARCH_MSM_SCORPION
bool
config MSM_VIC
bool
menu "Qualcomm MSM Board Type"
depends on ARCH_MSM
config MACH_HALIBUT
depends on ARCH_MSM
depends on ARCH_MSM7X00A
bool "Halibut Board (QCT SURF7201A)"
help
Support for the Qualcomm SURF7201A eval board.
config MACH_TROUT
depends on ARCH_MSM
depends on ARCH_MSM7X00A
bool "HTC Dream (aka trout)"
help
Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
config MACH_MSM7X30_SURF
depends on ARCH_MSM7X30
bool "MSM7x30 SURF"
help
Support for the Qualcomm MSM7x30 SURF eval board.
config MACH_QSD8X50_SURF
depends on ARCH_QSD8X50
bool "QSD8x50 SURF"
help
Support for the Qualcomm QSD8x50 SURF eval board.
config MACH_QSD8X50A_ST1_5
depends on ARCH_QSD8X50
bool "QSD8x50A ST1.5"
select MSM_SOC_REV_A
help
Support for the Qualcomm ST1.5.
endmenu
config MSM_SMD_PKG3
bool
config MSM_PROC_COMM
bool
config MSM_SMD
bool
config MSM_GPIOMUX
bool
help
Support for MSM V1 TLMM GPIOMUX architecture.
endif
obj-$(CONFIG_MSM_PROC_COMM) += clock.o
obj-$(CONFIG_MSM_VIC) += irq-vic.o
obj-$(CONFIG_ARCH_MSM7X00A) += irq.o
obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
obj-$(CONFIG_ARCH_MSM7X00A) += dma.o io.o
obj-$(CONFIG_ARCH_MSM7X30) += dma.o io.o
obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
zreladdr-y += 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x10800000
/* linux/arch/arm/mach-msm/board-halibut.c
*
* Copyright (C) 2007 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/smc91x.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/setup.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include "devices.h"
#include "common.h"
static struct resource smc91x_resources[] = {
[0] = {
.start = 0x9C004300,
.end = 0x9C004400,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSM_GPIO_TO_INT(49),
.end = MSM_GPIO_TO_INT(49),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
static struct smc91x_platdata smc91x_platdata = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev.platform_data = &smc91x_platdata,
};
static struct platform_device *devices[] __initdata = {
&msm_clock_7x01a,
&msm_device_gpio_7201,
&msm_device_uart3,
&msm_device_smd,
&msm_device_nand,
&msm_device_hsusb,
&msm_device_i2c,
&smc91x_device,
};
static void __init halibut_init_early(void)
{
arch_ioremap_caller = __msm_ioremap_caller;
}
static void __init halibut_init_irq(void)
{
msm_init_irq();
}
static void __init halibut_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static void __init halibut_map_io(void)
{
msm_map_common_io();
}
static void __init halibut_init_late(void)
{
smd_debugfs_init();
}
MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
.atag_offset = 0x100,
.map_io = halibut_map_io,
.init_early = halibut_init_early,
.init_irq = halibut_init_irq,
.init_machine = halibut_init,
.init_late = halibut_init_late,
.init_time = msm7x01_timer_init,
MACHINE_END
/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/smsc911x.h>
#include <linux/usb/msm_hsusb.h>
#include <linux/clkdev.h>
#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/memory.h>
#include <asm/setup.h>
#include <mach/clk.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
#include <mach/vreg.h>
#include "devices.h"
#include "gpiomux.h"
#include "proc_comm.h"
#include "common.h"
static void __init msm7x30_fixup(struct tag *tag, char **cmdline)
{
for (; tag->hdr.size; tag = tag_next(tag))
if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) {
tag->u.mem.start = 0;
tag->u.mem.size += SZ_2M;
}
}
static void __init msm7x30_reserve(void)
{
memblock_remove(0x0, SZ_2M);
}
static int hsusb_phy_init_seq[] = {
0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */
0x02, 0x36, /* Disable CDR Auto Reset feature */
-1
};
static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
{
int ret;
if (assert) {
ret = clk_reset(link_clk, CLK_RESET_ASSERT);
if (ret)
pr_err("usb hs_clk assert failed\n");
} else {
ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
if (ret)
pr_err("usb hs_clk deassert failed\n");
}
return ret;
}
static int hsusb_phy_clk_reset(struct clk *phy_clk)
{
int ret;
ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
if (ret) {
pr_err("usb phy clk assert failed\n");
return ret;
}
usleep_range(10000, 12000);
ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
if (ret)
pr_err("usb phy clk deassert failed\n");
return ret;
}
static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq = hsusb_phy_init_seq,
.mode = USB_DR_MODE_PERIPHERAL,
.otg_control = OTG_PHY_CONTROL,
.link_clk_reset = hsusb_link_clk_reset,
.phy_clk_reset = hsusb_phy_clk_reset,
};
struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
#ifdef CONFIG_SERIAL_MSM_CONSOLE
[49] = { /* UART2 RFR */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_2 | GPIOMUX_VALID,
},
[50] = { /* UART2 CTS */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_2 | GPIOMUX_VALID,
},
[51] = { /* UART2 RX */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_2 | GPIOMUX_VALID,
},
[52] = { /* UART2 TX */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_2 | GPIOMUX_VALID,
},
#endif
};
static struct platform_device *devices[] __initdata = {
&msm_clock_7x30,
&msm_device_gpio_7x30,
#if defined(CONFIG_SERIAL_MSM)
&msm_device_uart2,
#endif
&msm_device_smd,
&msm_device_otg,
&msm_device_hsusb,
&msm_device_hsusb_host,
};
static void __init msm7x30_init_irq(void)
{
msm_init_irq();
}
static void __init msm7x30_init(void)
{
msm_device_otg.dev.platform_data = &msm_otg_pdata;
msm_device_hsusb.dev.parent = &msm_device_otg.dev;
msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static void __init msm7x30_map_io(void)
{
msm_map_msm7x30_io();
}
static void __init msm7x30_init_late(void)
{
smd_debugfs_init();
}
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
.atag_offset = 0x100,
.fixup = msm7x30_fixup,
.reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
.init_late = msm7x30_init_late,
.init_time = msm7x30_timer_init,
MACHINE_END
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
.atag_offset = 0x100,
.fixup = msm7x30_fixup,
.reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
.init_late = msm7x30_init_late,
.init_time = msm7x30_timer_init,
MACHINE_END
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
.atag_offset = 0x100,
.fixup = msm7x30_fixup,
.reserve = msm7x30_reserve,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
.init_late = msm7x30_init_late,
.init_time = msm7x30_timer_init,
MACHINE_END
/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/usb/msm_hsusb.h>
#include <linux/err.h>
#include <linux/clkdev.h>
#include <linux/smc91x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <mach/irqs.h>
#include <mach/sirc.h>
#include <mach/vreg.h>
#include <mach/clk.h>
#include <linux/platform_data/mmc-msm_sdcc.h>
#include "devices.h"
#include "common.h"
static const resource_size_t qsd8x50_surf_smc91x_base __initconst = 0x70000300;
static const unsigned qsd8x50_surf_smc91x_gpio __initconst = 156;
/* Leave smc91x resources empty here, as we'll fill them in
* at run-time: they vary from board to board, and the true
* configuration won't be known until boot.
*/
static struct resource smc91x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
static struct smc91x_platdata smc91x_platdata = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev.platform_data = &smc91x_platdata,
};
static int __init msm_init_smc91x(void)
{
if (machine_is_qsd8x50_surf()) {
smc91x_resources[0].start = qsd8x50_surf_smc91x_base;
smc91x_resources[0].end = qsd8x50_surf_smc91x_base + 0xff;
smc91x_resources[1].start =
gpio_to_irq(qsd8x50_surf_smc91x_gpio);
smc91x_resources[1].end =
gpio_to_irq(qsd8x50_surf_smc91x_gpio);
platform_device_register(&smc91x_device);
}
return 0;
}
module_init(msm_init_smc91x);
static int hsusb_phy_init_seq[] = {
0x08, 0x31, /* Increase HS Driver Amplitude */
0x20, 0x32, /* Enable and set Pre-Emphasis Depth to 10% */
-1
};
static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
{
int ret;
if (assert) {
ret = clk_reset(link_clk, CLK_RESET_ASSERT);
if (ret)
pr_err("usb hs_clk assert failed\n");
} else {
ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
if (ret)
pr_err("usb hs_clk deassert failed\n");
}
return ret;
}
static int hsusb_phy_clk_reset(struct clk *phy_clk)
{
int ret;
ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
if (ret) {
pr_err("usb phy clk assert failed\n");
return ret;
}
usleep_range(10000, 12000);
ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
if (ret)
pr_err("usb phy clk deassert failed\n");
return ret;
}
static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq = hsusb_phy_init_seq,
.mode = USB_DR_MODE_PERIPHERAL,
.otg_control = OTG_PHY_CONTROL,
.link_clk_reset = hsusb_link_clk_reset,
.phy_clk_reset = hsusb_phy_clk_reset,
};
static struct platform_device *devices[] __initdata = {
&msm_clock_8x50,
&msm_device_gpio_8x50,
&msm_device_uart3,
&msm_device_smd,
&msm_device_otg,
&msm_device_hsusb,
&msm_device_hsusb_host,
};
static struct msm_mmc_gpio sdc1_gpio_cfg[] = {
{51, "sdc1_dat_3"},
{52, "sdc1_dat_2"},
{53, "sdc1_dat_1"},
{54, "sdc1_dat_0"},
{55, "sdc1_cmd"},
{56, "sdc1_clk"}
};
static struct vreg *vreg_mmc;
static unsigned long vreg_sts;
static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
{
int rc = 0;
struct platform_device *pdev;
pdev = container_of(dv, struct platform_device, dev);
if (vdd == 0) {
if (!vreg_sts)
return 0;
clear_bit(pdev->id, &vreg_sts);
if (!vreg_sts) {
rc = vreg_disable(vreg_mmc);
if (rc)
pr_err("vreg_mmc disable failed for slot "
"%d: %d\n", pdev->id, rc);
}
return 0;
}
if (!vreg_sts) {
rc = vreg_set_level(vreg_mmc, 2900);
if (rc)
pr_err("vreg_mmc set level failed for slot %d: %d\n",
pdev->id, rc);
rc = vreg_enable(vreg_mmc);
if (rc)
pr_err("vreg_mmc enable failed for slot %d: %d\n",
pdev->id, rc);
}
set_bit(pdev->id, &vreg_sts);
return 0;
}
static struct msm_mmc_gpio_data sdc1_gpio = {
.gpio = sdc1_gpio_cfg,
.size = ARRAY_SIZE(sdc1_gpio_cfg),
};
static struct msm_mmc_platform_data qsd8x50_sdc1_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
.translate_vdd = msm_sdcc_setup_power,
.gpio_data = &sdc1_gpio,
};
static void __init qsd8x50_init_mmc(void)
{
vreg_mmc = vreg_get(NULL, "gp5");
if (IS_ERR(vreg_mmc)) {
pr_err("vreg get for vreg_mmc failed (%ld)\n",
PTR_ERR(vreg_mmc));
return;
}
msm_add_sdcc(1, &qsd8x50_sdc1_data, 0, 0);
}
static void __init qsd8x50_map_io(void)
{
msm_map_qsd8x50_io();
}
static void __init qsd8x50_init_irq(void)
{
msm_init_irq();
msm_init_sirc();
}
static void __init qsd8x50_init(void)
{
msm_device_otg.dev.platform_data = &msm_otg_pdata;
msm_device_hsusb.dev.parent = &msm_device_otg.dev;
msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
platform_add_devices(devices, ARRAY_SIZE(devices));
qsd8x50_init_mmc();
}
static void __init qsd8x50_init_late(void)
{
smd_debugfs_init();
}
MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
.atag_offset = 0x100,
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
.init_late = qsd8x50_init_late,
.init_time = qsd8x50_timer_init,
MACHINE_END
MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
.atag_offset = 0x100,
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
.init_late = qsd8x50_init_late,
.init_time = qsd8x50_timer_init,
MACHINE_END
/* linux/arch/arm/mach-msm/board-sapphire.c
* Copyright (C) 2007-2009 HTC Corporation.
* Author: Thomas Tsai <thomas_tsai@htc.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/vreg.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/setup.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/memblock.h>
#include "gpio_chip.h"
#include "board-sapphire.h"
#include "proc_comm.h"
#include "devices.h"
#include "common.h"
void msm_init_irq(void);
void msm_init_gpio(void);
static struct platform_device *devices[] __initdata = {
&msm_device_smd,
&msm_device_dmov,
&msm_device_nand,
&msm_device_uart1,
&msm_device_uart3,
};
void msm_timer_init(void);
static void __init sapphire_init_irq(void)
{
msm_init_irq();
}
static void __init sapphire_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static struct map_desc sapphire_io_desc[] __initdata = {
{
.virtual = SAPPHIRE_CPLD_BASE,
.pfn = __phys_to_pfn(SAPPHIRE_CPLD_START),
.length = SAPPHIRE_CPLD_SIZE,
.type = MT_DEVICE_NONSHARED
}
};
static void __init sapphire_fixup(struct tag *tags, char **cmdline)
{
int smi_sz = parse_tag_smi((const struct tag *)tags);
if (smi_sz == 32) {
memblock_add(PHYS_OFFSET, 84*SZ_1M);
} else if (smi_sz == 64) {
memblock_add(PHYS_OFFSET, 101*SZ_1M);
} else {
memblock_add(PHYS_OFFSET, 101*SZ_1M);
/* Give a default value when not get smi size */
smi_sz = 64;
}
}
static void __init sapphire_map_io(void)
{
msm_map_common_io();
iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc));
msm_clock_init();
}
static void __init sapphire_init_late(void)
{
smd_debugfs_init();
}
MACHINE_START(SAPPHIRE, "sapphire")
/* Maintainer: Brian Swetland <swetland@google.com> */
.atag_offset = 0x100,
.fixup = sapphire_fixup,
.map_io = sapphire_map_io,
.init_irq = sapphire_init_irq,
.init_machine = sapphire_init,
.init_late = sapphire_init_late,
.init_time = msm_timer_init,
MACHINE_END
/*
* linux/arch/arm/mach-msm/gpio.c
*
* Copyright (C) 2005 HP Labs
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2009 Pavel Machek <pavel@ucw.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include "board-trout.h"
static uint8_t trout_int_mask[2] = {
[0] = 0xff, /* mask all interrupts */
[1] = 0xff,
};
static uint8_t trout_sleep_int_mask[] = {
[0] = 0xff,
[1] = 0xff,
};
struct msm_gpio_chip {
struct gpio_chip chip;
void __iomem *reg; /* Base of register bank */
u8 shadow;
};
#define to_msm_gpio_chip(c) container_of(c, struct msm_gpio_chip, chip)
static int msm_gpiolib_get(struct gpio_chip *chip, unsigned offset)
{
struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
unsigned mask = 1 << offset;
return !!(readb(msm_gpio->reg) & mask);
}
static void msm_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
{
struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
unsigned mask = 1 << offset;
if (val)
msm_gpio->shadow |= mask;
else
msm_gpio->shadow &= ~mask;
writeb(msm_gpio->shadow, msm_gpio->reg);
}
static int msm_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset)
{
msm_gpiolib_set(chip, offset, 0);
return 0;
}
static int msm_gpiolib_direction_output(struct gpio_chip *chip,
unsigned offset, int val)
{
msm_gpiolib_set(chip, offset, val);
return 0;
}
static int trout_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
return TROUT_GPIO_TO_INT(offset + chip->base);
}
#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
{ \
.chip = { \
.label = name, \
.direction_input = msm_gpiolib_direction_input,\
.direction_output = msm_gpiolib_direction_output, \
.get = msm_gpiolib_get, \
.set = msm_gpiolib_set, \
.to_irq = trout_gpio_to_irq, \
.base = base_gpio, \
.ngpio = 8, \
}, \
.reg = reg_num + TROUT_CPLD_BASE, \
.shadow = shadow_val, \
}
static struct msm_gpio_chip msm_gpio_banks[] = {
#if defined(CONFIG_DEBUG_MSM_UART) && (CONFIG_DEBUG_UART_PHYS == 0xa9a00000)
/* H2W pins <-> UART1 */
TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x40),
#else
/* H2W pins <-> UART3, Bluetooth <-> UART1 */
TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x80),
#endif
/* I2C pull */
TROUT_GPIO_BANK("MISC3", 0x02, TROUT_GPIO_MISC3_BASE, 0x04),
TROUT_GPIO_BANK("MISC4", 0x04, TROUT_GPIO_MISC4_BASE, 0),
/* mmdi 32k en */
TROUT_GPIO_BANK("MISC5", 0x06, TROUT_GPIO_MISC5_BASE, 0x04),
TROUT_GPIO_BANK("INT2", 0x08, TROUT_GPIO_INT2_BASE, 0),
TROUT_GPIO_BANK("MISC1", 0x0a, TROUT_GPIO_MISC1_BASE, 0),
TROUT_GPIO_BANK("VIRTUAL", 0x12, TROUT_GPIO_VIRTUAL_BASE, 0),
};
static void trout_gpio_irq_ack(struct irq_data *d)
{
int bank = TROUT_INT_TO_BANK(d->irq);
uint8_t mask = TROUT_INT_TO_MASK(d->irq);
int reg = TROUT_BANK_TO_STAT_REG(bank);
/*printk(KERN_INFO "trout_gpio_irq_ack irq %d\n", d->irq);*/
writeb(mask, TROUT_CPLD_BASE + reg);
}
static void trout_gpio_irq_mask(struct irq_data *d)
{
unsigned long flags;
uint8_t reg_val;
int bank = TROUT_INT_TO_BANK(d->irq);
uint8_t mask = TROUT_INT_TO_MASK(d->irq);
int reg = TROUT_BANK_TO_MASK_REG(bank);
local_irq_save(flags);
reg_val = trout_int_mask[bank] |= mask;
/*printk(KERN_INFO "trout_gpio_irq_mask irq %d => %d:%02x\n",
d->irq, bank, reg_val);*/
writeb(reg_val, TROUT_CPLD_BASE + reg);
local_irq_restore(flags);
}
static void trout_gpio_irq_unmask(struct irq_data *d)
{
unsigned long flags;
uint8_t reg_val;
int bank = TROUT_INT_TO_BANK(d->irq);
uint8_t mask = TROUT_INT_TO_MASK(d->irq);
int reg = TROUT_BANK_TO_MASK_REG(bank);
local_irq_save(flags);
reg_val = trout_int_mask[bank] &= ~mask;
/*printk(KERN_INFO "trout_gpio_irq_unmask irq %d => %d:%02x\n",
d->irq, bank, reg_val);*/
writeb(reg_val, TROUT_CPLD_BASE + reg);
local_irq_restore(flags);
}
int trout_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned long flags;
int bank = TROUT_INT_TO_BANK(d->irq);
uint8_t mask = TROUT_INT_TO_MASK(d->irq);
local_irq_save(flags);
if(on)
trout_sleep_int_mask[bank] &= ~mask;
else
trout_sleep_int_mask[bank] |= mask;
local_irq_restore(flags);
return 0;
}
static void trout_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int j, m;
unsigned v;
int bank;
int stat_reg;
int int_base = TROUT_INT_START;
uint8_t int_mask;
for (bank = 0; bank < 2; bank++) {
stat_reg = TROUT_BANK_TO_STAT_REG(bank);
v = readb(TROUT_CPLD_BASE + stat_reg);
int_mask = trout_int_mask[bank];
if (v & int_mask) {
writeb(v & int_mask, TROUT_CPLD_BASE + stat_reg);
printk(KERN_ERR "trout_gpio_irq_handler: got masked "
"interrupt: %d:%02x\n", bank, v & int_mask);
}
v &= ~int_mask;
while (v) {
m = v & -v;
j = fls(m) - 1;
/*printk(KERN_INFO "msm_gpio_irq_handler %d:%02x %02x b"
"it %d irq %d\n", bank, v, m, j, int_base + j);*/
v &= ~m;
generic_handle_irq(int_base + j);
}
int_base += TROUT_INT_BANK0_COUNT;
}
desc->irq_data.chip->irq_ack(&desc->irq_data);
}
static struct irq_chip trout_gpio_irq_chip = {
.name = "troutgpio",
.irq_ack = trout_gpio_irq_ack,
.irq_mask = trout_gpio_irq_mask,
.irq_unmask = trout_gpio_irq_unmask,
.irq_set_wake = trout_gpio_irq_set_wake,
};
/*
* Called from the processor-specific init to enable GPIO pin support.
*/
int __init trout_init_gpio(void)
{
int i;
for(i = TROUT_INT_START; i <= TROUT_INT_END; i++) {
irq_set_chip_and_handler(i, &trout_gpio_irq_chip,
handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
gpiochip_add(&msm_gpio_banks[i].chip);
irq_set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH);
irq_set_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler);
irq_set_irq_wake(MSM_GPIO_TO_INT(17), 1);
return 0;
}
postcore_initcall(trout_init_gpio);
/* linux/arch/arm/mach-msm/board-trout-mmc.c
** Author: Brian Swetland <swetland@google.com>
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/err.h>
#include <linux/debugfs.h>
#include <asm/io.h>
#include <mach/vreg.h>
#include <linux/platform_data/mmc-msm_sdcc.h>
#include "devices.h"
#include "board-trout.h"
#include "proc_comm.h"
#define DEBUG_SDSLOT_VDD 1
/* ---- COMMON ---- */
static void config_gpio_table(uint32_t *table, int len)
{
int n;
unsigned id;
for(n = 0; n < len; n++) {
id = table[n];
msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0);
}
}
/* ---- SDCARD ---- */
static uint32_t sdcard_on_gpio_table[] = {
PCOM_GPIO_CFG(62, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA), /* CLK */
PCOM_GPIO_CFG(63, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* CMD */
PCOM_GPIO_CFG(64, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT3 */
PCOM_GPIO_CFG(65, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT2 */
PCOM_GPIO_CFG(66, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT1 */
PCOM_GPIO_CFG(67, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT0 */
};
static uint32_t sdcard_off_gpio_table[] = {
PCOM_GPIO_CFG(62, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CLK */
PCOM_GPIO_CFG(63, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CMD */
PCOM_GPIO_CFG(64, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT3 */
PCOM_GPIO_CFG(65, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT2 */
PCOM_GPIO_CFG(66, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT1 */
PCOM_GPIO_CFG(67, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT0 */
};
static uint opt_disable_sdcard;
static int __init trout_disablesdcard_setup(char *str)
{
int cal = simple_strtol(str, NULL, 0);
opt_disable_sdcard = cal;
return 1;
}
__setup("board_trout.disable_sdcard=", trout_disablesdcard_setup);
static struct vreg *vreg_sdslot; /* SD slot power */
struct mmc_vdd_xlat {
int mask;
int level;
};
static struct mmc_vdd_xlat mmc_vdd_table[] = {
{ MMC_VDD_165_195, 1800 },
{ MMC_VDD_20_21, 2050 },
{ MMC_VDD_21_22, 2150 },
{ MMC_VDD_22_23, 2250 },
{ MMC_VDD_23_24, 2350 },
{ MMC_VDD_24_25, 2450 },
{ MMC_VDD_25_26, 2550 },
{ MMC_VDD_26_27, 2650 },
{ MMC_VDD_27_28, 2750 },
{ MMC_VDD_28_29, 2850 },
{ MMC_VDD_29_30, 2950 },
};
static unsigned int sdslot_vdd = 0xffffffff;
static unsigned int sdslot_vreg_enabled;
static uint32_t trout_sdslot_switchvdd(struct device *dev, unsigned int vdd)
{
int i, rc;
BUG_ON(!vreg_sdslot);
if (vdd == sdslot_vdd)
return 0;
sdslot_vdd = vdd;
if (vdd == 0) {
#if DEBUG_SDSLOT_VDD
printk("%s: Disabling SD slot power\n", __func__);
#endif
config_gpio_table(sdcard_off_gpio_table,
ARRAY_SIZE(sdcard_off_gpio_table));
vreg_disable(vreg_sdslot);
sdslot_vreg_enabled = 0;
return 0;
}
if (!sdslot_vreg_enabled) {
rc = vreg_enable(vreg_sdslot);
if (rc) {
printk(KERN_ERR "%s: Error enabling vreg (%d)\n",
__func__, rc);
}
config_gpio_table(sdcard_on_gpio_table,
ARRAY_SIZE(sdcard_on_gpio_table));
sdslot_vreg_enabled = 1;
}
for (i = 0; i < ARRAY_SIZE(mmc_vdd_table); i++) {
if (mmc_vdd_table[i].mask == (1 << vdd)) {
#if DEBUG_SDSLOT_VDD
printk("%s: Setting level to %u\n",
__func__, mmc_vdd_table[i].level);
#endif
rc = vreg_set_level(vreg_sdslot,
mmc_vdd_table[i].level);
if (rc) {
printk(KERN_ERR
"%s: Error setting vreg level (%d)\n",
__func__, rc);
}
return 0;
}
}
printk(KERN_ERR "%s: Invalid VDD %d specified\n", __func__, vdd);
return 0;
}
static unsigned int trout_sdslot_status(struct device *dev)
{
unsigned int status;
status = (unsigned int) gpio_get_value(TROUT_GPIO_SDMC_CD_N);
return (!status);
}
#define TROUT_MMC_VDD MMC_VDD_165_195 | MMC_VDD_20_21 | MMC_VDD_21_22 \
| MMC_VDD_22_23 | MMC_VDD_23_24 | MMC_VDD_24_25 \
| MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 \
| MMC_VDD_28_29 | MMC_VDD_29_30
static struct msm_mmc_platform_data trout_sdslot_data = {
.ocr_mask = TROUT_MMC_VDD,
.status = trout_sdslot_status,
.translate_vdd = trout_sdslot_switchvdd,
};
int __init trout_init_mmc(unsigned int sys_rev)
{
sdslot_vreg_enabled = 0;
vreg_sdslot = vreg_get(0, "gp6");
if (IS_ERR(vreg_sdslot))
return PTR_ERR(vreg_sdslot);
irq_set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1);
if (!opt_disable_sdcard)
msm_add_sdcc(2, &trout_sdslot_data,
TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 0);
else
printk(KERN_INFO "trout: SD-Card interface disabled\n");
return 0;
}
/* linux/arch/arm/mach-msm/board-trout-mddi.c
** Author: Brian Swetland <swetland@google.com>
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/system_info.h>
#include <linux/platform_data/video-msm_fb.h>
#include <mach/vreg.h>
#include "board-trout.h"
#include "proc_comm.h"
#include "clock-pcom.h"
#include "devices.h"
#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255
#define MDDI_CLIENT_CORE_BASE 0x108000
#define LCD_CONTROL_BLOCK_BASE 0x110000
#define SPI_BLOCK_BASE 0x120000
#define I2C_BLOCK_BASE 0x130000
#define PWM_BLOCK_BASE 0x140000
#define GPIO_BLOCK_BASE 0x150000
#define SYSTEM_BLOCK1_BASE 0x160000
#define SYSTEM_BLOCK2_BASE 0x170000
#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)
#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
#define V_VDDE2E_VDD2_GPIO 0
#define MDDI_RST_N 82
#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
#define START (LCD_CONTROL_BLOCK_BASE|0x08)
#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
#define SSICTL (SPI_BLOCK_BASE|0x00)
#define SSITIME (SPI_BLOCK_BASE|0x04)
#define SSITX (SPI_BLOCK_BASE|0x08)
#define SSIRX (SPI_BLOCK_BASE|0x0C)
#define SSIINTC (SPI_BLOCK_BASE|0x10)
#define SSIINTS (SPI_BLOCK_BASE|0x14)
#define SSIDBG1 (SPI_BLOCK_BASE|0x18)
#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
#define SSIID (SPI_BLOCK_BASE|0x20)
#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
#define GPIODATA (GPIO_BLOCK_BASE|0x00)
#define GPIODIR (GPIO_BLOCK_BASE|0x04)
#define GPIOIS (GPIO_BLOCK_BASE|0x08)
#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
#define GPIOIE (GPIO_BLOCK_BASE|0x14)
#define GPIORIS (GPIO_BLOCK_BASE|0x18)
#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
#define GPIOIC (GPIO_BLOCK_BASE|0x20)
#define GPIOOMS (GPIO_BLOCK_BASE|0x24)
#define GPIOPC (GPIO_BLOCK_BASE|0x28)
#define GPIOID (GPIO_BLOCK_BASE|0x30)
#define SPI_WRITE(reg, val) \
{ SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
{ 0, 5 },
#define SPI_WRITE1(reg) \
{ SSITX, (reg) & 0xff }, \
{ 0, 5 },
struct mddi_table {
uint32_t reg;
uint32_t value;
};
static struct mddi_table mddi_toshiba_init_table[] = {
{ DPSET0, 0x09e90046 },
{ DPSET1, 0x00000118 },
{ DPSUS, 0x00000000 },
{ DPRUN, 0x00000001 },
{ 1, 14 }, /* msleep 14 */
{ SYSCKENA, 0x00000001 },
{ CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */
{ GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
{ GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */
{ GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */
{ GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */
{ WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */
{ GPIOIBE, 0x000003FF },
{ GPIOIS, 0x00000000 },
{ GPIOIC, 0x000003FF },
{ GPIOIE, 0x00000000 },
{ GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
{ 1, 1 }, /* msleep 1 */
{ GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
{ DRAMPWR, 0x00000001 }, /* eDRAM power */
};
#define GPIOSEL_VWAKEINT (1U << 0)
#define INTMASK_VWAKEOUT (1U << 0)
static int trout_new_backlight = 1;
static struct vreg *vreg_mddi_1v5;
static struct vreg *vreg_lcm_2v85;
static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,
struct mddi_table *table, size_t count)
{
int i;
for (i = 0; i < count; i++) {
uint32_t reg = table[i].reg;
uint32_t value = table[i].value;
if (reg == 0)
udelay(value);
else if (reg == 1)
msleep(value);
else
client_data->remote_write(client_data, value, reg);
}
}
static int trout_mddi_toshiba_client_init(
struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
int panel_id;
client_data->auto_hibernate(client_data, 0);
trout_process_mddi_table(client_data, mddi_toshiba_init_table,
ARRAY_SIZE(mddi_toshiba_init_table));
client_data->auto_hibernate(client_data, 1);
panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
if (panel_id > 1) {
printk(KERN_WARNING "unknown panel id at mddi_enable\n");
return -1;
}
return 0;
}
static int trout_mddi_toshiba_client_uninit(
struct msm_mddi_bridge_platform_data *bridge_data,
struct msm_mddi_client_data *client_data)
{
return 0;
}
static struct resource resources_msm_fb[] = {
{
.start = MSM_FB_BASE,
.end = MSM_FB_BASE + MSM_FB_SIZE,
.flags = IORESOURCE_MEM,
},
};
struct msm_mddi_bridge_platform_data toshiba_client_data = {
.init = trout_mddi_toshiba_client_init,
.uninit = trout_mddi_toshiba_client_uninit,
.fb_data = {
.xres = 320,
.yres = 480,
.width = 45,
.height = 67,
.output_format = 0,
},
};
static struct msm_mddi_platform_data mddi_pdata = {
.clk_rate = 122880000,
.fb_resource = resources_msm_fb,
.num_clients = 1,
.client_platform_data = {
{
.product_id = (0xd263 << 16 | 0),
.name = "mddi_c_d263_0000",
.id = 0,
.client_data = &toshiba_client_data,
.clk_rate = 0,
},
},
};
int __init trout_init_panel(void)
{
int rc;
if (!machine_is_trout())
return 0;
vreg_mddi_1v5 = vreg_get(0, "gp2");
if (IS_ERR(vreg_mddi_1v5))
return PTR_ERR(vreg_mddi_1v5);
vreg_lcm_2v85 = vreg_get(0, "gp4");
if (IS_ERR(vreg_lcm_2v85))
return PTR_ERR(vreg_lcm_2v85);
trout_new_backlight = system_rev >= 5;
if (trout_new_backlight) {
uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,
GPIO_NO_PULL, GPIO_8MA);
msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
} else {
uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
GPIO_NO_PULL, GPIO_8MA);
uint32_t id = P_GP_CLK;
uint32_t rate = 19200000;
msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
if (id < 0)
pr_err("trout_init_panel: set clock rate failed\n");
}
rc = platform_device_register(&msm_device_mdp);
if (rc)
return rc;
msm_device_mddi0.dev.platform_data = &mddi_pdata;
return platform_device_register(&msm_device_mddi0);
}
device_initcall(trout_init_panel);
/* linux/arch/arm/mach-msm/board-trout.c
*
* Copyright (C) 2009 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/clkdev.h>
#include <linux/memblock.h>
#include <asm/system_info.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <mach/hardware.h>
#include <mach/msm_iomap.h>
#include "devices.h"
#include "board-trout.h"
#include "common.h"
extern int trout_init_mmc(unsigned int);
static struct platform_device *devices[] __initdata = {
&msm_clock_7x01a,
&msm_device_gpio_7201,
&msm_device_uart3,
&msm_device_smd,
&msm_device_nand,
&msm_device_hsusb,
&msm_device_i2c,
};
static void __init trout_init_early(void)
{
arch_ioremap_caller = __msm_ioremap_caller;
}
static void __init trout_init_irq(void)
{
msm_init_irq();
}
static void __init trout_fixup(struct tag *tags, char **cmdline)
{
memblock_add(PHYS_OFFSET, 101*SZ_1M);
}
static void __init trout_init(void)
{
int rc;
platform_add_devices(devices, ARRAY_SIZE(devices));
if (IS_ENABLED(CONFIG_MMC)) {
rc = trout_init_mmc(system_rev);
if (rc)
pr_crit("MMC init failure (%d)\n", rc);
}
}
static struct map_desc trout_io_desc[] __initdata = {
{
.virtual = (unsigned long)TROUT_CPLD_BASE,
.pfn = __phys_to_pfn(TROUT_CPLD_START),
.length = TROUT_CPLD_SIZE,
.type = MT_DEVICE_NONSHARED
}
};
static void __init trout_map_io(void)
{
msm_map_common_io();
iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc));
#if defined(CONFIG_DEBUG_MSM_UART) && (CONFIG_DEBUG_UART_PHYS == 0xa9c00000)
/* route UART3 to the "H2W" extended usb connector */
writeb(0x80, TROUT_CPLD_BASE + 0x00);
#endif
}
static void __init trout_init_late(void)
{
smd_debugfs_init();
}
MACHINE_START(TROUT, "HTC Dream")
.atag_offset = 0x100,
.fixup = trout_fixup,
.map_io = trout_map_io,
.init_early = trout_init_early,
.init_irq = trout_init_irq,
.init_machine = trout_init,
.init_late = trout_init_late,
.init_time = msm7x01_timer_init,
MACHINE_END
/* linux/arch/arm/mach-msm/board-trout.h
** Author: Brian Swetland <swetland@google.com>
*/
#ifndef __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
#define __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
#include "common.h"
#define MSM_SMI_BASE 0x00000000
#define MSM_SMI_SIZE 0x00800000
#define MSM_EBI_BASE 0x10000000
#define MSM_EBI_SIZE 0x06e00000
#define MSM_PMEM_GPU0_BASE 0x00000000
#define MSM_PMEM_GPU0_SIZE 0x00700000
#define MSM_PMEM_MDP_BASE 0x02000000
#define MSM_PMEM_MDP_SIZE 0x00800000
#define MSM_PMEM_ADSP_BASE 0x02800000
#define MSM_PMEM_ADSP_SIZE 0x00800000
#define MSM_PMEM_CAMERA_BASE 0x03000000
#define MSM_PMEM_CAMERA_SIZE 0x00800000
#define MSM_FB_BASE 0x03800000
#define MSM_FB_SIZE 0x00100000
#define MSM_LINUX_BASE MSM_EBI_BASE
#define MSM_LINUX_SIZE 0x06500000
#define MSM_PMEM_GPU1_SIZE 0x800000
#define MSM_PMEM_GPU1_BASE (MSM_RAM_CONSOLE_BASE - MSM_PMEM_GPU1_SIZE)
#define MSM_RAM_CONSOLE_BASE (MSM_EBI_BASE + 0x6d00000)
#define MSM_RAM_CONSOLE_SIZE (128 * SZ_1K)
#if (MSM_FB_BASE + MSM_FB_SIZE) >= (MSM_PMEM_GPU1_BASE)
#error invalid memory map
#endif
#define DECLARE_MSM_IOMAP
#include <mach/msm_iomap.h>
#define TROUT_4_BALL_UP_0 1
#define TROUT_4_BALL_LEFT_0 18
#define TROUT_4_BALL_DOWN_0 57
#define TROUT_4_BALL_RIGHT_0 91
#define TROUT_5_BALL_UP_0 94
#define TROUT_5_BALL_LEFT_0 18
#define TROUT_5_BALL_DOWN_0 90
#define TROUT_5_BALL_RIGHT_0 19
#define TROUT_POWER_KEY 20
#define TROUT_4_TP_LS_EN 19
#define TROUT_5_TP_LS_EN 1
#define TROUT_CPLD_BASE IOMEM(0xE8100000)
#define TROUT_CPLD_START 0x98000000
#define TROUT_CPLD_SIZE SZ_4K
#define TROUT_GPIO_CABLE_IN1 (83)
#define TROUT_GPIO_CABLE_IN2 (49)
#define TROUT_GPIO_START (128)
#define TROUT_GPIO_INT_MASK0_REG (0x0c)
#define TROUT_GPIO_INT_STAT0_REG (0x0e)
#define TROUT_GPIO_INT_MASK1_REG (0x14)
#define TROUT_GPIO_INT_STAT1_REG (0x10)
#define TROUT_GPIO_HAPTIC_PWM (28)
#define TROUT_GPIO_PS_HOLD (25)
#define TROUT_GPIO_MISC2_BASE (TROUT_GPIO_START + 0x00)
#define TROUT_GPIO_MISC3_BASE (TROUT_GPIO_START + 0x08)
#define TROUT_GPIO_MISC4_BASE (TROUT_GPIO_START + 0x10)
#define TROUT_GPIO_MISC5_BASE (TROUT_GPIO_START + 0x18)
#define TROUT_GPIO_INT2_BASE (TROUT_GPIO_START + 0x20)
#define TROUT_GPIO_MISC1_BASE (TROUT_GPIO_START + 0x28)
#define TROUT_GPIO_VIRTUAL_BASE (TROUT_GPIO_START + 0x30)
#define TROUT_GPIO_INT5_BASE (TROUT_GPIO_START + 0x48)
#define TROUT_GPIO_CHARGER_EN (TROUT_GPIO_MISC2_BASE + 0)
#define TROUT_GPIO_ISET (TROUT_GPIO_MISC2_BASE + 1)
#define TROUT_GPIO_H2W_DAT_DIR (TROUT_GPIO_MISC2_BASE + 2)
#define TROUT_GPIO_H2W_CLK_DIR (TROUT_GPIO_MISC2_BASE + 3)
#define TROUT_GPIO_H2W_DAT_GPO (TROUT_GPIO_MISC2_BASE + 4)
#define TROUT_GPIO_H2W_CLK_GPO (TROUT_GPIO_MISC2_BASE + 5)
#define TROUT_GPIO_H2W_SEL0 (TROUT_GPIO_MISC2_BASE + 6)
#define TROUT_GPIO_H2W_SEL1 (TROUT_GPIO_MISC2_BASE + 7)
#define TROUT_GPIO_SPOTLIGHT_EN (TROUT_GPIO_MISC3_BASE + 0)
#define TROUT_GPIO_FLASH_EN (TROUT_GPIO_MISC3_BASE + 1)
#define TROUT_GPIO_I2C_PULL (TROUT_GPIO_MISC3_BASE + 2)
#define TROUT_GPIO_TP_I2C_PULL (TROUT_GPIO_MISC3_BASE + 3)
#define TROUT_GPIO_TP_EN (TROUT_GPIO_MISC3_BASE + 4)
#define TROUT_GPIO_JOG_EN (TROUT_GPIO_MISC3_BASE + 5)
#define TROUT_GPIO_UI_LED_EN (TROUT_GPIO_MISC3_BASE + 6)
#define TROUT_GPIO_QTKEY_LED_EN (TROUT_GPIO_MISC3_BASE + 7)
#define TROUT_GPIO_VCM_PWDN (TROUT_GPIO_MISC4_BASE + 0)
#define TROUT_GPIO_USB_H2W_SW (TROUT_GPIO_MISC4_BASE + 1)
#define TROUT_GPIO_COMPASS_RST_N (TROUT_GPIO_MISC4_BASE + 2)
#define TROUT_GPIO_HAPTIC_EN_UP (TROUT_GPIO_MISC4_BASE + 3)
#define TROUT_GPIO_HAPTIC_EN_MAIN (TROUT_GPIO_MISC4_BASE + 4)
#define TROUT_GPIO_USB_PHY_RST_N (TROUT_GPIO_MISC4_BASE + 5)
#define TROUT_GPIO_WIFI_PA_RESETX (TROUT_GPIO_MISC4_BASE + 6)
#define TROUT_GPIO_WIFI_EN (TROUT_GPIO_MISC4_BASE + 7)
#define TROUT_GPIO_BT_32K_EN (TROUT_GPIO_MISC5_BASE + 0)
#define TROUT_GPIO_MAC_32K_EN (TROUT_GPIO_MISC5_BASE + 1)
#define TROUT_GPIO_MDDI_32K_EN (TROUT_GPIO_MISC5_BASE + 2)
#define TROUT_GPIO_COMPASS_32K_EN (TROUT_GPIO_MISC5_BASE + 3)
#define TROUT_GPIO_NAVI_ACT_N (TROUT_GPIO_INT2_BASE + 0)
#define TROUT_GPIO_COMPASS_IRQ (TROUT_GPIO_INT2_BASE + 1)
#define TROUT_GPIO_SLIDING_DET (TROUT_GPIO_INT2_BASE + 2)
#define TROUT_GPIO_AUD_HSMIC_DET_N (TROUT_GPIO_INT2_BASE + 3)
#define TROUT_GPIO_SD_DOOR_N (TROUT_GPIO_INT2_BASE + 4)
#define TROUT_GPIO_CAM_BTN_STEP1_N (TROUT_GPIO_INT2_BASE + 5)
#define TROUT_GPIO_CAM_BTN_STEP2_N (TROUT_GPIO_INT2_BASE + 6)
#define TROUT_GPIO_TP_ATT_N (TROUT_GPIO_INT2_BASE + 7)
#define TROUT_GPIO_BANK0_FIRST_INT_SOURCE (TROUT_GPIO_NAVI_ACT_N)
#define TROUT_GPIO_BANK0_LAST_INT_SOURCE (TROUT_GPIO_TP_ATT_N)
#define TROUT_GPIO_H2W_DAT_GPI (TROUT_GPIO_MISC1_BASE + 0)
#define TROUT_GPIO_H2W_CLK_GPI (TROUT_GPIO_MISC1_BASE + 1)
#define TROUT_GPIO_CPLD128_VER_0 (TROUT_GPIO_MISC1_BASE + 4)
#define TROUT_GPIO_CPLD128_VER_1 (TROUT_GPIO_MISC1_BASE + 5)
#define TROUT_GPIO_CPLD128_VER_2 (TROUT_GPIO_MISC1_BASE + 6)
#define TROUT_GPIO_CPLD128_VER_3 (TROUT_GPIO_MISC1_BASE + 7)
#define TROUT_GPIO_SDMC_CD_N (TROUT_GPIO_VIRTUAL_BASE + 0)
#define TROUT_GPIO_END (TROUT_GPIO_SDMC_CD_N)
#define TROUT_GPIO_BANK1_FIRST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
#define TROUT_GPIO_BANK1_LAST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
#define TROUT_GPIO_VIRTUAL_TO_REAL_OFFSET \
(TROUT_GPIO_INT5_BASE - TROUT_GPIO_VIRTUAL_BASE)
#define TROUT_INT_START (NR_MSM_IRQS + NR_GPIO_IRQS)
#define TROUT_INT_BANK0_COUNT (8)
#define TROUT_INT_BANK1_START (TROUT_INT_START + TROUT_INT_BANK0_COUNT)
#define TROUT_INT_BANK1_COUNT (1)
#define TROUT_INT_END (TROUT_INT_START + TROUT_INT_BANK0_COUNT + \
TROUT_INT_BANK1_COUNT - 1)
#define TROUT_GPIO_TO_INT(n) (((n) <= TROUT_GPIO_BANK0_LAST_INT_SOURCE) ? \
(TROUT_INT_START - TROUT_GPIO_BANK0_FIRST_INT_SOURCE + (n)) : \
(TROUT_INT_BANK1_START - TROUT_GPIO_BANK1_FIRST_INT_SOURCE + (n)))
#define TROUT_INT_TO_BANK(n) ((n - TROUT_INT_START) / TROUT_INT_BANK0_COUNT)
#define TROUT_INT_TO_MASK(n) (1U << ((n - TROUT_INT_START) & 7))
#define TROUT_BANK_TO_MASK_REG(bank) \
(bank ? TROUT_GPIO_INT_MASK1_REG : TROUT_GPIO_INT_MASK0_REG)
#define TROUT_BANK_TO_STAT_REG(bank) \
(bank ? TROUT_GPIO_INT_STAT1_REG : TROUT_GPIO_INT_STAT0_REG)
#endif /* GUARD */
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <mach/clk.h>
#include "proc_comm.h"
#include "clock.h"
#include "clock-pcom.h"
struct clk_pcom {
unsigned id;
unsigned long flags;
struct msm_clk msm_clk;
};
static inline struct clk_pcom *to_clk_pcom(struct clk_hw *hw)
{
return container_of(to_msm_clk(hw), struct clk_pcom, msm_clk);
}
static int pc_clk_enable(struct clk_hw *hw)
{
unsigned id = to_clk_pcom(hw)->id;
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
static void pc_clk_disable(struct clk_hw *hw)
{
unsigned id = to_clk_pcom(hw)->id;
msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
}
static int pc_clk_reset(struct clk_hw *hw, enum clk_reset_action action)
{
int rc;
unsigned id = to_clk_pcom(hw)->id;
if (action == CLK_RESET_ASSERT)
rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
else
rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
static int pc_clk_set_rate(struct clk_hw *hw, unsigned long new_rate,
unsigned long p_rate)
{
struct clk_pcom *p = to_clk_pcom(hw);
unsigned id = p->id, rate = new_rate;
int rc;
/*
* The rate _might_ be rounded off to the nearest KHz value by the
* remote function. So a return value of 0 doesn't necessarily mean
* that the exact rate was set successfully.
*/
if (p->flags & CLKFLAG_MIN)
rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
else
rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
static unsigned long pc_clk_recalc_rate(struct clk_hw *hw, unsigned long p_rate)
{
unsigned id = to_clk_pcom(hw)->id;
if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
return 0;
else
return id;
}
static int pc_clk_is_enabled(struct clk_hw *hw)
{
unsigned id = to_clk_pcom(hw)->id;
if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
return 0;
else
return id;
}
static long pc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *p_rate)
{
/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
return rate;
}
static struct clk_ops clk_ops_pcom = {
.enable = pc_clk_enable,
.disable = pc_clk_disable,
.set_rate = pc_clk_set_rate,
.recalc_rate = pc_clk_recalc_rate,
.is_enabled = pc_clk_is_enabled,
.round_rate = pc_clk_round_rate,
};
static int msm_clock_pcom_probe(struct platform_device *pdev)
{
const struct pcom_clk_pdata *pdata = pdev->dev.platform_data;
int i, ret;
for (i = 0; i < pdata->num_lookups; i++) {
const struct clk_pcom_desc *desc = &pdata->lookup[i];
struct clk *c;
struct clk_pcom *p;
struct clk_hw *hw;
struct clk_init_data init;
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (!p)
return -ENOMEM;
p->id = desc->id;
p->flags = desc->flags;
p->msm_clk.reset = pc_clk_reset;
hw = &p->msm_clk.hw;
hw->init = &init;
init.name = desc->name;
init.ops = &clk_ops_pcom;
init.num_parents = 0;
init.flags = CLK_IS_ROOT;
if (!(p->flags & CLKFLAG_AUTO_OFF))
init.flags |= CLK_IGNORE_UNUSED;
c = devm_clk_register(&pdev->dev, hw);
ret = clk_register_clkdev(c, desc->con, desc->dev);
if (ret)
return ret;
}
return 0;
}
static struct platform_driver msm_clock_pcom_driver = {
.probe = msm_clock_pcom_probe,
.driver = {
.name = "msm-clock-pcom",
},
};
module_platform_driver(msm_clock_pcom_driver);
MODULE_LICENSE("GPL v2");
/*
* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
/* clock IDs used by the modem processor */
#define P_ACPU_CLK 0 /* Applications processor clock */
#define P_ADM_CLK 1 /* Applications data mover clock */
#define P_ADSP_CLK 2 /* ADSP clock */
#define P_EBI1_CLK 3 /* External bus interface 1 clock */
#define P_EBI2_CLK 4 /* External bus interface 2 clock */
#define P_ECODEC_CLK 5 /* External CODEC clock */
#define P_EMDH_CLK 6 /* External MDDI host clock */
#define P_GP_CLK 7 /* General purpose clock */
#define P_GRP_3D_CLK 8 /* Graphics clock */
#define P_I2C_CLK 9 /* I2C clock */
#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
#define P_IMEM_CLK 12 /* Internal graphics memory clock */
#define P_MDC_CLK 13 /* MDDI client clock */
#define P_MDP_CLK 14 /* Mobile display processor clock */
#define P_PBUS_CLK 15 /* Peripheral bus clock */
#define P_PCM_CLK 16 /* PCM clock */
#define P_PMDH_CLK 17 /* Primary MDDI host clock */
#define P_SDAC_CLK 18 /* Stereo DAC clock */
#define P_SDC1_CLK 19 /* Secure Digital Card clocks */
#define P_SDC1_P_CLK 20
#define P_SDC2_CLK 21
#define P_SDC2_P_CLK 22
#define P_SDC3_CLK 23
#define P_SDC3_P_CLK 24
#define P_SDC4_CLK 25
#define P_SDC4_P_CLK 26
#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */
#define P_TSIF_REF_CLK 28
#define P_TV_DAC_CLK 29 /* TV clocks */
#define P_TV_ENC_CLK 30
#define P_UART1_CLK 31 /* UART clocks */
#define P_UART2_CLK 32
#define P_UART3_CLK 33
#define P_UART1DM_CLK 34
#define P_UART2DM_CLK 35
#define P_USB_HS_CLK 36 /* High speed USB core clock */
#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */
#define P_USB_OTG_CLK 38 /* Full speed USB clock */
#define P_VDC_CLK 39 /* Video controller clock */
#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */
#define P_VFE_CLK 41 /* VFE MDDI client clock */
#define P_MDP_LCDC_PCLK_CLK 42
#define P_MDP_LCDC_PAD_PCLK_CLK 43
#define P_MDP_VSYNC_CLK 44
#define P_SPI_CLK 45
#define P_VFE_AXI_CLK 46
#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */
#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */
#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */
#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */
#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */
#define P_USB_PHY_CLK 52 /* USB PHY clock */
#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */
#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */
#define P_CAM_M_CLK 56
#define P_CAMIF_PAD_P_CLK 57
#define P_GRP_2D_CLK 58
#define P_GRP_2D_P_CLK 59
#define P_I2S_CLK 60
#define P_JPEG_CLK 61
#define P_JPEG_P_CLK 62
#define P_LPA_CODEC_CLK 63
#define P_LPA_CORE_CLK 64
#define P_LPA_P_CLK 65
#define P_MDC_IO_CLK 66
#define P_MDC_P_CLK 67
#define P_MFC_CLK 68
#define P_MFC_DIV2_CLK 69
#define P_MFC_P_CLK 70
#define P_QUP_I2C_CLK 71
#define P_ROTATOR_IMEM_CLK 72
#define P_ROTATOR_P_CLK 73
#define P_VFE_CAMIF_CLK 74
#define P_VFE_P_CLK 75
#define P_VPE_CLK 76
#define P_I2C_2_CLK 77
#define P_MI2S_CODEC_RX_S_CLK 78
#define P_MI2S_CODEC_RX_M_CLK 79
#define P_MI2S_CODEC_TX_S_CLK 80
#define P_MI2S_CODEC_TX_M_CLK 81
#define P_PMDH_P_CLK 82
#define P_EMDH_P_CLK 83
#define P_SPI_P_CLK 84
#define P_TSIF_P_CLK 85
#define P_MDP_P_CLK 86
#define P_SDAC_M_CLK 87
#define P_MI2S_S_CLK 88
#define P_MI2S_M_CLK 89
#define P_AXI_ROTATOR_CLK 90
#define P_HDMI_CLK 91
#define P_CSI0_CLK 92
#define P_CSI0_VFE_CLK 93
#define P_CSI0_P_CLK 94
#define P_CSI1_CLK 95
#define P_CSI1_VFE_CLK 96
#define P_CSI1_P_CLK 97
#define P_GSBI_CLK 98
#define P_GSBI_P_CLK 99
#define P_CE_CLK 100 /* Crypto engine */
#define P_CODEC_SSBI_CLK 101
#define P_NR_CLKS 102
struct clk_pcom_desc {
unsigned id;
const char *name;
const char *con;
const char *dev;
unsigned long flags;
};
struct pcom_clk_pdata {
struct clk_pcom_desc *lookup;
u32 num_lookups;
};
#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
.id = P_##clk_id, \
.name = #clk_id, \
.con = clk_name, \
.dev = clk_dev, \
.flags = clk_flags, \
}
#endif
/* arch/arm/mach-msm/clock.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include "clock.h"
int clk_reset(struct clk *clk, enum clk_reset_action action)
{
struct clk_hw *hw = __clk_get_hw(clk);
struct msm_clk *m = to_msm_clk(hw);
return m->reset(hw, action);
}
EXPORT_SYMBOL(clk_reset);
/* arch/arm/mach-msm/clock.h
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
#define __ARCH_ARM_MACH_MSM_CLOCK_H
#include <linux/clk-provider.h>
#include <mach/clk.h>
#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
#define CLKFLAG_AUTO_OFF 0x00000200
#define CLKFLAG_MIN 0x00000400
#define CLKFLAG_MAX 0x00000800
#define OFF CLKFLAG_AUTO_OFF
#define CLK_MIN CLKFLAG_MIN
#define CLK_MAX CLKFLAG_MAX
#define CLK_MINMAX (CLK_MIN | CLK_MAX)
struct msm_clk {
int (*reset)(struct clk_hw *hw, enum clk_reset_action action);
struct clk_hw hw;
};
static inline struct msm_clk *to_msm_clk(struct clk_hw *hw)
{
return container_of(hw, struct msm_clk, hw);
}
#endif
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MACH_COMMON_H
#define __MACH_COMMON_H
extern void msm7x01_timer_init(void);
extern void msm7x30_timer_init(void);
extern void qsd8x50_timer_init(void);
extern void msm_map_common_io(void);
extern void msm_map_msm7x30_io(void);
extern void msm_map_qsd8x50_io(void);
extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller);
struct msm_mmc_platform_data;
extern void msm_add_devices(void);
extern void msm_init_irq(void);
extern void msm_init_gpio(void);
extern int msm_add_sdcc(unsigned int controller,
struct msm_mmc_platform_data *plat,
unsigned int stat_irq, unsigned long stat_irq_flags);
#if defined(CONFIG_MSM_SMD) && defined(CONFIG_DEBUG_FS)
extern int smd_debugfs_init(void);
#else
static inline int smd_debugfs_init(void) { return 0; }
#endif
#endif
/* linux/arch/arm/mach-msm/devices.c
*
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/clkdev.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
#include "devices.h"
#include <asm/mach/flash.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include "clock.h"
#include "clock-pcom.h"
#include <linux/platform_data/mmc-msm_sdcc.h>
static struct resource msm_gpio_resources[] = {
{
.start = 32 + 0,
.end = 32 + 0,
.flags = IORESOURCE_IRQ,
},
{
.start = 32 + 1,
.end = 32 + 1,
.flags = IORESOURCE_IRQ,
},
{
.start = 0xa9200800,
.end = 0xa9200800 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio1"
},
{
.start = 0xa9300C00,
.end = 0xa9300C00 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio2"
},
};
struct platform_device msm_device_gpio_7201 = {
.name = "gpio-msm-7201",
.num_resources = ARRAY_SIZE(msm_gpio_resources),
.resource = msm_gpio_resources,
};
static struct resource resources_uart1[] = {
{
.start = INT_UART1,
.end = INT_UART1,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART1_PHYS,
.end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "uart_resource"
},
};
static struct resource resources_uart2[] = {
{
.start = INT_UART2,
.end = INT_UART2,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART2_PHYS,
.end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "uart_resource"
},
};
static struct resource resources_uart3[] = {
{
.start = INT_UART3,
.end = INT_UART3,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART3_PHYS,
.end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "uart_resource"
},
};
struct platform_device msm_device_uart1 = {
.name = "msm_serial",
.id = 0,
.num_resources = ARRAY_SIZE(resources_uart1),
.resource = resources_uart1,
};
struct platform_device msm_device_uart2 = {
.name = "msm_serial",
.id = 1,
.num_resources = ARRAY_SIZE(resources_uart2),
.resource = resources_uart2,
};
struct platform_device msm_device_uart3 = {
.name = "msm_serial",
.id = 2,
.num_resources = ARRAY_SIZE(resources_uart3),
.resource = resources_uart3,
};
static struct resource resources_i2c[] = {
{
.start = MSM_I2C_PHYS,
.end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_PWB_I2C,
.end = INT_PWB_I2C,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_i2c = {
.name = "msm_i2c",
.id = 0,
.num_resources = ARRAY_SIZE(resources_i2c),
.resource = resources_i2c,
};
static struct resource resources_hsusb[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb = {
.name = "msm_hsusb",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb),
.resource = resources_hsusb,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct flash_platform_data msm_nand_data = {
.parts = NULL,
.nr_parts = 0,
};
static struct resource resources_nand[] = {
[0] = {
.start = 7,
.end = 7,
.flags = IORESOURCE_DMA,
},
};
struct platform_device msm_device_nand = {
.name = "msm_nand",
.id = -1,
.num_resources = ARRAY_SIZE(resources_nand),
.resource = resources_nand,
.dev = {
.platform_data = &msm_nand_data,
},
};
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
};
static struct resource resources_sdc1[] = {
{
.start = MSM_SDC1_PHYS,
.end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC1_0,
.end = INT_SDC1_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc2[] = {
{
.start = MSM_SDC2_PHYS,
.end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC2_0,
.end = INT_SDC2_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc3[] = {
{
.start = MSM_SDC3_PHYS,
.end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC3_0,
.end = INT_SDC3_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc4[] = {
{
.start = MSM_SDC4_PHYS,
.end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC4_0,
.end = INT_SDC4_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
struct platform_device msm_device_sdc1 = {
.name = "msm_sdcc",
.id = 1,
.num_resources = ARRAY_SIZE(resources_sdc1),
.resource = resources_sdc1,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc2 = {
.name = "msm_sdcc",
.id = 2,
.num_resources = ARRAY_SIZE(resources_sdc2),
.resource = resources_sdc2,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc3 = {
.name = "msm_sdcc",
.id = 3,
.num_resources = ARRAY_SIZE(resources_sdc3),
.resource = resources_sdc3,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc4 = {
.name = "msm_sdcc",
.id = 4,
.num_resources = ARRAY_SIZE(resources_sdc4),
.resource = resources_sdc4,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct platform_device *msm_sdcc_devices[] __initdata = {
&msm_device_sdc1,
&msm_device_sdc2,
&msm_device_sdc3,
&msm_device_sdc4,
};
int __init msm_add_sdcc(unsigned int controller,
struct msm_mmc_platform_data *plat,
unsigned int stat_irq, unsigned long stat_irq_flags)
{
struct platform_device *pdev;
struct resource *res;
if (controller < 1 || controller > 4)
return -EINVAL;
pdev = msm_sdcc_devices[controller-1];
pdev->dev.platform_data = plat;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
if (!res)
return -EINVAL;
else if (stat_irq) {
res->start = res->end = stat_irq;
res->flags &= ~IORESOURCE_DISABLED;
res->flags |= stat_irq_flags;
}
return platform_device_register(pdev);
}
static struct resource resources_mddi0[] = {
{
.start = MSM_PMDH_PHYS,
.end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_MDDI_PRI,
.end = INT_MDDI_PRI,
.flags = IORESOURCE_IRQ,
},
};
static struct resource resources_mddi1[] = {
{
.start = MSM_EMDH_PHYS,
.end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_MDDI_EXT,
.end = INT_MDDI_EXT,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_mddi0 = {
.name = "msm_mddi",
.id = 0,
.num_resources = ARRAY_SIZE(resources_mddi0),
.resource = resources_mddi0,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_mddi1 = {
.name = "msm_mddi",
.id = 1,
.num_resources = ARRAY_SIZE(resources_mddi1),
.resource = resources_mddi1,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct resource resources_mdp[] = {
{
.start = MSM_MDP_PHYS,
.end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1,
.name = "mdp",
.flags = IORESOURCE_MEM
},
{
.start = INT_MDP,
.end = INT_MDP,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_mdp = {
.name = "msm_mdp",
.id = 0,
.num_resources = ARRAY_SIZE(resources_mdp),
.resource = resources_mdp,
};
static struct clk_pcom_desc msm_clocks_7x01a[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF),
CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF),
CLK_PCOM("i2c_clk", I2C_CLK, "msm_i2c.0", 0),
CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
CLK_PCOM("sdc_clk", SDC1_CLK, "msm_sdcc.1", OFF),
CLK_PCOM("sdc_pclk", SDC1_P_CLK, "msm_sdcc.1", OFF),
CLK_PCOM("sdc_clk", SDC2_CLK, "msm_sdcc.2", OFF),
CLK_PCOM("sdc_pclk", SDC2_P_CLK, "msm_sdcc.2", OFF),
CLK_PCOM("sdc_clk", SDC3_CLK, "msm_sdcc.3", OFF),
CLK_PCOM("sdc_pclk", SDC3_P_CLK, "msm_sdcc.3", OFF),
CLK_PCOM("sdc_clk", SDC4_CLK, "msm_sdcc.4", OFF),
CLK_PCOM("sdc_pclk", SDC4_P_CLK, "msm_sdcc.4", OFF),
CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLK_PCOM("core", UART1_CLK, "msm_serial.0", OFF),
CLK_PCOM("core", UART2_CLK, "msm_serial.1", 0),
CLK_PCOM("core", UART3_CLK, "msm_serial.2", OFF),
CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF),
CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0),
CLK_PCOM("usb_hs_clk", USB_HS_CLK, "msm_hsusb", OFF),
CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, "msm_hsusb", OFF),
CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ),
CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
};
static struct pcom_clk_pdata msm_clock_7x01a_pdata = {
.lookup = msm_clocks_7x01a,
.num_lookups = ARRAY_SIZE(msm_clocks_7x01a),
};
struct platform_device msm_clock_7x01a = {
.name = "msm-clock-pcom",
.dev.platform_data = &msm_clock_7x01a_pdata,
};
/*
* Copyright (C) 2008 Google, Inc.
* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/clkdev.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
#include "devices.h"
#include "smd_private.h"
#include "common.h"
#include <asm/mach/flash.h>
#include "clock.h"
#include "clock-pcom.h"
#include <linux/platform_data/mmc-msm_sdcc.h>
static struct resource msm_gpio_resources[] = {
{
.start = 32 + 18,
.end = 32 + 18,
.flags = IORESOURCE_IRQ,
},
{
.start = 32 + 19,
.end = 32 + 19,
.flags = IORESOURCE_IRQ,
},
{
.start = 0xac001000,
.end = 0xac001000 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio1"
},
{
.start = 0xac101400,
.end = 0xac101400 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio2"
},
};
struct platform_device msm_device_gpio_7x30 = {
.name = "gpio-msm-7x30",
.num_resources = ARRAY_SIZE(msm_gpio_resources),
.resource = msm_gpio_resources,
};
static struct resource resources_uart2[] = {
{
.start = INT_UART2,
.end = INT_UART2,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART2_PHYS,
.end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "uart_resource"
},
};
struct platform_device msm_device_uart2 = {
.name = "msm_serial",
.id = 1,
.num_resources = ARRAY_SIZE(resources_uart2),
.resource = resources_uart2,
};
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
};
static struct resource resources_otg[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_otg = {
.name = "msm_otg",
.id = -1,
.num_resources = ARRAY_SIZE(resources_otg),
.resource = resources_otg,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct resource resources_hsusb[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb = {
.name = "msm_hsusb",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb),
.resource = resources_hsusb,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static u64 dma_mask = 0xffffffffULL;
static struct resource resources_hsusb_host[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb_host = {
.name = "msm_hsusb_host",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb_host),
.resource = resources_hsusb_host,
.dev = {
.dma_mask = &dma_mask,
.coherent_dma_mask = 0xffffffffULL,
},
};
static struct clk_pcom_desc msm_clocks_7x30[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0),
CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF),
CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
CLK_PCOM("codec_ssbi_clk", CODEC_SSBI_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF),
CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0),
CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0),
CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0),
CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0),
CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF),
CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF),
CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0),
CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0),
CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0),
CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0),
CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0),
CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0),
CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0),
CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0),
CLK_PCOM("mi2s_m_clk", MI2S_M_CLK, NULL, 0),
CLK_PCOM("mi2s_s_clk", MI2S_S_CLK, NULL, 0),
CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0),
CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0),
CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0),
CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0),
CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0),
CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF),
CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF),
CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0),
CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLK_PCOM("core", UART2_CLK, "msm_serial.1", 0),
CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF),
CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, OFF),
CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, OFF),
CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, 0),
CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0),
CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, 0),
CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF),
CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0),
/* 7x30 v2 hardware only. */
CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0),
CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0),
CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0),
};
static struct pcom_clk_pdata msm_clock_7x30_pdata = {
.lookup = msm_clocks_7x30,
.num_lookups = ARRAY_SIZE(msm_clocks_7x30),
};
struct platform_device msm_clock_7x30 = {
.name = "msm-clock-pcom",
.dev.platform_data = &msm_clock_7x30_pdata,
};
/*
* Copyright (C) 2008 Google, Inc.
* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
#include "devices.h"
#include "common.h"
#include <asm/mach/flash.h>
#include <linux/platform_data/mmc-msm_sdcc.h>
#include "clock.h"
#include "clock-pcom.h"
static struct resource msm_gpio_resources[] = {
{
.start = 64 + 165 + 9,
.end = 64 + 165 + 9,
.flags = IORESOURCE_IRQ,
},
{
.start = 64 + 165 + 10,
.end = 64 + 165 + 10,
.flags = IORESOURCE_IRQ,
},
{
.start = 0xa9000800,
.end = 0xa9000800 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio1"
},
{
.start = 0xa9100C00,
.end = 0xa9100C00 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
.name = "gpio2"
},
};
struct platform_device msm_device_gpio_8x50 = {
.name = "gpio-msm-8x50",
.num_resources = ARRAY_SIZE(msm_gpio_resources),
.resource = msm_gpio_resources,
};
static struct resource resources_uart3[] = {
{
.start = INT_UART3,
.end = INT_UART3,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART3_PHYS,
.end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "uart_resource"
},
};
struct platform_device msm_device_uart3 = {
.name = "msm_serial",
.id = 2,
.num_resources = ARRAY_SIZE(resources_uart3),
.resource = resources_uart3,
};
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
};
static struct resource resources_otg[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_otg = {
.name = "msm_otg",
.id = -1,
.num_resources = ARRAY_SIZE(resources_otg),
.resource = resources_otg,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct resource resources_hsusb[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb = {
.name = "msm_hsusb",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb),
.resource = resources_hsusb,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static u64 dma_mask = 0xffffffffULL;
static struct resource resources_hsusb_host[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb_host = {
.name = "msm_hsusb_host",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb_host),
.resource = resources_hsusb_host,
.dev = {
.dma_mask = &dma_mask,
.coherent_dma_mask = 0xffffffffULL,
},
};
static struct resource resources_sdc1[] = {
{
.start = MSM_SDC1_PHYS,
.end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC1_0,
.end = INT_SDC1_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc2[] = {
{
.start = MSM_SDC2_PHYS,
.end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC2_0,
.end = INT_SDC2_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc3[] = {
{
.start = MSM_SDC3_PHYS,
.end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC3_0,
.end = INT_SDC3_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc4[] = {
{
.start = MSM_SDC4_PHYS,
.end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC4_0,
.end = INT_SDC4_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
struct platform_device msm_device_sdc1 = {
.name = "msm_sdcc",
.id = 1,
.num_resources = ARRAY_SIZE(resources_sdc1),
.resource = resources_sdc1,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc2 = {
.name = "msm_sdcc",
.id = 2,
.num_resources = ARRAY_SIZE(resources_sdc2),
.resource = resources_sdc2,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc3 = {
.name = "msm_sdcc",
.id = 3,
.num_resources = ARRAY_SIZE(resources_sdc3),
.resource = resources_sdc3,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc4 = {
.name = "msm_sdcc",
.id = 4,
.num_resources = ARRAY_SIZE(resources_sdc4),
.resource = resources_sdc4,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct platform_device *msm_sdcc_devices[] __initdata = {
&msm_device_sdc1,
&msm_device_sdc2,
&msm_device_sdc3,
&msm_device_sdc4,
};
int __init msm_add_sdcc(unsigned int controller,
struct msm_mmc_platform_data *plat,
unsigned int stat_irq, unsigned long stat_irq_flags)
{
struct platform_device *pdev;
struct resource *res;
if (controller < 1 || controller > 4)
return -EINVAL;
pdev = msm_sdcc_devices[controller-1];
pdev->dev.platform_data = plat;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
if (!res)
return -EINVAL;
else if (stat_irq) {
res->start = res->end = stat_irq;
res->flags &= ~IORESOURCE_DISABLED;
res->flags |= stat_irq_flags;
}
return platform_device_register(pdev);
}
static struct clk_pcom_desc msm_clocks_8x50[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
CLK_PCOM("i2c_clk", I2C_CLK, NULL, 0),
CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
CLK_PCOM("sdc_clk", SDC1_CLK, "msm_sdcc.1", OFF),
CLK_PCOM("sdc_pclk", SDC1_P_CLK, "msm_sdcc.1", OFF),
CLK_PCOM("sdc_clk", SDC2_CLK, "msm_sdcc.2", OFF),
CLK_PCOM("sdc_pclk", SDC2_P_CLK, "msm_sdcc.2", OFF),
CLK_PCOM("sdc_clk", SDC3_CLK, "msm_sdcc.3", OFF),
CLK_PCOM("sdc_pclk", SDC3_P_CLK, "msm_sdcc.3", OFF),
CLK_PCOM("sdc_clk", SDC4_CLK, "msm_sdcc.4", OFF),
CLK_PCOM("sdc_pclk", SDC4_P_CLK, "msm_sdcc.4", OFF),
CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLK_PCOM("core", UART1_CLK, NULL, OFF),
CLK_PCOM("core", UART2_CLK, NULL, 0),
CLK_PCOM("core", UART3_CLK, "msm_serial.2", OFF),
CLK_PCOM("uartdm_clk", UART1DM_CLK, NULL, OFF),
CLK_PCOM("uartdm_clk", UART2DM_CLK, NULL, 0),
CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF),
CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
};
static struct pcom_clk_pdata msm_clock_8x50_pdata = {
.lookup = msm_clocks_8x50,
.num_lookups = ARRAY_SIZE(msm_clocks_8x50),
};
struct platform_device msm_clock_8x50 = {
.name = "msm-clock-pcom",
.dev.platform_data = &msm_clock_8x50_pdata,
};
/* linux/arch/arm/mach-msm/devices.h
*
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
#define __ARCH_ARM_MACH_MSM_DEVICES_H
extern struct platform_device msm_device_gpio_7201;
extern struct platform_device msm_device_gpio_7x30;
extern struct platform_device msm_device_gpio_8x50;
extern struct platform_device msm_device_uart1;
extern struct platform_device msm_device_uart2;
extern struct platform_device msm_device_uart3;
extern struct platform_device msm8960_device_uart_gsbi2;
extern struct platform_device msm8960_device_uart_gsbi5;
extern struct platform_device msm_device_sdc1;
extern struct platform_device msm_device_sdc2;
extern struct platform_device msm_device_sdc3;
extern struct platform_device msm_device_sdc4;
extern struct platform_device msm_device_hsusb;
extern struct platform_device msm_device_otg;
extern struct platform_device msm_device_hsusb_host;
extern struct platform_device msm_device_i2c;
extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_nand;
extern struct platform_device msm_device_mddi0;
extern struct platform_device msm_device_mddi1;
extern struct platform_device msm_device_mdp;
extern struct platform_device msm_clock_7x01a;
extern struct platform_device msm_clock_7x30;
extern struct platform_device msm_clock_8x50;
#endif
/* linux/arch/arm/mach-msm/dma.c
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <mach/dma.h>
#include <mach/msm_iomap.h>
#define MSM_DMOV_CHANNEL_COUNT 16
#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
#if defined(CONFIG_ARCH_MSM7X30)
#define DMOV_SD_AARM DMOV_SD2
#else
#define DMOV_SD_AARM DMOV_SD3
#endif
#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch)
#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch)
#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
#define DMOV_ISR DMOV_SD_AARM(0x380, 0)
#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch)
enum {
MSM_DMOV_PRINT_ERRORS = 1,
MSM_DMOV_PRINT_IO = 2,
MSM_DMOV_PRINT_FLOW = 4
};
static DEFINE_SPINLOCK(msm_dmov_lock);
static struct clk *msm_dmov_clk;
static unsigned int channel_active;
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
#define MSM_DMOV_DPRINTF(mask, format, args...) \
do { \
if ((mask) & msm_dmov_print_mask) \
printk(KERN_ERR format, args); \
} while (0)
#define PRINT_ERROR(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
#define PRINT_IO(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
#define PRINT_FLOW(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
{
writel((graceful << 31), DMOV_FLUSH0(id));
}
EXPORT_SYMBOL_GPL(msm_dmov_stop_cmd);
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned long irq_flags;
unsigned int status;
spin_lock_irqsave(&msm_dmov_lock, irq_flags);
if (!channel_active)
clk_enable(msm_dmov_clk);
dsb();
status = readl(DMOV_STATUS(id));
if (list_empty(&ready_commands[id]) &&
(status & DMOV_STATUS_CMD_PTR_RDY)) {
#if 0
if (list_empty(&active_commands[id])) {
PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
}
#endif
if (cmd->execute_func)
cmd->execute_func(cmd);
PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
list_add_tail(&cmd->list, &active_commands[id]);
if (!channel_active)
enable_irq(INT_ADM_AARM);
channel_active |= 1U << id;
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
} else {
if (!channel_active)
clk_disable(msm_dmov_clk);
if (list_empty(&active_commands[id]))
PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
list_add_tail(&cmd->list, &ready_commands[id]);
}
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
}
EXPORT_SYMBOL_GPL(msm_dmov_enqueue_cmd);
struct msm_dmov_exec_cmdptr_cmd {
struct msm_dmov_cmd dmov_cmd;
struct completion complete;
unsigned id;
unsigned int result;
struct msm_dmov_errdata err;
};
static void
dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
unsigned int result,
struct msm_dmov_errdata *err)
{
struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
cmd->result = result;
if (result != 0x80000002 && err)
memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
complete(&cmd->complete);
}
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
{
struct msm_dmov_exec_cmdptr_cmd cmd;
PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
cmd.dmov_cmd.cmdptr = cmdptr;
cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
cmd.dmov_cmd.execute_func = NULL;
cmd.id = id;
init_completion(&cmd.complete);
msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd);
wait_for_completion(&cmd.complete);
if (cmd.result != 0x80000002) {
PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
return -EIO;
}
PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
return 0;
}
static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
{
unsigned int int_status, mask, id;
unsigned long irq_flags;
unsigned int ch_status;
unsigned int ch_result;
struct msm_dmov_cmd *cmd;
spin_lock_irqsave(&msm_dmov_lock, irq_flags);
int_status = readl(DMOV_ISR); /* read and clear interrupt */
PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
while (int_status) {
mask = int_status & -int_status;
id = fls(mask) - 1;
PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
int_status &= ~mask;
ch_status = readl(DMOV_STATUS(id));
if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
continue;
}
do {
ch_result = readl(DMOV_RSLT(id));
if (list_empty(&active_commands[id])) {
PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
"with no active command, status %x, result %x\n",
id, ch_status, ch_result);
cmd = NULL;
} else
cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
if (ch_result & DMOV_RSLT_DONE) {
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
id, ch_status);
PRINT_IO("msm_datamover_irq_handler id %d, got result "
"for %p, result %x\n", id, cmd, ch_result);
if (cmd) {
list_del(&cmd->list);
dsb();
cmd->complete_func(cmd, ch_result, NULL);
}
}
if (ch_result & DMOV_RSLT_FLUSH) {
struct msm_dmov_errdata errdata;
errdata.flush[0] = readl(DMOV_FLUSH0(id));
errdata.flush[1] = readl(DMOV_FLUSH1(id));
errdata.flush[2] = readl(DMOV_FLUSH2(id));
errdata.flush[3] = readl(DMOV_FLUSH3(id));
errdata.flush[4] = readl(DMOV_FLUSH4(id));
errdata.flush[5] = readl(DMOV_FLUSH5(id));
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
dsb();
cmd->complete_func(cmd, ch_result, &errdata);
}
}
if (ch_result & DMOV_RSLT_ERROR) {
struct msm_dmov_errdata errdata;
errdata.flush[0] = readl(DMOV_FLUSH0(id));
errdata.flush[1] = readl(DMOV_FLUSH1(id));
errdata.flush[2] = readl(DMOV_FLUSH2(id));
errdata.flush[3] = readl(DMOV_FLUSH3(id));
errdata.flush[4] = readl(DMOV_FLUSH4(id));
errdata.flush[5] = readl(DMOV_FLUSH5(id));
PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
dsb();
cmd->complete_func(cmd, ch_result, &errdata);
}
/* this does not seem to work, once we get an error */
/* the datamover will no longer accept commands */
writel(0, DMOV_FLUSH0(id));
}
ch_status = readl(DMOV_STATUS(id));
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
list_move_tail(&cmd->list, &active_commands[id]);
if (cmd->execute_func)
cmd->execute_func(cmd);
PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
}
} while (ch_status & DMOV_STATUS_RSLT_VALID);
if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
channel_active &= ~(1U << id);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
}
if (!channel_active) {
disable_irq_nosync(INT_ADM_AARM);
clk_disable(msm_dmov_clk);
}
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
return IRQ_HANDLED;
}
static int __init msm_init_datamover(void)
{
int i;
int ret;
struct clk *clk;
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
INIT_LIST_HEAD(&ready_commands[i]);
INIT_LIST_HEAD(&active_commands[i]);
writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
}
clk = clk_get(NULL, "adm_clk");
if (IS_ERR(clk))
return PTR_ERR(clk);
clk_prepare(clk);
msm_dmov_clk = clk;
ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
if (ret)
return ret;
disable_irq(INT_ADM_AARM);
return 0;
}
module_init(msm_init_datamover);
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "gpiomux.h"
#if defined(CONFIG_MMC_MSM) || defined(CONFIG_MMC_MSM_MODULE)
#define SDCC_DAT_0_3_CMD_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_UP\
| GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
#define SDCC_CLK_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_NONE\
| GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
#else
#define SDCC_DAT_0_3_CMD_ACTV_CFG 0
#define SDCC_CLK_ACTV_CFG 0
#endif
#define SDC1_SUSPEND_CONFIG (GPIOMUX_VALID | GPIOMUX_PULL_DOWN\
| GPIOMUX_FUNC_GPIO | GPIOMUX_DRV_2MA)
struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
[86] = { /* UART3 RX */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_1 | GPIOMUX_VALID,
},
[87] = { /* UART3 TX */
.suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
GPIOMUX_FUNC_1 | GPIOMUX_VALID,
},
/* SDC1 data[3:0] & CMD */
[51 ... 55] = {
.active = SDCC_DAT_0_3_CMD_ACTV_CFG,
.suspended = SDC1_SUSPEND_CONFIG
},
/* SDC1 CLK */
[56] = {
.active = SDCC_CLK_ACTV_CFG,
.suspended = SDC1_SUSPEND_CONFIG
},
};
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
#if defined(CONFIG_ARCH_MSM7X30)
#define GPIOMUX_NGPIOS 182
#elif defined(CONFIG_ARCH_QSD8X50)
#define GPIOMUX_NGPIOS 165
#else
#define GPIOMUX_NGPIOS 133
#endif
typedef u32 gpiomux_config_t;
enum {
GPIOMUX_DRV_2MA = 0UL << 17,
GPIOMUX_DRV_4MA = 1UL << 17,
GPIOMUX_DRV_6MA = 2UL << 17,
GPIOMUX_DRV_8MA = 3UL << 17,
GPIOMUX_DRV_10MA = 4UL << 17,
GPIOMUX_DRV_12MA = 5UL << 17,
GPIOMUX_DRV_14MA = 6UL << 17,
GPIOMUX_DRV_16MA = 7UL << 17,
};
enum {
GPIOMUX_FUNC_GPIO = 0UL,
GPIOMUX_FUNC_1 = 1UL,
GPIOMUX_FUNC_2 = 2UL,
GPIOMUX_FUNC_3 = 3UL,
GPIOMUX_FUNC_4 = 4UL,
GPIOMUX_FUNC_5 = 5UL,
GPIOMUX_FUNC_6 = 6UL,
GPIOMUX_FUNC_7 = 7UL,
GPIOMUX_FUNC_8 = 8UL,
GPIOMUX_FUNC_9 = 9UL,
GPIOMUX_FUNC_A = 10UL,
GPIOMUX_FUNC_B = 11UL,
GPIOMUX_FUNC_C = 12UL,
GPIOMUX_FUNC_D = 13UL,
GPIOMUX_FUNC_E = 14UL,
GPIOMUX_FUNC_F = 15UL,
};
enum {
GPIOMUX_PULL_NONE = 0UL << 15,
GPIOMUX_PULL_DOWN = 1UL << 15,
GPIOMUX_PULL_KEEPER = 2UL << 15,
GPIOMUX_PULL_UP = 3UL << 15,
};
#endif
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include "gpiomux.h"
#include "proc_comm.h"
static DEFINE_SPINLOCK(gpiomux_lock);
static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
{
unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) |
((gpio & 0x3ff) << 4);
unsigned tlmm_disable = 0;
int rc;
rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
&tlmm_config, &tlmm_disable);
if (rc)
pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
__func__, rc, tlmm_config, tlmm_disable);
}
int msm_gpiomux_write(unsigned gpio,
gpiomux_config_t active,
gpiomux_config_t suspended)
{
struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
unsigned long irq_flags;
gpiomux_config_t setting;
if (gpio >= GPIOMUX_NGPIOS)
return -EINVAL;
spin_lock_irqsave(&gpiomux_lock, irq_flags);
if (active & GPIOMUX_VALID)
cfg->active = active;
if (suspended & GPIOMUX_VALID)
cfg->suspended = suspended;
setting = cfg->ref ? active : suspended;
if (setting & GPIOMUX_VALID)
__msm_gpiomux_write(gpio, setting);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
}
EXPORT_SYMBOL(msm_gpiomux_write);
int msm_gpiomux_get(unsigned gpio)
{
struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
unsigned long irq_flags;
if (gpio >= GPIOMUX_NGPIOS)
return -EINVAL;
spin_lock_irqsave(&gpiomux_lock, irq_flags);
if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
__msm_gpiomux_write(gpio, cfg->active);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
}
EXPORT_SYMBOL(msm_gpiomux_get);
int msm_gpiomux_put(unsigned gpio)
{
struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
unsigned long irq_flags;
if (gpio >= GPIOMUX_NGPIOS)
return -EINVAL;
spin_lock_irqsave(&gpiomux_lock, irq_flags);
BUG_ON(cfg->ref == 0);
if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
__msm_gpiomux_write(gpio, cfg->suspended);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
}
EXPORT_SYMBOL(msm_gpiomux_put);
static int __init gpiomux_init(void)
{
unsigned n;
for (n = 0; n < GPIOMUX_NGPIOS; ++n) {
msm_gpiomux_configs[n].ref = 0;
if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID))
continue;
__msm_gpiomux_write(n, msm_gpiomux_configs[n].suspended);
}
return 0;
}
postcore_initcall(gpiomux_init);
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H
#define __ARCH_ARM_MACH_MSM_GPIOMUX_H
#include <linux/bitops.h>
#include <linux/errno.h>
#include <mach/msm_gpiomux.h>
#include "gpiomux-v1.h"
/**
* struct msm_gpiomux_config: gpiomux settings for one gpio line.
*
* A complete gpiomux config is the bitwise-or of a drive-strength,
* function, and pull. For functions other than GPIO, the OE
* is hard-wired according to the function. For GPIO mode,
* OE is controlled by gpiolib.
*
* Available settings differ by target; see the gpiomux header
* specific to your target arch for available configurations.
*
* @active: The configuration to be installed when the line is
* active, or its reference count is > 0.
* @suspended: The configuration to be installed when the line
* is suspended, or its reference count is 0.
* @ref: The reference count of the line. For internal use of
* the gpiomux framework only.
*/
struct msm_gpiomux_config {
gpiomux_config_t active;
gpiomux_config_t suspended;
unsigned ref;
};
/**
* @GPIOMUX_VALID: If set, the config field contains 'good data'.
* The absence of this bit will prevent the gpiomux
* system from applying the configuration under all
* circumstances.
*/
enum {
GPIOMUX_VALID = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
GPIOMUX_CTL_MASK = GPIOMUX_VALID,
};
#ifdef CONFIG_MSM_GPIOMUX
/* Each architecture must provide its own instance of this table.
* To avoid having gpiomux manage any given gpio, one or both of
* the entries can avoid setting GPIOMUX_VALID - the absence
* of that flag will prevent the configuration from being applied
* during state transitions.
*/
extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
/* Install a new configuration to the gpio line. To avoid overwriting
* a configuration, leave the VALID bit out.
*/
int msm_gpiomux_write(unsigned gpio,
gpiomux_config_t active,
gpiomux_config_t suspended);
#else
static inline int msm_gpiomux_write(unsigned gpio,
gpiomux_config_t active,
gpiomux_config_t suspended)
{
return -ENOSYS;
}
#endif
#endif
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MACH_CLK_H
#define __MACH_CLK_H
/* Magic rate value for use with PM QOS to request the board's maximum
* supported AXI rate. PM QOS will only pass positive s32 rate values
* through to the clock driver, so INT_MAX is used.
*/
#define MSM_AXI_MAX_FREQ LONG_MAX
enum clk_reset_action {
CLK_RESET_DEASSERT = 0,
CLK_RESET_ASSERT = 1
};
struct clk;
/* Assert/Deassert reset to a hardware block associated with a clock */
int clk_reset(struct clk *clk, enum clk_reset_action action);
#endif
/* linux/include/asm-arm/arch-msm/dma.h
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_MSM_DMA_H
#include <linux/list.h>
struct msm_dmov_errdata {
uint32_t flush[6];
};
struct msm_dmov_cmd {
struct list_head list;
unsigned int cmdptr;
void (*complete_func)(struct msm_dmov_cmd *cmd,
unsigned int result,
struct msm_dmov_errdata *err);
void (*execute_func)(struct msm_dmov_cmd *cmd);
void *data;
};
#ifndef CONFIG_ARCH_MSM8X60
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
#else
static inline
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
static inline
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
static inline
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
#endif
#define DMOV_CMD_LIST (0 << 29) /* does not work */
#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */
#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */
#define DMOV_CMD_ADDR(addr) ((addr) >> 3)
#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */
#define DMOV_RSLT_ERROR (1 << 3)
#define DMOV_RSLT_FLUSH (1 << 2)
#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */
#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */
#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3)
#define DMOV_STATUS_RSLT_VALID (1 << 1)
#define DMOV_STATUS_CMD_PTR_RDY (1 << 0)
#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1)
#define DMOV_CONFIG_IRQ_EN (1 << 0)
/* channel assignments */
#define DMOV_NAND_CHAN 7
#define DMOV_NAND_CRCI_CMD 5
#define DMOV_NAND_CRCI_DATA 4
#define DMOV_SDC1_CHAN 8
#define DMOV_SDC1_CRCI 6
#define DMOV_SDC2_CHAN 8
#define DMOV_SDC2_CRCI 7
#define DMOV_TSIF_CHAN 10
#define DMOV_TSIF_CRCI 10
#define DMOV_USB_CHAN 11
/* no client rate control ifc (eg, ram) */
#define DMOV_NONE_CRCI 0
/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
* is going to walk a list of 32bit pointers as described below. Each
* pointer points to a *array* of dmov_s, etc structs. The last pointer
* in the list is marked with CMD_PTR_LP. The last struct in each array
* is marked with CMD_LC (see below).
*/
#define CMD_PTR_ADDR(addr) ((addr) >> 3)
#define CMD_PTR_LP (1 << 31) /* last pointer */
#define CMD_PTR_PT (3 << 29) /* ? */
/* Single Item Mode */
typedef struct {
unsigned cmd;
unsigned src;
unsigned dst;
unsigned len;
} dmov_s;
/* Scatter/Gather Mode */
typedef struct {
unsigned cmd;
unsigned src_dscr;
unsigned dst_dscr;
unsigned _reserved;
} dmov_sg;
/* Box mode */
typedef struct {
uint32_t cmd;
uint32_t src_row_addr;
uint32_t dst_row_addr;
uint32_t src_dst_len;
uint32_t num_rows;
uint32_t row_offset;
} dmov_box;
/* bits for the cmd field of the above structures */
#define CMD_LC (1 << 31) /* last command */
#define CMD_FR (1 << 22) /* force result -- does not work? */
#define CMD_OCU (1 << 21) /* other channel unblock */
#define CMD_OCB (1 << 20) /* other channel block */
#define CMD_TCB (1 << 19) /* ? */
#define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/
#define CMD_SAH (1 << 17) /* source address hold -- does not work? */
#define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */
#define CMD_MODE_SG (1 << 0) /* untested */
#define CMD_MODE_IND_SG (2 << 0) /* untested */
#define CMD_MODE_BOX (3 << 0) /* untested */
#define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */
#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
#define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */
#define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */
#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
#define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */
#define CMD_DST_CRCI(n) (((n) & 15) << 7)
#define CMD_SRC_CRCI(n) (((n) & 15) << 3)
#endif
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
#if !defined(CONFIG_ARM_GIC)
#include <mach/msm_iomap.h>
.macro get_irqnr_preamble, base, tmp
@ enable imprecise aborts
cpsie a
mov \base, #MSM_VIC_BASE
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
@ 0xD0 has irq# or old irq# if the irq has been handled
@ 0xD4 has irq# or -1 if none pending *but* if you just
@ read 0xD4 you never get the first irq for some reason
ldr \irqnr, [\base, #0xD0]
ldr \irqnr, [\base, #0xD4]
cmp \irqnr, #0xffffffff
.endm
#endif
/* arch/arm/mach-msm/include/mach/hardware.h
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_MSM_HARDWARE_H
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*/
#ifndef __ASM_ARCH_MSM_IRQS_7X00_H
#define __ASM_ARCH_MSM_IRQS_7X00_H
/* MSM ARM11 Interrupt Numbers */
/* See 80-VE113-1 A, pp219-221 */
#define INT_A9_M2A_0 0
#define INT_A9_M2A_1 1
#define INT_A9_M2A_2 2
#define INT_A9_M2A_3 3
#define INT_A9_M2A_4 4
#define INT_A9_M2A_5 5
#define INT_A9_M2A_6 6
#define INT_GP_TIMER_EXP 7
#define INT_DEBUG_TIMER_EXP 8
#define INT_UART1 9
#define INT_UART2 10
#define INT_UART3 11
#define INT_UART1_RX 12
#define INT_UART2_RX 13
#define INT_UART3_RX 14
#define INT_USB_OTG 15
#define INT_MDDI_PRI 16
#define INT_MDDI_EXT 17
#define INT_MDDI_CLIENT 18
#define INT_MDP 19
#define INT_GRAPHICS 20
#define INT_ADM_AARM 21
#define INT_ADSP_A11 22
#define INT_ADSP_A9_A11 23
#define INT_SDC1_0 24
#define INT_SDC1_1 25
#define INT_SDC2_0 26
#define INT_SDC2_1 27
#define INT_KEYSENSE 28
#define INT_TCHSCRN_SSBI 29
#define INT_TCHSCRN1 30
#define INT_TCHSCRN2 31
#define INT_GPIO_GROUP1 (32 + 0)
#define INT_GPIO_GROUP2 (32 + 1)
#define INT_PWB_I2C (32 + 2)
#define INT_SOFTRESET (32 + 3)
#define INT_NAND_WR_ER_DONE (32 + 4)
#define INT_NAND_OP_DONE (32 + 5)
#define INT_PBUS_ARM11 (32 + 6)
#define INT_AXI_MPU_SMI (32 + 7)
#define INT_AXI_MPU_EBI1 (32 + 8)
#define INT_AD_HSSD (32 + 9)
#define INT_ARM11_PMU (32 + 10)
#define INT_ARM11_DMA (32 + 11)
#define INT_TSIF_IRQ (32 + 12)
#define INT_UART1DM_IRQ (32 + 13)
#define INT_UART1DM_RX (32 + 14)
#define INT_USB_HS (32 + 15)
#define INT_SDC3_0 (32 + 16)
#define INT_SDC3_1 (32 + 17)
#define INT_SDC4_0 (32 + 18)
#define INT_SDC4_1 (32 + 19)
#define INT_UART2DM_RX (32 + 20)
#define INT_UART2DM_IRQ (32 + 21)
/* 22-31 are reserved */
#define NR_MSM_IRQS 64
#define NR_GPIO_IRQS 122
#define NR_BOARD_IRQS 64
#endif
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_MSM_IRQS_7X30_H
#define __ASM_ARCH_MSM_IRQS_7X30_H
/* MSM ACPU Interrupt Numbers */
#define INT_DEBUG_TIMER_EXP 0
#define INT_GPT0_TIMER_EXP 1
#define INT_GPT1_TIMER_EXP 2
#define INT_WDT0_ACCSCSSBARK 3
#define INT_WDT1_ACCSCSSBARK 4
#define INT_AVS_SVIC 5
#define INT_AVS_SVIC_SW_DONE 6
#define INT_SC_DBG_RX_FULL 7
#define INT_SC_DBG_TX_EMPTY 8
#define INT_ARM11_PM 9
#define INT_AVS_REQ_DOWN 10
#define INT_AVS_REQ_UP 11
#define INT_SC_ACG 12
/* SCSS_VICFIQSTS0[13:15] are RESERVED */
#define INT_L2_SVICCPUIRPTREQ 16
#define INT_L2_SVICDMANSIRPTREQ 17
#define INT_L2_SVICDMASIRPTREQ 18
#define INT_L2_SVICSLVIRPTREQ 19
#define INT_AD5A_MPROC_APPS_0 20
#define INT_AD5A_MPROC_APPS_1 21
#define INT_A9_M2A_0 22
#define INT_A9_M2A_1 23
#define INT_A9_M2A_2 24
#define INT_A9_M2A_3 25
#define INT_A9_M2A_4 26
#define INT_A9_M2A_5 27
#define INT_A9_M2A_6 28
#define INT_A9_M2A_7 29
#define INT_A9_M2A_8 30
#define INT_A9_M2A_9 31
#define INT_AXI_EBI1_SC (32 + 0)
#define INT_IMEM_ERR (32 + 1)
#define INT_AXI_EBI0_SC (32 + 2)
#define INT_PBUS_SC_IRQC (32 + 3)
#define INT_PERPH_BUS_BPM (32 + 4)
#define INT_CC_TEMP_SENSE (32 + 5)
#define INT_UXMC_EBI0 (32 + 6)
#define INT_UXMC_EBI1 (32 + 7)
#define INT_EBI2_OP_DONE (32 + 8)
#define INT_EBI2_WR_ER_DONE (32 + 9)
#define INT_TCSR_SPSS_CE (32 + 10)
#define INT_EMDH (32 + 11)
#define INT_PMDH (32 + 12)
#define INT_MDC (32 + 13)
#define INT_MIDI_TO_SUPSS (32 + 14)
#define INT_LPA_2 (32 + 15)
#define INT_GPIO_GROUP1_SECURE (32 + 16)
#define INT_GPIO_GROUP2_SECURE (32 + 17)
#define INT_GPIO_GROUP1 (32 + 18)
#define INT_GPIO_GROUP2 (32 + 19)
#define INT_MPRPH_SOFTRESET (32 + 20)
#define INT_PWB_I2C (32 + 21)
#define INT_PWB_I2C_2 (32 + 22)
#define INT_TSSC_SAMPLE (32 + 23)
#define INT_TSSC_PENUP (32 + 24)
#define INT_TCHSCRN_SSBI (32 + 25)
#define INT_FM_RDS (32 + 26)
#define INT_KEYSENSE (32 + 27)
#define INT_USB_OTG_HS (32 + 28)
#define INT_USB_OTG_HS2 (32 + 29)
#define INT_USB_OTG_HS3 (32 + 30)
#define INT_CSI (32 + 31)
#define INT_SPI_OUTPUT (64 + 0)
#define INT_SPI_INPUT (64 + 1)
#define INT_SPI_ERROR (64 + 2)
#define INT_UART1 (64 + 3)
#define INT_UART1_RX (64 + 4)
#define INT_UART2 (64 + 5)
#define INT_UART2_RX (64 + 6)
#define INT_UART3 (64 + 7)
#define INT_UART3_RX (64 + 8)
#define INT_UART1DM_IRQ (64 + 9)
#define INT_UART1DM_RX (64 + 10)
#define INT_UART2DM_IRQ (64 + 11)
#define INT_UART2DM_RX (64 + 12)
#define INT_TSIF (64 + 13)
#define INT_ADM_SC1 (64 + 14)
#define INT_ADM_SC2 (64 + 15)
#define INT_MDP (64 + 16)
#define INT_VPE (64 + 17)
#define INT_GRP_2D (64 + 18)
#define INT_GRP_3D (64 + 19)
#define INT_ROTATOR (64 + 20)
#define INT_MFC720 (64 + 21)
#define INT_JPEG (64 + 22)
#define INT_VFE (64 + 23)
#define INT_TV_ENC (64 + 24)
#define INT_PMIC_SSBI (64 + 25)
#define INT_MPM_1 (64 + 26)
#define INT_TCSR_SPSS_SAMPLE (64 + 27)
#define INT_TCSR_SPSS_PENUP (64 + 28)
#define INT_MPM_2 (64 + 29)
#define INT_SDC1_0 (64 + 30)
#define INT_SDC1_1 (64 + 31)
#define INT_SDC3_0 (96 + 0)
#define INT_SDC3_1 (96 + 1)
#define INT_SDC2_0 (96 + 2)
#define INT_SDC2_1 (96 + 3)
#define INT_SDC4_0 (96 + 4)
#define INT_SDC4_1 (96 + 5)
#define INT_PWB_QUP_IN (96 + 6)
#define INT_PWB_QUP_OUT (96 + 7)
#define INT_PWB_QUP_ERR (96 + 8)
#define INT_SCSS_WDT0_BITE (96 + 9)
/* SCSS_VICFIQSTS3[10:31] are RESERVED */
/* Retrofit universal macro names */
#define INT_ADM_AARM INT_ADM_SC2
#define INT_USB_HS INT_USB_OTG_HS
#define INT_USB_OTG INT_USB_OTG_HS
#define INT_TCHSCRN1 INT_TSSC_SAMPLE
#define INT_TCHSCRN2 INT_TSSC_PENUP
#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP
#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0
#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1
#define INT_MDDI_EXT INT_EMDH
#define INT_MDDI_PRI INT_PMDH
#define INT_MDDI_CLIENT INT_MDC
#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE
#define INT_NAND_OP_DONE INT_EBI2_OP_DONE
#define NR_MSM_IRQS 128
#define NR_GPIO_IRQS 182
#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
#define NR_PMIC8058_GPIO_IRQS 40
#define NR_PMIC8058_MPP_IRQS 12
#define NR_PMIC8058_MISC_IRQS 8
#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\
NR_PMIC8058_MPP_IRQS +\
NR_PMIC8058_MISC_IRQS)
#define NR_BOARD_IRQS NR_PMIC8058_IRQS
#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_MSM_IRQS_8XXX_H
#define __ASM_ARCH_MSM_IRQS_8XXX_H
/* MSM ACPU Interrupt Numbers */
#define INT_A9_M2A_0 0
#define INT_A9_M2A_1 1
#define INT_A9_M2A_2 2
#define INT_A9_M2A_3 3
#define INT_A9_M2A_4 4
#define INT_A9_M2A_5 5
#define INT_A9_M2A_6 6
#define INT_GP_TIMER_EXP 7
#define INT_DEBUG_TIMER_EXP 8
#define INT_SIRC_0 9
#define INT_SDC3_0 10
#define INT_SDC3_1 11
#define INT_SDC4_0 12
#define INT_SDC4_1 13
#define INT_AD6_EXT_VFR 14
#define INT_USB_OTG 15
#define INT_MDDI_PRI 16
#define INT_MDDI_EXT 17
#define INT_MDDI_CLIENT 18
#define INT_MDP 19
#define INT_GRAPHICS 20
#define INT_ADM_AARM 21
#define INT_ADSP_A11 22
#define INT_ADSP_A9_A11 23
#define INT_SDC1_0 24
#define INT_SDC1_1 25
#define INT_SDC2_0 26
#define INT_SDC2_1 27
#define INT_KEYSENSE 28
#define INT_TCHSCRN_SSBI 29
#define INT_TCHSCRN1 30
#define INT_TCHSCRN2 31
#define INT_TCSR_MPRPH_SC1 (32 + 0)
#define INT_USB_FS2 (32 + 1)
#define INT_PWB_I2C (32 + 2)
#define INT_SOFTRESET (32 + 3)
#define INT_NAND_WR_ER_DONE (32 + 4)
#define INT_NAND_OP_DONE (32 + 5)
#define INT_TCSR_MPRPH_SC2 (32 + 6)
#define INT_OP_PEN (32 + 7)
#define INT_AD_HSSD (32 + 8)
#define INT_ARM11_PM (32 + 9)
#define INT_SDMA_NON_SECURE (32 + 10)
#define INT_TSIF_IRQ (32 + 11)
#define INT_UART1DM_IRQ (32 + 12)
#define INT_UART1DM_RX (32 + 13)
#define INT_SDMA_SECURE (32 + 14)
#define INT_SI2S_SLAVE (32 + 15)
#define INT_SC_I2CPU (32 + 16)
#define INT_SC_DBG_RDTRFULL (32 + 17)
#define INT_SC_DBG_WDTRFULL (32 + 18)
#define INT_SCPLL_CTL_DONE (32 + 19)
#define INT_UART2DM_IRQ (32 + 20)
#define INT_UART2DM_RX (32 + 21)
#define INT_VDC_MEC (32 + 22)
#define INT_VDC_DB (32 + 23)
#define INT_VDC_AXI (32 + 24)
#define INT_VFE (32 + 25)
#define INT_USB_HS (32 + 26)
#define INT_AUDIO_OUT0 (32 + 27)
#define INT_AUDIO_OUT1 (32 + 28)
#define INT_CRYPTO (32 + 29)
#define INT_AD6M_IDLE (32 + 30)
#define INT_SIRC_1 (32 + 31)
#define NR_GPIO_IRQS 165
#define NR_MSM_IRQS 64
#define NR_BOARD_IRQS 64
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_MSM_IRQS_H
#define __ASM_ARCH_MSM_IRQS_H
#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31))
#if defined(CONFIG_ARCH_MSM7X30)
#include "irqs-7x30.h"
#elif defined(CONFIG_ARCH_QSD8X50)
#include "irqs-8x50.h"
#include "sirc.h"
#elif defined(CONFIG_ARCH_MSM_ARM11)
#include "irqs-7x00.h"
#else
#error "Unknown architecture specification"
#endif
#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
#define MSM_INT_TO_REG(base, irq) (base + irq / 32)
#endif
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _LINUX_MSM_GPIOMUX_H
#define _LINUX_MSM_GPIOMUX_H
#ifdef CONFIG_MSM_GPIOMUX
/* Increment a gpio's reference count, possibly activating the line. */
int __must_check msm_gpiomux_get(unsigned gpio);
/* Decrement a gpio's reference count, possibly suspending the line. */
int msm_gpiomux_put(unsigned gpio);
#else
static inline int __must_check msm_gpiomux_get(unsigned gpio)
{
return -ENOSYS;
}
static inline int msm_gpiomux_put(unsigned gpio)
{
return -ENOSYS;
}
#endif
#endif /* _LINUX_MSM_GPIOMUX_H */
/* arch/arm/mach-msm/include/mach/msm_iomap.h
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* The MSM peripherals are spread all over across 768MB of physical
* space, which makes just having a simple IO_ADDRESS macro to slide
* them into the right virtual location rough. Instead, we will
* provide a master phys->virt mapping for peripherals here.
*
*/
#ifndef __ASM_ARCH_MSM_IOMAP_7X00_H
#define __ASM_ARCH_MSM_IOMAP_7X00_H
#include <asm/sizes.h>
/* Physical base address and size of peripherals.
* Ordered by the virtual base addresses they will be mapped at.
*
* MSM_VIC_BASE must be an value that can be loaded via a "mov"
* instruction, otherwise entry-macro.S will not compile.
*
* If you add or remove entries here, you'll want to edit the
* msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
* changes.
*
*/
#define MSM_VIC_BASE IOMEM(0xE0000000)
#define MSM_VIC_PHYS 0xC0000000
#define MSM_VIC_SIZE SZ_4K
#define MSM7X00_CSR_PHYS 0xC0100000
#define MSM7X00_CSR_SIZE SZ_4K
#define MSM_DMOV_BASE IOMEM(0xE0002000)
#define MSM_DMOV_PHYS 0xA9700000
#define MSM_DMOV_SIZE SZ_4K
#define MSM7X00_GPIO1_PHYS 0xA9200000
#define MSM7X00_GPIO1_SIZE SZ_4K
#define MSM7X00_GPIO2_PHYS 0xA9300000
#define MSM7X00_GPIO2_SIZE SZ_4K
#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
#define MSM_CLK_CTL_PHYS 0xA8600000
#define MSM_CLK_CTL_SIZE SZ_4K
#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
#define MSM_SHARED_RAM_PHYS 0x01F00000
#define MSM_SHARED_RAM_SIZE SZ_1M
#define MSM_UART1_PHYS 0xA9A00000
#define MSM_UART1_SIZE SZ_4K
#define MSM_UART2_PHYS 0xA9B00000
#define MSM_UART2_SIZE SZ_4K
#define MSM_UART3_PHYS 0xA9C00000
#define MSM_UART3_SIZE SZ_4K
#define MSM_SDC1_PHYS 0xA0400000
#define MSM_SDC1_SIZE SZ_4K
#define MSM_SDC2_PHYS 0xA0500000
#define MSM_SDC2_SIZE SZ_4K
#define MSM_SDC3_PHYS 0xA0600000
#define MSM_SDC3_SIZE SZ_4K
#define MSM_SDC4_PHYS 0xA0700000
#define MSM_SDC4_SIZE SZ_4K
#define MSM_I2C_PHYS 0xA9900000
#define MSM_I2C_SIZE SZ_4K
#define MSM_HSUSB_PHYS 0xA0800000
#define MSM_HSUSB_SIZE SZ_4K
#define MSM_PMDH_PHYS 0xAA600000
#define MSM_PMDH_SIZE SZ_4K
#define MSM_EMDH_PHYS 0xAA700000
#define MSM_EMDH_SIZE SZ_4K
#define MSM_MDP_PHYS 0xAA200000
#define MSM_MDP_SIZE 0x000F0000
#define MSM_MDC_PHYS 0xAA500000
#define MSM_MDC_SIZE SZ_1M
#define MSM_AD5_PHYS 0xAC000000
#define MSM_AD5_SIZE (SZ_1M*13)
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* The MSM peripherals are spread all over across 768MB of physical
* space, which makes just having a simple IO_ADDRESS macro to slide
* them into the right virtual location rough. Instead, we will
* provide a master phys->virt mapping for peripherals here.
*
*/
#ifndef __ASM_ARCH_MSM_IOMAP_7X30_H
#define __ASM_ARCH_MSM_IOMAP_7X30_H
/* Physical base address and size of peripherals.
* Ordered by the virtual base addresses they will be mapped at.
*
* MSM_VIC_BASE must be an value that can be loaded via a "mov"
* instruction, otherwise entry-macro.S will not compile.
*
* If you add or remove entries here, you'll want to edit the
* msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
* changes.
*
*/
#define MSM_VIC_BASE IOMEM(0xE0000000)
#define MSM_VIC_PHYS 0xC0080000
#define MSM_VIC_SIZE SZ_4K
#define MSM7X30_CSR_PHYS 0xC0100000
#define MSM7X30_CSR_SIZE SZ_4K
#define MSM_DMOV_BASE IOMEM(0xE0002000)
#define MSM_DMOV_PHYS 0xAC400000
#define MSM_DMOV_SIZE SZ_4K
#define MSM7X30_GPIO1_PHYS 0xAC001000
#define MSM7X30_GPIO1_SIZE SZ_4K
#define MSM7X30_GPIO2_PHYS 0xAC101000
#define MSM7X30_GPIO2_SIZE SZ_4K
#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
#define MSM_CLK_CTL_PHYS 0xAB800000
#define MSM_CLK_CTL_SIZE SZ_4K
#define MSM_CLK_CTL_SH2_BASE IOMEM(0xE0006000)
#define MSM_CLK_CTL_SH2_PHYS 0xABA01000
#define MSM_CLK_CTL_SH2_SIZE SZ_4K
#define MSM_ACC_BASE IOMEM(0xE0007000)
#define MSM_ACC_PHYS 0xC0101000
#define MSM_ACC_SIZE SZ_4K
#define MSM_SAW_BASE IOMEM(0xE0008000)
#define MSM_SAW_PHYS 0xC0102000
#define MSM_SAW_SIZE SZ_4K
#define MSM_GCC_BASE IOMEM(0xE0009000)
#define MSM_GCC_PHYS 0xC0182000
#define MSM_GCC_SIZE SZ_4K
#define MSM_TCSR_BASE IOMEM(0xE000A000)
#define MSM_TCSR_PHYS 0xAB600000
#define MSM_TCSR_SIZE SZ_4K
#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
#define MSM_SHARED_RAM_PHYS 0x00100000
#define MSM_SHARED_RAM_SIZE SZ_1M
#define MSM_UART1_PHYS 0xACA00000
#define MSM_UART1_SIZE SZ_4K
#define MSM_UART2_PHYS 0xACB00000
#define MSM_UART2_SIZE SZ_4K
#define MSM_UART3_PHYS 0xACC00000
#define MSM_UART3_SIZE SZ_4K
#define MSM_MDC_BASE IOMEM(0xE0200000)
#define MSM_MDC_PHYS 0xAA500000
#define MSM_MDC_SIZE SZ_1M
#define MSM_AD5_BASE IOMEM(0xE0300000)
#define MSM_AD5_PHYS 0xA7000000
#define MSM_AD5_SIZE (SZ_1M*13)
#define MSM_HSUSB_PHYS 0xA3600000
#define MSM_HSUSB_SIZE SZ_1K
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* The MSM peripherals are spread all over across 768MB of physical
* space, which makes just having a simple IO_ADDRESS macro to slide
* them into the right virtual location rough. Instead, we will
* provide a master phys->virt mapping for peripherals here.
*
*/
#ifndef __ASM_ARCH_MSM_IOMAP_8X50_H
#define __ASM_ARCH_MSM_IOMAP_8X50_H
/* Physical base address and size of peripherals.
* Ordered by the virtual base addresses they will be mapped at.
*
* MSM_VIC_BASE must be an value that can be loaded via a "mov"
* instruction, otherwise entry-macro.S will not compile.
*
* If you add or remove entries here, you'll want to edit the
* msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
* changes.
*
*/
#define MSM_VIC_BASE IOMEM(0xE0000000)
#define MSM_VIC_PHYS 0xAC000000
#define MSM_VIC_SIZE SZ_4K
#define QSD8X50_CSR_PHYS 0xAC100000
#define QSD8X50_CSR_SIZE SZ_4K
#define MSM_DMOV_BASE IOMEM(0xE0002000)
#define MSM_DMOV_PHYS 0xA9700000
#define MSM_DMOV_SIZE SZ_4K
#define QSD8X50_GPIO1_PHYS 0xA9000000
#define QSD8X50_GPIO1_SIZE SZ_4K
#define QSD8X50_GPIO2_PHYS 0xA9100000
#define QSD8X50_GPIO2_SIZE SZ_4K
#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
#define MSM_CLK_CTL_PHYS 0xA8600000
#define MSM_CLK_CTL_SIZE SZ_4K
#define MSM_SIRC_BASE IOMEM(0xE1006000)
#define MSM_SIRC_PHYS 0xAC200000
#define MSM_SIRC_SIZE SZ_4K
#define MSM_SCPLL_BASE IOMEM(0xE1007000)
#define MSM_SCPLL_PHYS 0xA8800000
#define MSM_SCPLL_SIZE SZ_4K
#ifdef CONFIG_MSM_SOC_REV_A
#define MSM_SMI_BASE 0xE0000000
#else
#define MSM_SMI_BASE 0x00000000
#endif
#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
#define MSM_SHARED_RAM_SIZE SZ_1M
#define MSM_UART1_PHYS 0xA9A00000
#define MSM_UART1_SIZE SZ_4K
#define MSM_UART2_PHYS 0xA9B00000
#define MSM_UART2_SIZE SZ_4K
#define MSM_UART3_PHYS 0xA9C00000
#define MSM_UART3_SIZE SZ_4K
#define MSM_MDC_BASE IOMEM(0xE0200000)
#define MSM_MDC_PHYS 0xAA500000
#define MSM_MDC_SIZE SZ_1M
#define MSM_AD5_BASE IOMEM(0xE0300000)
#define MSM_AD5_PHYS 0xAC000000
#define MSM_AD5_SIZE (SZ_1M*13)
#define MSM_I2C_SIZE SZ_4K
#define MSM_I2C_PHYS 0xA9900000
#define MSM_HSUSB_PHYS 0xA0800000
#define MSM_HSUSB_SIZE SZ_1K
#define MSM_NAND_PHYS 0xA0A00000
#define MSM_TSIF_PHYS (0xa0100000)
#define MSM_TSIF_SIZE (0x200)
#define MSM_TSSC_PHYS 0xAA300000
#define MSM_UART1DM_PHYS 0xA0200000
#define MSM_UART2DM_PHYS 0xA0900000
#define MSM_SDC1_PHYS 0xA0300000
#define MSM_SDC1_SIZE SZ_4K
#define MSM_SDC2_PHYS 0xA0400000
#define MSM_SDC2_SIZE SZ_4K
#define MSM_SDC3_PHYS 0xA0500000
#define MSM_SDC3_SIZE SZ_4K
#define MSM_SDC4_PHYS 0xA0600000
#define MSM_SDC4_SIZE SZ_4K
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* The MSM peripherals are spread all over across 768MB of physical
* space, which makes just having a simple IO_ADDRESS macro to slide
* them into the right virtual location rough. Instead, we will
* provide a master phys->virt mapping for peripherals here.
*
*/
#ifndef __ASM_ARCH_MSM_IOMAP_H
#define __ASM_ARCH_MSM_IOMAP_H
#include <asm/sizes.h>
/* Physical base address and size of peripherals.
* Ordered by the virtual base addresses they will be mapped at.
*
* MSM_VIC_BASE must be an value that can be loaded via a "mov"
* instruction, otherwise entry-macro.S will not compile.
*
* If you add or remove entries here, you'll want to edit the
* msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
* changes.
*
*/
#if defined(CONFIG_ARCH_MSM7X30)
#include "msm_iomap-7x30.h"
#elif defined(CONFIG_ARCH_QSD8X50)
#include "msm_iomap-8x50.h"
#else
#include "msm_iomap-7x00.h"
#endif
/* Virtual addresses shared across all MSM targets. */
#define MSM_CSR_BASE IOMEM(0xE0001000)
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
#define MSM_GPIO2_BASE IOMEM(0xE0004000)
#endif
/* linux/include/asm-arm/arch-msm/msm_smd.h
*
* Copyright (C) 2007 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_MSM_SMD_H
#define __ASM_ARCH_MSM_SMD_H
typedef struct smd_channel smd_channel_t;
extern int (*msm_check_for_modem_crash)(void);
/* warning: notify() may be called before open returns */
int smd_open(const char *name, smd_channel_t **ch, void *priv,
void (*notify)(void *priv, unsigned event));
#define SMD_EVENT_DATA 1
#define SMD_EVENT_OPEN 2
#define SMD_EVENT_CLOSE 3
int smd_close(smd_channel_t *ch);
/* passing a null pointer for data reads and discards */
int smd_read(smd_channel_t *ch, void *data, int len);
/* Write to stream channels may do a partial write and return
** the length actually written.
** Write to packet channels will never do a partial write --
** it will return the requested length written or an error.
*/
int smd_write(smd_channel_t *ch, const void *data, int len);
int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
int smd_write_avail(smd_channel_t *ch);
int smd_read_avail(smd_channel_t *ch);
/* Returns the total size of the current packet being read.
** Returns 0 if no packets available or a stream channel.
*/
int smd_cur_packet_size(smd_channel_t *ch);
/* used for tty unthrottling and the like -- causes the notify()
** callback to be called from the same lock context as is used
** when it is called from channel updates
*/
void smd_kick(smd_channel_t *ch);
#if 0
/* these are interruptable waits which will block you until the specified
** number of bytes are readable or writable.
*/
int smd_wait_until_readable(smd_channel_t *ch, int bytes);
int smd_wait_until_writable(smd_channel_t *ch, int bytes);
#endif
typedef enum {
SMD_PORT_DS = 0,
SMD_PORT_DIAG,
SMD_PORT_RPC_CALL,
SMD_PORT_RPC_REPLY,
SMD_PORT_BT,
SMD_PORT_CONTROL,
SMD_PORT_MEMCPY_SPARE1,
SMD_PORT_DATA1,
SMD_PORT_DATA2,
SMD_PORT_DATA3,
SMD_PORT_DATA4,
SMD_PORT_DATA5,
SMD_PORT_DATA6,
SMD_PORT_DATA7,
SMD_PORT_DATA8,
SMD_PORT_DATA9,
SMD_PORT_DATA10,
SMD_PORT_DATA11,
SMD_PORT_DATA12,
SMD_PORT_DATA13,
SMD_PORT_DATA14,
SMD_PORT_DATA15,
SMD_PORT_DATA16,
SMD_PORT_DATA17,
SMD_PORT_DATA18,
SMD_PORT_DATA19,
SMD_PORT_DATA20,
SMD_PORT_GPS_NMEA,
SMD_PORT_BRIDGE_1,
SMD_PORT_BRIDGE_2,
SMD_PORT_BRIDGE_3,
SMD_PORT_BRIDGE_4,
SMD_PORT_BRIDGE_5,
SMD_PORT_LOOPBACK,
SMD_PORT_CS_APPS_MODEM,
SMD_PORT_CS_APPS_DSP,
SMD_PORT_CS_MODEM_DSP,
SMD_NUM_PORTS,
} smd_port_id_type;
#endif
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_MSM_SIRC_H
#define __ASM_ARCH_MSM_SIRC_H
struct sirc_regs_t {
void *int_enable;
void *int_enable_clear;
void *int_enable_set;
void *int_type;
void *int_polarity;
void *int_clear;
};
struct sirc_cascade_regs {
void *int_status;
unsigned int cascade_irq;
};
void msm_init_sirc(void);
void msm_sirc_enter_sleep(void);
void msm_sirc_exit_sleep(void);
#if defined(CONFIG_ARCH_MSM_SCORPION)
#include <mach/msm_iomap.h>
/*
* Secondary interrupt controller interrupts
*/
#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS)
#define INT_UART1 (FIRST_SIRC_IRQ + 0)
#define INT_UART2 (FIRST_SIRC_IRQ + 1)
#define INT_UART3 (FIRST_SIRC_IRQ + 2)
#define INT_UART1_RX (FIRST_SIRC_IRQ + 3)
#define INT_UART2_RX (FIRST_SIRC_IRQ + 4)
#define INT_UART3_RX (FIRST_SIRC_IRQ + 5)
#define INT_SPI_INPUT (FIRST_SIRC_IRQ + 6)
#define INT_SPI_OUTPUT (FIRST_SIRC_IRQ + 7)
#define INT_SPI_ERROR (FIRST_SIRC_IRQ + 8)
#define INT_GPIO_GROUP1 (FIRST_SIRC_IRQ + 9)
#define INT_GPIO_GROUP2 (FIRST_SIRC_IRQ + 10)
#define INT_GPIO_GROUP1_SECURE (FIRST_SIRC_IRQ + 11)
#define INT_GPIO_GROUP2_SECURE (FIRST_SIRC_IRQ + 12)
#define INT_AVS_SVIC (FIRST_SIRC_IRQ + 13)
#define INT_AVS_REQ_UP (FIRST_SIRC_IRQ + 14)
#define INT_AVS_REQ_DOWN (FIRST_SIRC_IRQ + 15)
#define INT_PBUS_ERR (FIRST_SIRC_IRQ + 16)
#define INT_AXI_ERR (FIRST_SIRC_IRQ + 17)
#define INT_SMI_ERR (FIRST_SIRC_IRQ + 18)
#define INT_EBI1_ERR (FIRST_SIRC_IRQ + 19)
#define INT_IMEM_ERR (FIRST_SIRC_IRQ + 20)
#define INT_TEMP_SENSOR (FIRST_SIRC_IRQ + 21)
#define INT_TV_ENC (FIRST_SIRC_IRQ + 22)
#define INT_GRP2D (FIRST_SIRC_IRQ + 23)
#define INT_GSBI_QUP (FIRST_SIRC_IRQ + 24)
#define INT_SC_ACG (FIRST_SIRC_IRQ + 25)
#define INT_WDT0 (FIRST_SIRC_IRQ + 26)
#define INT_WDT1 (FIRST_SIRC_IRQ + 27)
#if defined(CONFIG_MSM_SOC_REV_A)
#define NR_SIRC_IRQS 28
#define SIRC_MASK 0x0FFFFFFF
#else
#define NR_SIRC_IRQS 23
#define SIRC_MASK 0x007FFFFF
#endif
#define LAST_SIRC_IRQ (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1)
#define SPSS_SIRC_INT_SELECT (MSM_SIRC_BASE + 0x00)
#define SPSS_SIRC_INT_ENABLE (MSM_SIRC_BASE + 0x04)
#define SPSS_SIRC_INT_ENABLE_CLEAR (MSM_SIRC_BASE + 0x08)
#define SPSS_SIRC_INT_ENABLE_SET (MSM_SIRC_BASE + 0x0C)
#define SPSS_SIRC_INT_TYPE (MSM_SIRC_BASE + 0x10)
#define SPSS_SIRC_INT_POLARITY (MSM_SIRC_BASE + 0x14)
#define SPSS_SIRC_SECURITY (MSM_SIRC_BASE + 0x18)
#define SPSS_SIRC_IRQ_STATUS (MSM_SIRC_BASE + 0x1C)
#define SPSS_SIRC_IRQ1_STATUS (MSM_SIRC_BASE + 0x20)
#define SPSS_SIRC_RAW_STATUS (MSM_SIRC_BASE + 0x24)
#define SPSS_SIRC_INT_CLEAR (MSM_SIRC_BASE + 0x28)
#define SPSS_SIRC_SOFT_INT (MSM_SIRC_BASE + 0x2C)
#endif
#endif
/* linux/include/asm-arm/arch-msm/vreg.h
*
* Copyright (C) 2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_VREG_H
#define __ARCH_ARM_MACH_MSM_VREG_H
struct vreg;
struct vreg *vreg_get(struct device *dev, const char *id);
void vreg_put(struct vreg *vreg);
int vreg_enable(struct vreg *vreg);
int vreg_disable(struct vreg *vreg);
int vreg_set_level(struct vreg *vreg, unsigned mv);
#endif
/* arch/arm/mach-msm/io.c
*
* MSM7K, QSD io support
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/export.h>
#include <mach/hardware.h>
#include <asm/page.h>
#include <mach/msm_iomap.h>
#include <asm/mach/map.h>
#include "common.h"
#define MSM_CHIP_DEVICE_TYPE(name, chip, mem_type) { \
.virtual = (unsigned long) MSM_##name##_BASE, \
.pfn = __phys_to_pfn(chip##_##name##_PHYS), \
.length = chip##_##name##_SIZE, \
.type = mem_type, \
}
#define MSM_DEVICE_TYPE(name, mem_type) \
MSM_CHIP_DEVICE_TYPE(name, MSM, mem_type)
#define MSM_CHIP_DEVICE(name, chip) \
MSM_CHIP_DEVICE_TYPE(name, chip, MT_DEVICE)
#define MSM_DEVICE(name) MSM_CHIP_DEVICE(name, MSM)
#if defined(CONFIG_ARCH_MSM7X00A)
static struct map_desc msm_io_desc[] __initdata = {
MSM_DEVICE_TYPE(VIC, MT_DEVICE_NONSHARED),
MSM_CHIP_DEVICE_TYPE(CSR, MSM7X00, MT_DEVICE_NONSHARED),
MSM_DEVICE_TYPE(DMOV, MT_DEVICE_NONSHARED),
MSM_CHIP_DEVICE_TYPE(GPIO1, MSM7X00, MT_DEVICE_NONSHARED),
MSM_CHIP_DEVICE_TYPE(GPIO2, MSM7X00, MT_DEVICE_NONSHARED),
MSM_DEVICE_TYPE(CLK_CTL, MT_DEVICE_NONSHARED),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
.length = MSM_SHARED_RAM_SIZE,
.type = MT_DEVICE,
},
#if defined(CONFIG_DEBUG_MSM_UART)
{
/* Must be last: virtual and pfn filled in by debug_ll_addr() */
.length = SZ_4K,
.type = MT_DEVICE_NONSHARED,
}
#endif
};
void __init msm_map_common_io(void)
{
size_t size = ARRAY_SIZE(msm_io_desc);
/* Make sure the peripheral register window is closed, since
* we will use PTE flags (TEX[1]=1,B=0,C=1) to determine which
* pages are peripheral interface or not.
*/
asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
#if defined(CONFIG_DEBUG_MSM_UART)
#ifdef CONFIG_MMU
debug_ll_addr(&msm_io_desc[size - 1].pfn,
&msm_io_desc[size - 1].virtual);
#endif
msm_io_desc[size - 1].pfn = __phys_to_pfn(msm_io_desc[size - 1].pfn);
#endif
iotable_init(msm_io_desc, size);
}
#endif
#ifdef CONFIG_ARCH_QSD8X50
static struct map_desc qsd8x50_io_desc[] __initdata = {
MSM_DEVICE(VIC),
MSM_CHIP_DEVICE(CSR, QSD8X50),
MSM_DEVICE(DMOV),
MSM_CHIP_DEVICE(GPIO1, QSD8X50),
MSM_CHIP_DEVICE(GPIO2, QSD8X50),
MSM_DEVICE(CLK_CTL),
MSM_DEVICE(SIRC),
MSM_DEVICE(SCPLL),
MSM_DEVICE(AD5),
MSM_DEVICE(MDC),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
.length = MSM_SHARED_RAM_SIZE,
.type = MT_DEVICE,
},
};
void __init msm_map_qsd8x50_io(void)
{
debug_ll_io_init();
iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc));
}
#endif /* CONFIG_ARCH_QSD8X50 */
#ifdef CONFIG_ARCH_MSM7X30
static struct map_desc msm7x30_io_desc[] __initdata = {
MSM_DEVICE(VIC),
MSM_CHIP_DEVICE(CSR, MSM7X30),
MSM_DEVICE(DMOV),
MSM_CHIP_DEVICE(GPIO1, MSM7X30),
MSM_CHIP_DEVICE(GPIO2, MSM7X30),
MSM_DEVICE(CLK_CTL),
MSM_DEVICE(CLK_CTL_SH2),
MSM_DEVICE(AD5),
MSM_DEVICE(MDC),
MSM_DEVICE(ACC),
MSM_DEVICE(SAW),
MSM_DEVICE(GCC),
MSM_DEVICE(TCSR),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
.length = MSM_SHARED_RAM_SIZE,
.type = MT_DEVICE,
},
};
void __init msm_map_msm7x30_io(void)
{
debug_ll_io_init();
iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc));
}
#endif /* CONFIG_ARCH_MSM7X30 */
#ifdef CONFIG_ARCH_MSM7X00A
void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller)
{
if (mtype == MT_DEVICE) {
/* The peripherals in the 88000000 - D0000000 range
* are only accessible by type MT_DEVICE_NONSHARED.
* Adjust mtype as necessary to make this "just work."
*/
if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000))
mtype = MT_DEVICE_NONSHARED;
}
return __arm_ioremap_caller(phys_addr, size, mtype, caller);
}
#endif
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <mach/msm_iomap.h>
#include "smd_private.h"
enum {
IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0,
IRQ_DEBUG_SLEEP_INT = 1U << 1,
IRQ_DEBUG_SLEEP_ABORT = 1U << 2,
IRQ_DEBUG_SLEEP = 1U << 3,
IRQ_DEBUG_SLEEP_REQUEST = 1U << 4,
};
static int msm_irq_debug_mask;
module_param_named(debug_mask, msm_irq_debug_mask, int,
S_IRUGO | S_IWUSR | S_IWGRP);
#define VIC_REG(off) (MSM_VIC_BASE + (off))
#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4)
#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3)
#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT2 VIC_REG(0x0008) /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT3 VIC_REG(0x000C) /* 1: FIQ, 0: IRQ */
#define VIC_INT_EN0 VIC_REG(0x0010)
#define VIC_INT_EN1 VIC_REG(0x0014)
#define VIC_INT_EN2 VIC_REG(0x0018)
#define VIC_INT_EN3 VIC_REG(0x001C)
#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
#define VIC_INT_ENCLEAR2 VIC_REG(0x0028)
#define VIC_INT_ENCLEAR3 VIC_REG(0x002C)
#define VIC_INT_ENSET0 VIC_REG(0x0030)
#define VIC_INT_ENSET1 VIC_REG(0x0034)
#define VIC_INT_ENSET2 VIC_REG(0x0038)
#define VIC_INT_ENSET3 VIC_REG(0x003C)
#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_TYPE2 VIC_REG(0x0048) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_TYPE3 VIC_REG(0x004C) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY2 VIC_REG(0x0058) /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY3 VIC_REG(0x005C) /* 1: NEG, 0: POS */
#define VIC_NO_PEND_VAL VIC_REG(0x0060)
#if defined(CONFIG_ARCH_MSM_SCORPION)
#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064)
#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */
#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE SC VIC */
#else
#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
#endif
#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
#define VIC_IRQ_STATUS2 VIC_REG(0x0088)
#define VIC_IRQ_STATUS3 VIC_REG(0x008C)
#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
#define VIC_FIQ_STATUS2 VIC_REG(0x0098)
#define VIC_FIQ_STATUS3 VIC_REG(0x009C)
#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
#define VIC_RAW_STATUS2 VIC_REG(0x00A8)
#define VIC_RAW_STATUS3 VIC_REG(0x00AC)
#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
#define VIC_INT_CLEAR2 VIC_REG(0x00B8)
#define VIC_INT_CLEAR3 VIC_REG(0x00BC)
#define VIC_SOFTINT0 VIC_REG(0x00C0)
#define VIC_SOFTINT1 VIC_REG(0x00C4)
#define VIC_SOFTINT2 VIC_REG(0x00C8)
#define VIC_SOFTINT3 VIC_REG(0x00CC)
#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
#if defined(CONFIG_ARCH_MSM_SCORPION)
#define VIC_FIQ_VEC_RD VIC_REG(0x00DC)
#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)
#define VIC_FIQ_VEC_WR VIC_REG(0x00E4)
#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8)
#define VIC_IRQ_IN_STACK VIC_REG(0x00EC)
#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0)
#define VIC_FIQ_IN_STACK VIC_REG(0x00F4)
#define VIC_TEST_BUS_SEL VIC_REG(0x00F8)
#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC)
#else
#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
#endif
#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
#if defined(CONFIG_ARCH_MSM7X30)
#define VIC_NUM_REGS 4
#else
#define VIC_NUM_REGS 2
#endif
#if VIC_NUM_REGS == 2
#define DPRINT_REGS(base_reg, format, ...) \
printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
readl(base_reg ## 0), readl(base_reg ## 1))
#define DPRINT_ARRAY(array, format, ...) \
printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
array[0], array[1])
#elif VIC_NUM_REGS == 4
#define DPRINT_REGS(base_reg, format, ...) \
printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
readl(base_reg ## 0), readl(base_reg ## 1), \
readl(base_reg ## 2), readl(base_reg ## 3))
#define DPRINT_ARRAY(array, format, ...) \
printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
array[0], array[1], \
array[2], array[3])
#else
#error "VIC_NUM_REGS set to illegal value"
#endif
static uint32_t msm_irq_smsm_wake_enable[2];
static struct {
uint32_t int_en[2];
uint32_t int_type;
uint32_t int_polarity;
uint32_t int_select;
} msm_irq_shadow_reg[VIC_NUM_REGS];
static uint32_t msm_irq_idle_disable[VIC_NUM_REGS];
#define SMSM_FAKE_IRQ (0xff)
static uint8_t msm_irq_to_smsm[NR_IRQS] = {
[INT_MDDI_EXT] = 1,
[INT_MDDI_PRI] = 2,
[INT_MDDI_CLIENT] = 3,
[INT_USB_OTG] = 4,
[INT_PWB_I2C] = 5,
[INT_SDC1_0] = 6,
[INT_SDC1_1] = 7,
[INT_SDC2_0] = 8,
[INT_SDC2_1] = 9,
[INT_ADSP_A9_A11] = 10,
[INT_UART1] = 11,
[INT_UART2] = 12,
[INT_UART3] = 13,
[INT_UART1_RX] = 14,
[INT_UART2_RX] = 15,
[INT_UART3_RX] = 16,
[INT_UART1DM_IRQ] = 17,
[INT_UART1DM_RX] = 18,
[INT_KEYSENSE] = 19,
#if !defined(CONFIG_ARCH_MSM7X30)
[INT_AD_HSSD] = 20,
#endif
[INT_NAND_WR_ER_DONE] = 21,
[INT_NAND_OP_DONE] = 22,
[INT_TCHSCRN1] = 23,
[INT_TCHSCRN2] = 24,
[INT_TCHSCRN_SSBI] = 25,
[INT_USB_HS] = 26,
[INT_UART2DM_RX] = 27,
[INT_UART2DM_IRQ] = 28,
[INT_SDC4_1] = 29,
[INT_SDC4_0] = 30,
[INT_SDC3_1] = 31,
[INT_SDC3_0] = 32,
/* fake wakeup interrupts */
[INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
[INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
[INT_A9_M2A_0] = SMSM_FAKE_IRQ,
[INT_A9_M2A_1] = SMSM_FAKE_IRQ,
[INT_A9_M2A_5] = SMSM_FAKE_IRQ,
[INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
[INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
[INT_ADSP_A11] = SMSM_FAKE_IRQ,
#ifdef CONFIG_ARCH_QSD8X50
[INT_SIRC_0] = SMSM_FAKE_IRQ,
[INT_SIRC_1] = SMSM_FAKE_IRQ,
#endif
};
static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val)
{
int i;
for (i = 0; i < VIC_NUM_REGS; i++)
writel(val, base + (i * 4));
}
static void msm_irq_ack(struct irq_data *d)
{
void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, d->irq);
writel(1 << (d->irq & 31), reg);
}
static void msm_irq_mask(struct irq_data *d)
{
void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, d->irq);
unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
uint32_t mask = 1UL << (d->irq & 31);
int smsm_irq = msm_irq_to_smsm[d->irq];
msm_irq_shadow_reg[index].int_en[0] &= ~mask;
writel(mask, reg);
if (smsm_irq == 0)
msm_irq_idle_disable[index] &= ~mask;
else {
mask = 1UL << (smsm_irq - 1);
msm_irq_smsm_wake_enable[0] &= ~mask;
}
}
static void msm_irq_unmask(struct irq_data *d)
{
void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, d->irq);
unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
uint32_t mask = 1UL << (d->irq & 31);
int smsm_irq = msm_irq_to_smsm[d->irq];
msm_irq_shadow_reg[index].int_en[0] |= mask;
writel(mask, reg);
if (smsm_irq == 0)
msm_irq_idle_disable[index] |= mask;
else {
mask = 1UL << (smsm_irq - 1);
msm_irq_smsm_wake_enable[0] |= mask;
}
}
static int msm_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
uint32_t mask = 1UL << (d->irq & 31);
int smsm_irq = msm_irq_to_smsm[d->irq];
if (smsm_irq == 0) {
printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", d->irq);
return -EINVAL;
}
if (on)
msm_irq_shadow_reg[index].int_en[1] |= mask;
else
msm_irq_shadow_reg[index].int_en[1] &= ~mask;
if (smsm_irq == SMSM_FAKE_IRQ)
return 0;
mask = 1UL << (smsm_irq - 1);
if (on)
msm_irq_smsm_wake_enable[1] |= mask;
else
msm_irq_smsm_wake_enable[1] &= ~mask;
return 0;
}
static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, d->irq);
void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, d->irq);
unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
int b = 1 << (d->irq & 31);
uint32_t polarity;
uint32_t type;
polarity = msm_irq_shadow_reg[index].int_polarity;
if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
polarity |= b;
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
polarity &= ~b;
writel(polarity, preg);
msm_irq_shadow_reg[index].int_polarity = polarity;
type = msm_irq_shadow_reg[index].int_type;
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
type |= b;
__irq_set_handler_locked(d->irq, handle_edge_irq);
}
if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
type &= ~b;
__irq_set_handler_locked(d->irq, handle_level_irq);
}
writel(type, treg);
msm_irq_shadow_reg[index].int_type = type;
return 0;
}
static struct irq_chip msm_irq_chip = {
.name = "msm",
.irq_disable = msm_irq_mask,
.irq_ack = msm_irq_ack,
.irq_mask = msm_irq_mask,
.irq_unmask = msm_irq_unmask,
.irq_set_wake = msm_irq_set_wake,
.irq_set_type = msm_irq_set_type,
};
void __init msm_init_irq(void)
{
unsigned n;
/* select level interrupts */
msm_irq_write_all_regs(VIC_INT_TYPE0, 0);
/* select highlevel interrupts */
msm_irq_write_all_regs(VIC_INT_POLARITY0, 0);
/* select IRQ for all INTs */
msm_irq_write_all_regs(VIC_INT_SELECT0, 0);
/* disable all INTs */
msm_irq_write_all_regs(VIC_INT_EN0, 0);
/* don't use vic */
writel(0, VIC_CONFIG);
/* enable interrupt controller */
writel(3, VIC_INT_MASTEREN);
for (n = 0; n < NR_MSM_IRQS; n++) {
irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
set_irq_flags(n, IRQF_VALID);
}
}
/* linux/arch/arm/mach-msm/irq.c
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/msm_iomap.h>
#define VIC_REG(off) (MSM_VIC_BASE + (off))
#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
#define VIC_INT_EN0 VIC_REG(0x0010)
#define VIC_INT_EN1 VIC_REG(0x0014)
#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
#define VIC_INT_ENSET0 VIC_REG(0x0030)
#define VIC_INT_ENSET1 VIC_REG(0x0034)
#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
#define VIC_NO_PEND_VAL VIC_REG(0x0060)
#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
#define VIC_SOFTINT0 VIC_REG(0x00C0)
#define VIC_SOFTINT1 VIC_REG(0x00C4)
#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
static void msm_irq_ack(struct irq_data *d)
{
void __iomem *reg = VIC_INT_CLEAR0 + ((d->irq & 32) ? 4 : 0);
writel(1 << (d->irq & 31), reg);
}
static void msm_irq_mask(struct irq_data *d)
{
void __iomem *reg = VIC_INT_ENCLEAR0 + ((d->irq & 32) ? 4 : 0);
writel(1 << (d->irq & 31), reg);
}
static void msm_irq_unmask(struct irq_data *d)
{
void __iomem *reg = VIC_INT_ENSET0 + ((d->irq & 32) ? 4 : 0);
writel(1 << (d->irq & 31), reg);
}
static int msm_irq_set_wake(struct irq_data *d, unsigned int on)
{
return -EINVAL;
}
static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
void __iomem *treg = VIC_INT_TYPE0 + ((d->irq & 32) ? 4 : 0);
void __iomem *preg = VIC_INT_POLARITY0 + ((d->irq & 32) ? 4 : 0);
int b = 1 << (d->irq & 31);
if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
writel(readl(preg) | b, preg);
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
writel(readl(preg) & (~b), preg);
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
writel(readl(treg) | b, treg);
__irq_set_handler_locked(d->irq, handle_edge_irq);
}
if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
writel(readl(treg) & (~b), treg);
__irq_set_handler_locked(d->irq, handle_level_irq);
}
return 0;
}
static struct irq_chip msm_irq_chip = {
.name = "msm",
.irq_ack = msm_irq_ack,
.irq_mask = msm_irq_mask,
.irq_unmask = msm_irq_unmask,
.irq_set_wake = msm_irq_set_wake,
.irq_set_type = msm_irq_set_type,
};
void __init msm_init_irq(void)
{
unsigned n;
/* select level interrupts */
writel(0, VIC_INT_TYPE0);
writel(0, VIC_INT_TYPE1);
/* select highlevel interrupts */
writel(0, VIC_INT_POLARITY0);
writel(0, VIC_INT_POLARITY1);
/* select IRQ for all INTs */
writel(0, VIC_INT_SELECT0);
writel(0, VIC_INT_SELECT1);
/* disable all INTs */
writel(0, VIC_INT_EN0);
writel(0, VIC_INT_EN1);
/* don't use 1136 vic */
writel(0, VIC_CONFIG);
/* enable interrupt controller */
writel(1, VIC_INT_MASTEREN);
for (n = 0; n < NR_MSM_IRQS; n++) {
irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
set_irq_flags(n, IRQF_VALID);
}
}
/* arch/arm/mach-msm/last_radio_log.c
*
* Extract the log from a modem crash though SMEM
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include "smd_private.h"
static void *radio_log_base;
static size_t radio_log_size;
extern void *smem_item(unsigned id, unsigned *size);
static ssize_t last_radio_log_read(struct file *file, char __user *buf,
size_t len, loff_t *offset)
{
return simple_read_from_buffer(buf, len, offset,
radio_log_base, radio_log_size);
}
static struct file_operations last_radio_log_fops = {
.read = last_radio_log_read,
.llseek = default_llseek,
};
void msm_init_last_radio_log(struct module *owner)
{
struct proc_dir_entry *entry;
if (last_radio_log_fops.owner) {
pr_err("%s: already claimed\n", __func__);
return;
}
radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size);
if (!radio_log_base) {
pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__);
return;
}
entry = proc_create("last_radio_log", S_IRUGO, NULL,
&last_radio_log_fops);
if (!entry) {
pr_err("%s: could not create proc entry for radio log\n",
__func__);
return;
}
pr_err("%s: last radio log is %d bytes long\n", __func__,
radio_log_size);
last_radio_log_fops.owner = owner;
proc_set_size(entry, radio_log_size);
}
EXPORT_SYMBOL(msm_init_last_radio_log);
/* arch/arm/mach-msm/proc_comm.c
*
* Copyright (C) 2007-2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <mach/msm_iomap.h>
#include "proc_comm.h"
static inline void msm_a2m_int(uint32_t irq)
{
#if defined(CONFIG_ARCH_MSM7X30)
writel(1 << irq, MSM_GCC_BASE + 0x8);
#else
writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
#endif
}
static inline void notify_other_proc_comm(void)
{
msm_a2m_int(6);
}
#define APP_COMMAND 0x00
#define APP_STATUS 0x04
#define APP_DATA1 0x08
#define APP_DATA2 0x0C
#define MDM_COMMAND 0x10
#define MDM_STATUS 0x14
#define MDM_DATA1 0x18
#define MDM_DATA2 0x1C
static DEFINE_SPINLOCK(proc_comm_lock);
/* The higher level SMD support will install this to
* provide a way to check for and handle modem restart.
*/
int (*msm_check_for_modem_crash)(void);
/* Poll for a state change, checking for possible
* modem crashes along the way (so we don't wait
* forever while the ARM9 is blowing up).
*
* Return an error in the event of a modem crash and
* restart so the msm_proc_comm() routine can restart
* the operation from the beginning.
*/
static int proc_comm_wait_for(void __iomem *addr, unsigned value)
{
for (;;) {
if (readl(addr) == value)
return 0;
if (msm_check_for_modem_crash)
if (msm_check_for_modem_crash())
return -EAGAIN;
}
}
int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
{
void __iomem *base = MSM_SHARED_RAM_BASE;
unsigned long flags;
int ret;
spin_lock_irqsave(&proc_comm_lock, flags);
for (;;) {
if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
continue;
writel(cmd, base + APP_COMMAND);
writel(data1 ? *data1 : 0, base + APP_DATA1);
writel(data2 ? *data2 : 0, base + APP_DATA2);
notify_other_proc_comm();
if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
continue;
if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
if (data1)
*data1 = readl(base + APP_DATA1);
if (data2)
*data2 = readl(base + APP_DATA2);
ret = 0;
} else {
ret = -EIO;
}
break;
}
writel(PCOM_CMD_IDLE, base + APP_COMMAND);
spin_unlock_irqrestore(&proc_comm_lock, flags);
return ret;
}
/*
* We need to wait for the ARM9 to at least partially boot
* up before we can continue. Since the ARM9 does resource
* allocation, if we dont' wait we could end up crashing or in
* and unknown state. This function should be called early to
* wait on the ARM9.
*/
void proc_comm_boot_wait(void)
{
void __iomem *base = MSM_SHARED_RAM_BASE;
proc_comm_wait_for(base + MDM_STATUS, PCOM_READY);
}
/* arch/arm/mach-msm/proc_comm.h
*
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
#include <linux/init.h>
enum {
PCOM_CMD_IDLE = 0x0,
PCOM_CMD_DONE,
PCOM_RESET_APPS,
PCOM_RESET_CHIP,
PCOM_CONFIG_NAND_MPU,
PCOM_CONFIG_USB_CLKS,
PCOM_GET_POWER_ON_STATUS,
PCOM_GET_WAKE_UP_STATUS,
PCOM_GET_BATT_LEVEL,
PCOM_CHG_IS_CHARGING,
PCOM_POWER_DOWN,
PCOM_USB_PIN_CONFIG,
PCOM_USB_PIN_SEL,
PCOM_SET_RTC_ALARM,
PCOM_NV_READ,
PCOM_NV_WRITE,
PCOM_GET_UUID_HIGH,
PCOM_GET_UUID_LOW,
PCOM_GET_HW_ENTROPY,
PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
PCOM_CLKCTL_RPC_ENABLE,
PCOM_CLKCTL_RPC_DISABLE,
PCOM_CLKCTL_RPC_RESET,
PCOM_CLKCTL_RPC_SET_FLAGS,
PCOM_CLKCTL_RPC_SET_RATE,
PCOM_CLKCTL_RPC_MIN_RATE,
PCOM_CLKCTL_RPC_MAX_RATE,
PCOM_CLKCTL_RPC_RATE,
PCOM_CLKCTL_RPC_PLL_REQUEST,
PCOM_CLKCTL_RPC_ENABLED,
PCOM_VREG_SWITCH,
PCOM_VREG_SET_LEVEL,
PCOM_GPIO_TLMM_CONFIG_GROUP,
PCOM_GPIO_TLMM_UNCONFIG_GROUP,
PCOM_NV_WRITE_BYTES_4_7,
PCOM_CONFIG_DISP,
PCOM_GET_FTM_BOOT_COUNT,
PCOM_RPC_GPIO_TLMM_CONFIG_EX,
PCOM_PM_MPP_CONFIG,
PCOM_GPIO_IN,
PCOM_GPIO_OUT,
PCOM_RESET_MODEM,
PCOM_RESET_CHIP_IMM,
PCOM_PM_VID_EN,
PCOM_VREG_PULLDOWN,
PCOM_GET_MODEM_VERSION,
PCOM_CLK_REGIME_SEC_RESET,
PCOM_CLK_REGIME_SEC_RESET_ASSERT,
PCOM_CLK_REGIME_SEC_RESET_DEASSERT,
PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP,
PCOM_CLK_REGIME_SEC_ENABLE,
PCOM_CLK_REGIME_SEC_DISABLE,
PCOM_CLK_REGIME_SEC_IS_ON,
PCOM_CLK_REGIME_SEC_SEL_CLK_INV,
PCOM_CLK_REGIME_SEC_SEL_CLK_SRC,
PCOM_CLK_REGIME_SEC_SEL_CLK_DIV,
PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE,
PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE,
PCOM_CLK_REGIME_SEC_SEL_SPEED,
PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP,
PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP,
PCOM_CLK_REGIME_SEC_USB_XTAL_ON,
PCOM_CLK_REGIME_SEC_USB_XTAL_OFF,
PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE,
PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK,
PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ,
PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ,
PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ,
PCOM_CLK_REGIME_SEC_SEL_VFE_SRC,
PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK,
PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK,
PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF,
PCOM_CLK_REGIME_SEC_VFE_RAIL_ON,
PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF,
PCOM_CLK_REGIME_SEC_GRP_RAIL_ON,
PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF,
PCOM_CLK_REGIME_SEC_VDC_RAIL_ON,
PCOM_CLK_REGIME_SEC_LCD_CTRL,
PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE,
PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE,
PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP,
PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER,
PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP,
PCOM_GPIO_CONFIG,
PCOM_GPIO_CONFIGURE_GROUP,
PCOM_GPIO_TLMM_SET_PORT,
PCOM_GPIO_TLMM_CONFIG_EX,
PCOM_SET_FTM_BOOT_COUNT,
PCOM_RESERVED0,
PCOM_RESERVED1,
PCOM_CUSTOMER_CMD1,
PCOM_CUSTOMER_CMD2,
PCOM_CUSTOMER_CMD3,
PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE,
PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE,
PCOM_CLK_REGIME_SEC_RAIL_DISABLE,
PCOM_CLK_REGIME_SEC_RAIL_ENABLE,
PCOM_CLK_REGIME_SEC_RAIL_CONTROL,
PCOM_SET_SW_WATCHDOG_STATE,
PCOM_PM_MPP_CONFIG_DIGITAL_INPUT,
PCOM_PM_MPP_CONFIG_I_SINK,
PCOM_RESERVED_101,
PCOM_MSM_HSUSB_PHY_RESET,
PCOM_GET_BATT_MV_LEVEL,
PCOM_CHG_USB_IS_PC_CONNECTED,
PCOM_CHG_USB_IS_CHARGER_CONNECTED,
PCOM_CHG_USB_IS_DISCONNECTED,
PCOM_CHG_USB_IS_AVAILABLE,
PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ,
PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY,
PCOM_CLKCTL_RPC_RESET_ASSERT,
PCOM_CLKCTL_RPC_RESET_DEASSERT,
PCOM_CLKCTL_RPC_RAIL_ON,
PCOM_CLKCTL_RPC_RAIL_OFF,
PCOM_CLKCTL_RPC_RAIL_ENABLE,
PCOM_CLKCTL_RPC_RAIL_DISABLE,
PCOM_CLKCTL_RPC_RAIL_CONTROL,
PCOM_CLKCTL_RPC_MIN_MSMC1,
PCOM_NUM_CMDS,
};
enum {
PCOM_INVALID_STATUS = 0x0,
PCOM_READY,
PCOM_CMD_RUNNING,
PCOM_CMD_SUCCESS,
PCOM_CMD_FAIL,
PCOM_CMD_FAIL_FALSE_RETURNED,
PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER,
PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT,
PCOM_CMD_FAIL_CMD_UNREGISTERED,
PCOM_CMD_FAIL_CMD_LOCKED,
PCOM_CMD_FAIL_SERVER_NOT_YET_READY,
PCOM_CMD_FAIL_BAD_DESTINATION,
PCOM_CMD_FAIL_SERVER_RESET,
PCOM_CMD_FAIL_SMSM_NOT_INIT,
PCOM_CMD_FAIL_PROC_COMM_BUSY,
PCOM_CMD_FAIL_PROC_COMM_NOT_INIT,
};
/* List of VREGs that support the Pull Down Resistor setting. */
enum vreg_pdown_id {
PM_VREG_PDOWN_MSMA_ID,
PM_VREG_PDOWN_MSMP_ID,
PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
PM_VREG_PDOWN_MSMC1_ID, /* Not supported in PM6620 */
PM_VREG_PDOWN_MSMC2_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP3_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_MSME2_ID, /* Supported in PM7500 and Panoramix only */
PM_VREG_PDOWN_GP4_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP1_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_TCXO_ID,
PM_VREG_PDOWN_PA_ID,
PM_VREG_PDOWN_RFTX_ID,
PM_VREG_PDOWN_RFRX1_ID,
PM_VREG_PDOWN_RFRX2_ID,
PM_VREG_PDOWN_SYNT_ID,
PM_VREG_PDOWN_WLAN_ID,
PM_VREG_PDOWN_USB_ID,
PM_VREG_PDOWN_MMC_ID,
PM_VREG_PDOWN_RUIM_ID,
PM_VREG_PDOWN_MSMC0_ID, /* Supported in PM6610 only */
PM_VREG_PDOWN_GP2_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP5_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP6_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_RF_ID,
PM_VREG_PDOWN_RF_VCO_ID,
PM_VREG_PDOWN_MPLL_ID,
PM_VREG_PDOWN_S2_ID,
PM_VREG_PDOWN_S3_ID,
PM_VREG_PDOWN_RFUBM_ID,
/* new for HAN */
PM_VREG_PDOWN_RF1_ID,
PM_VREG_PDOWN_RF2_ID,
PM_VREG_PDOWN_RFA_ID,
PM_VREG_PDOWN_CDC2_ID,
PM_VREG_PDOWN_RFTX2_ID,
PM_VREG_PDOWN_USIM_ID,
PM_VREG_PDOWN_USB2P6_ID,
PM_VREG_PDOWN_USB3P3_ID,
PM_VREG_PDOWN_INVALID_ID,
/* backward compatible enums only */
PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
};
enum {
PCOM_CLKRGM_APPS_RESET_USB_PHY = 34,
PCOM_CLKRGM_APPS_RESET_USBH = 37,
};
/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
#define GPIO_ENABLE 0
#define GPIO_DISABLE 1
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
#define GPIO_NO_PULL 0
#define GPIO_PULL_DOWN 1
#define GPIO_KEEPER 2
#define GPIO_PULL_UP 3
#define GPIO_2MA 0
#define GPIO_4MA 1
#define GPIO_6MA 2
#define GPIO_8MA 3
#define GPIO_10MA 4
#define GPIO_12MA 5
#define GPIO_14MA 6
#define GPIO_16MA 7
#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
((((gpio) & 0x3FF) << 4) | \
((func) & 0xf) | \
(((dir) & 0x1) << 14) | \
(((pull) & 0x3) << 15) | \
(((drvstr) & 0xF) << 17))
int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
void proc_comm_boot_wait(void);
#endif
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
static unsigned int int_enable;
static unsigned int wake_enable;
static struct sirc_regs_t sirc_regs = {
.int_enable = SPSS_SIRC_INT_ENABLE,
.int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR,
.int_enable_set = SPSS_SIRC_INT_ENABLE_SET,
.int_type = SPSS_SIRC_INT_TYPE,
.int_polarity = SPSS_SIRC_INT_POLARITY,
.int_clear = SPSS_SIRC_INT_CLEAR,
};
static struct sirc_cascade_regs sirc_reg_table[] = {
{
.int_status = SPSS_SIRC_IRQ_STATUS,
.cascade_irq = INT_SIRC_0,
}
};
/* Mask off the given interrupt. Keep the int_enable mask in sync with
the enable reg, so it can be restored after power collapse. */
static void sirc_irq_mask(struct irq_data *d)
{
unsigned int mask;
mask = 1 << (d->irq - FIRST_SIRC_IRQ);
writel(mask, sirc_regs.int_enable_clear);
int_enable &= ~mask;
return;
}
/* Unmask the given interrupt. Keep the int_enable mask in sync with
the enable reg, so it can be restored after power collapse. */
static void sirc_irq_unmask(struct irq_data *d)
{
unsigned int mask;
mask = 1 << (d->irq - FIRST_SIRC_IRQ);
writel(mask, sirc_regs.int_enable_set);
int_enable |= mask;
return;
}
static void sirc_irq_ack(struct irq_data *d)
{
unsigned int mask;
mask = 1 << (d->irq - FIRST_SIRC_IRQ);
writel(mask, sirc_regs.int_clear);
return;
}
static int sirc_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned int mask;
/* Used to set the interrupt enable mask during power collapse. */
mask = 1 << (d->irq - FIRST_SIRC_IRQ);
if (on)
wake_enable |= mask;
else
wake_enable &= ~mask;
return 0;
}
static int sirc_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
unsigned int mask;
unsigned int val;
mask = 1 << (d->irq - FIRST_SIRC_IRQ);
val = readl(sirc_regs.int_polarity);
if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING))
val |= mask;
else
val &= ~mask;
writel(val, sirc_regs.int_polarity);
val = readl(sirc_regs.int_type);
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
val |= mask;
__irq_set_handler_locked(d->irq, handle_edge_irq);
} else {
val &= ~mask;
__irq_set_handler_locked(d->irq, handle_level_irq);
}
writel(val, sirc_regs.int_type);
return 0;
}
/* Finds the pending interrupt on the passed cascade irq and redrives it */
static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned int reg = 0;
unsigned int sirq;
unsigned int status;
while ((reg < ARRAY_SIZE(sirc_reg_table)) &&
(sirc_reg_table[reg].cascade_irq != irq))
reg++;
status = readl(sirc_reg_table[reg].int_status);
status &= SIRC_MASK;
if (status == 0)
return;
for (sirq = 0;
(sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0);
sirq++)
;
generic_handle_irq(sirq+FIRST_SIRC_IRQ);
desc->irq_data.chip->irq_ack(&desc->irq_data);
}
static struct irq_chip sirc_irq_chip = {
.name = "sirc",
.irq_ack = sirc_irq_ack,
.irq_mask = sirc_irq_mask,
.irq_unmask = sirc_irq_unmask,
.irq_set_wake = sirc_irq_set_wake,
.irq_set_type = sirc_irq_set_type,
};
void __init msm_init_sirc(void)
{
int i;
int_enable = 0;
wake_enable = 0;
for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
irq_set_chip_and_handler(i, &sirc_irq_chip, handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
irq_set_chained_handler(sirc_reg_table[i].cascade_irq,
sirc_irq_handler);
irq_set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
}
return;
}
/* arch/arm/mach-msm/smd.c
*
* Copyright (C) 2007 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <mach/msm_smd.h>
#include "smd_private.h"
#include "proc_comm.h"
#if defined(CONFIG_ARCH_QSD8X50)
#define CONFIG_QDSP6 1
#endif
#define MODULE_NAME "msm_smd"
enum {
MSM_SMD_DEBUG = 1U << 0,
MSM_SMSM_DEBUG = 1U << 0,
};
static int msm_smd_debug_mask;
struct shared_info {
int ready;
void __iomem *state;
};
static unsigned dummy_state[SMSM_STATE_COUNT];
static struct shared_info smd_info = {
/* FIXME: not a real __iomem pointer */
.state = &dummy_state,
};
module_param_named(debug_mask, msm_smd_debug_mask,
int, S_IRUGO | S_IWUSR | S_IWGRP);
static unsigned last_heap_free = 0xffffffff;
static inline void notify_other_smsm(void)
{
msm_a2m_int(5);
#ifdef CONFIG_QDSP6
msm_a2m_int(8);
#endif
}
static inline void notify_modem_smd(void)
{
msm_a2m_int(0);
}
static inline void notify_dsp_smd(void)
{
msm_a2m_int(8);
}
static void smd_diag(void)
{
char *x;
x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
if (x != 0) {
x[SZ_DIAG_ERR_MSG - 1] = 0;
pr_debug("DIAG '%s'\n", x);
}
}
/* call when SMSM_RESET flag is set in the A9's smsm_state */
static void handle_modem_crash(void)
{
pr_err("ARM9 has CRASHED\n");
smd_diag();
/* in this case the modem or watchdog should reboot us */
for (;;)
;
}
uint32_t raw_smsm_get_state(enum smsm_state_item item)
{
return readl(smd_info.state + item * 4);
}
static int check_for_modem_crash(void)
{
if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
handle_modem_crash();
return -1;
}
return 0;
}
/* the spinlock is used to synchronize between the
* irq handler and code that mutates the channel
* list or fiddles with channel state
*/
DEFINE_SPINLOCK(smd_lock);
DEFINE_SPINLOCK(smem_lock);
/* the mutex is used during open() and close()
* operations to avoid races while creating or
* destroying smd_channel structures
*/
static DEFINE_MUTEX(smd_creation_mutex);
static int smd_initialized;
LIST_HEAD(smd_ch_closed_list);
LIST_HEAD(smd_ch_list_modem);
LIST_HEAD(smd_ch_list_dsp);
static unsigned char smd_ch_allocated[64];
static struct work_struct probe_work;
/* how many bytes are available for reading */
static int smd_stream_read_avail(struct smd_channel *ch)
{
return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
}
/* how many bytes we are free to write */
static int smd_stream_write_avail(struct smd_channel *ch)
{
return ch->fifo_mask -
((ch->send->head - ch->send->tail) & ch->fifo_mask);
}
static int smd_packet_read_avail(struct smd_channel *ch)
{
if (ch->current_packet) {
int n = smd_stream_read_avail(ch);
if (n > ch->current_packet)
n = ch->current_packet;
return n;
} else {
return 0;
}
}
static int smd_packet_write_avail(struct smd_channel *ch)
{
int n = smd_stream_write_avail(ch);
return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
}
static int ch_is_open(struct smd_channel *ch)
{
return (ch->recv->state == SMD_SS_OPENED) &&
(ch->send->state == SMD_SS_OPENED);
}
/* provide a pointer and length to readable data in the fifo */
static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
{
unsigned head = ch->recv->head;
unsigned tail = ch->recv->tail;
*ptr = (void *) (ch->recv_data + tail);
if (tail <= head)
return head - tail;
else
return ch->fifo_size - tail;
}
/* advance the fifo read pointer after data from ch_read_buffer is consumed */
static void ch_read_done(struct smd_channel *ch, unsigned count)
{
BUG_ON(count > smd_stream_read_avail(ch));
ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
ch->send->fTAIL = 1;
}
/* basic read interface to ch_read_{buffer,done} used
* by smd_*_read() and update_packet_state()
* will read-and-discard if the _data pointer is null
*/
static int ch_read(struct smd_channel *ch, void *_data, int len)
{
void *ptr;
unsigned n;
unsigned char *data = _data;
int orig_len = len;
while (len > 0) {
n = ch_read_buffer(ch, &ptr);
if (n == 0)
break;
if (n > len)
n = len;
if (_data)
memcpy(data, ptr, n);
data += n;
len -= n;
ch_read_done(ch, n);
}
return orig_len - len;
}
static void update_stream_state(struct smd_channel *ch)
{
/* streams have no special state requiring updating */
}
static void update_packet_state(struct smd_channel *ch)
{
unsigned hdr[5];
int r;
/* can't do anything if we're in the middle of a packet */
if (ch->current_packet != 0)
return;
/* don't bother unless we can get the full header */
if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
return;
r = ch_read(ch, hdr, SMD_HEADER_SIZE);
BUG_ON(r != SMD_HEADER_SIZE);
ch->current_packet = hdr[0];
}
/* provide a pointer and length to next free space in the fifo */
static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
{
unsigned head = ch->send->head;
unsigned tail = ch->send->tail;
*ptr = (void *) (ch->send_data + head);
if (head < tail) {
return tail - head - 1;
} else {
if (tail == 0)
return ch->fifo_size - head - 1;
else
return ch->fifo_size - head;
}
}
/* advace the fifo write pointer after freespace
* from ch_write_buffer is filled
*/
static void ch_write_done(struct smd_channel *ch, unsigned count)
{
BUG_ON(count > smd_stream_write_avail(ch));
ch->send->head = (ch->send->head + count) & ch->fifo_mask;
ch->send->fHEAD = 1;
}
static void ch_set_state(struct smd_channel *ch, unsigned n)
{
if (n == SMD_SS_OPENED) {
ch->send->fDSR = 1;
ch->send->fCTS = 1;
ch->send->fCD = 1;
} else {
ch->send->fDSR = 0;
ch->send->fCTS = 0;
ch->send->fCD = 0;
}
ch->send->state = n;
ch->send->fSTATE = 1;
ch->notify_other_cpu();
}
static void do_smd_probe(void)
{
struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
if (shared->heap_info.free_offset != last_heap_free) {
last_heap_free = shared->heap_info.free_offset;
schedule_work(&probe_work);
}
}
static void smd_state_change(struct smd_channel *ch,
unsigned last, unsigned next)
{
ch->last_state = next;
pr_debug("ch %d %d -> %d\n", ch->n, last, next);
switch (next) {
case SMD_SS_OPENING:
ch->recv->tail = 0;
case SMD_SS_OPENED:
if (ch->send->state != SMD_SS_OPENED)
ch_set_state(ch, SMD_SS_OPENED);
ch->notify(ch->priv, SMD_EVENT_OPEN);
break;
case SMD_SS_FLUSHING:
case SMD_SS_RESET:
/* we should force them to close? */
default:
ch->notify(ch->priv, SMD_EVENT_CLOSE);
}
}
static void handle_smd_irq(struct list_head *list, void (*notify)(void))
{
unsigned long flags;
struct smd_channel *ch;
int do_notify = 0;
unsigned ch_flags;
unsigned tmp;
spin_lock_irqsave(&smd_lock, flags);
list_for_each_entry(ch, list, ch_list) {
ch_flags = 0;
if (ch_is_open(ch)) {
if (ch->recv->fHEAD) {
ch->recv->fHEAD = 0;
ch_flags |= 1;
do_notify |= 1;
}
if (ch->recv->fTAIL) {
ch->recv->fTAIL = 0;
ch_flags |= 2;
do_notify |= 1;
}
if (ch->recv->fSTATE) {
ch->recv->fSTATE = 0;
ch_flags |= 4;
do_notify |= 1;
}
}
tmp = ch->recv->state;
if (tmp != ch->last_state)
smd_state_change(ch, ch->last_state, tmp);
if (ch_flags) {
ch->update_state(ch);
ch->notify(ch->priv, SMD_EVENT_DATA);
}
}
if (do_notify)
notify();
spin_unlock_irqrestore(&smd_lock, flags);
do_smd_probe();
}
static irqreturn_t smd_modem_irq_handler(int irq, void *data)
{
handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
return IRQ_HANDLED;
}
#if defined(CONFIG_QDSP6)
static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
{
handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
return IRQ_HANDLED;
}
#endif
static void smd_fake_irq_handler(unsigned long arg)
{
handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
}
static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
static inline int smd_need_int(struct smd_channel *ch)
{
if (ch_is_open(ch)) {
if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
return 1;
if (ch->recv->state != ch->last_state)
return 1;
}
return 0;
}
void smd_sleep_exit(void)
{
unsigned long flags;
struct smd_channel *ch;
int need_int = 0;
spin_lock_irqsave(&smd_lock, flags);
list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
spin_unlock_irqrestore(&smd_lock, flags);
do_smd_probe();
if (need_int) {
if (msm_smd_debug_mask & MSM_SMD_DEBUG)
pr_info("smd_sleep_exit need interrupt\n");
tasklet_schedule(&smd_fake_irq_tasklet);
}
}
void smd_kick(smd_channel_t *ch)
{
unsigned long flags;
unsigned tmp;
spin_lock_irqsave(&smd_lock, flags);
ch->update_state(ch);
tmp = ch->recv->state;
if (tmp != ch->last_state) {
ch->last_state = tmp;
if (tmp == SMD_SS_OPENED)
ch->notify(ch->priv, SMD_EVENT_OPEN);
else
ch->notify(ch->priv, SMD_EVENT_CLOSE);
}
ch->notify(ch->priv, SMD_EVENT_DATA);
ch->notify_other_cpu();
spin_unlock_irqrestore(&smd_lock, flags);
}
static int smd_is_packet(int chn, unsigned type)
{
type &= SMD_KIND_MASK;
if (type == SMD_KIND_PACKET)
return 1;
if (type == SMD_KIND_STREAM)
return 0;
/* older AMSS reports SMD_KIND_UNKNOWN always */
if ((chn > 4) || (chn == 1))
return 1;
else
return 0;
}
static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
{
void *ptr;
const unsigned char *buf = _data;
unsigned xfer;
int orig_len = len;
if (len < 0)
return -EINVAL;
while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
if (!ch_is_open(ch))
break;
if (xfer > len)
xfer = len;
memcpy(ptr, buf, xfer);
ch_write_done(ch, xfer);
len -= xfer;
buf += xfer;
if (len == 0)
break;
}
ch->notify_other_cpu();
return orig_len - len;
}
static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
{
unsigned hdr[5];
if (len < 0)
return -EINVAL;
if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
return -ENOMEM;
hdr[0] = len;
hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
smd_stream_write(ch, hdr, sizeof(hdr));
smd_stream_write(ch, _data, len);
return len;
}
static int smd_stream_read(smd_channel_t *ch, void *data, int len)
{
int r;
if (len < 0)
return -EINVAL;
r = ch_read(ch, data, len);
if (r > 0)
ch->notify_other_cpu();
return r;
}
static int smd_packet_read(smd_channel_t *ch, void *data, int len)
{
unsigned long flags;
int r;
if (len < 0)
return -EINVAL;
if (len > ch->current_packet)
len = ch->current_packet;
r = ch_read(ch, data, len);
if (r > 0)
ch->notify_other_cpu();
spin_lock_irqsave(&smd_lock, flags);
ch->current_packet -= r;
update_packet_state(ch);
spin_unlock_irqrestore(&smd_lock, flags);
return r;
}
static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
{
struct smd_channel *ch;
ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
if (ch == 0) {
pr_err("smd_alloc_channel() out of memory\n");
return -1;
}
ch->n = cid;
if (_smd_alloc_channel(ch)) {
kfree(ch);
return -1;
}
ch->fifo_mask = ch->fifo_size - 1;
ch->type = type;
if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
ch->notify_other_cpu = notify_modem_smd;
else
ch->notify_other_cpu = notify_dsp_smd;
if (smd_is_packet(cid, type)) {
ch->read = smd_packet_read;
ch->write = smd_packet_write;
ch->read_avail = smd_packet_read_avail;
ch->write_avail = smd_packet_write_avail;
ch->update_state = update_packet_state;
} else {
ch->read = smd_stream_read;
ch->write = smd_stream_write;
ch->read_avail = smd_stream_read_avail;
ch->write_avail = smd_stream_write_avail;
ch->update_state = update_stream_state;
}
if ((type & 0xff) == 0)
memcpy(ch->name, "SMD_", 4);
else
memcpy(ch->name, "DSP_", 4);
memcpy(ch->name + 4, name, 20);
ch->name[23] = 0;
ch->pdev.name = ch->name;
ch->pdev.id = -1;
pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
ch->n, ch->fifo_size, ch->name);
mutex_lock(&smd_creation_mutex);
list_add(&ch->ch_list, &smd_ch_closed_list);
mutex_unlock(&smd_creation_mutex);
platform_device_register(&ch->pdev);
return 0;
}
static void smd_channel_probe_worker(struct work_struct *work)
{
struct smd_alloc_elm *shared;
unsigned ctype;
unsigned type;
unsigned n;
shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
if (!shared) {
pr_err("cannot find allocation table\n");
return;
}
for (n = 0; n < 64; n++) {
if (smd_ch_allocated[n])
continue;
if (!shared[n].ref_count)
continue;
if (!shared[n].name[0])
continue;
ctype = shared[n].ctype;
type = ctype & SMD_TYPE_MASK;
/* DAL channels are stream but neither the modem,
* nor the DSP correctly indicate this. Fixup manually.
*/
if (!memcmp(shared[n].name, "DAL", 3))
ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
type = shared[n].ctype & SMD_TYPE_MASK;
if ((type == SMD_TYPE_APPS_MODEM) ||
(type == SMD_TYPE_APPS_DSP))
if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
smd_ch_allocated[n] = 1;
}
}
static void do_nothing_notify(void *priv, unsigned flags)
{
}
struct smd_channel *smd_get_channel(const char *name)
{
struct smd_channel *ch;
mutex_lock(&smd_creation_mutex);
list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
if (!strcmp(name, ch->name)) {
list_del(&ch->ch_list);
mutex_unlock(&smd_creation_mutex);
return ch;
}
}
mutex_unlock(&smd_creation_mutex);
return NULL;
}
int smd_open(const char *name, smd_channel_t **_ch,
void *priv, void (*notify)(void *, unsigned))
{
struct smd_channel *ch;
unsigned long flags;
if (smd_initialized == 0) {
pr_info("smd_open() before smd_init()\n");
return -ENODEV;
}
ch = smd_get_channel(name);
if (!ch)
return -ENODEV;
if (notify == 0)
notify = do_nothing_notify;
ch->notify = notify;
ch->current_packet = 0;
ch->last_state = SMD_SS_CLOSED;
ch->priv = priv;
*_ch = ch;
spin_lock_irqsave(&smd_lock, flags);
if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
list_add(&ch->ch_list, &smd_ch_list_modem);
else
list_add(&ch->ch_list, &smd_ch_list_dsp);
/* If the remote side is CLOSING, we need to get it to
* move to OPENING (which we'll do by moving from CLOSED to
* OPENING) and then get it to move from OPENING to
* OPENED (by doing the same state change ourselves).
*
* Otherwise, it should be OPENING and we can move directly
* to OPENED so that it will follow.
*/
if (ch->recv->state == SMD_SS_CLOSING) {
ch->send->head = 0;
ch_set_state(ch, SMD_SS_OPENING);
} else {
ch_set_state(ch, SMD_SS_OPENED);
}
spin_unlock_irqrestore(&smd_lock, flags);
smd_kick(ch);
return 0;
}
int smd_close(smd_channel_t *ch)
{
unsigned long flags;
if (ch == 0)
return -1;
spin_lock_irqsave(&smd_lock, flags);
ch->notify = do_nothing_notify;
list_del(&ch->ch_list);
ch_set_state(ch, SMD_SS_CLOSED);
spin_unlock_irqrestore(&smd_lock, flags);
mutex_lock(&smd_creation_mutex);
list_add(&ch->ch_list, &smd_ch_closed_list);
mutex_unlock(&smd_creation_mutex);
return 0;
}
int smd_read(smd_channel_t *ch, void *data, int len)
{
return ch->read(ch, data, len);
}
int smd_write(smd_channel_t *ch, const void *data, int len)
{
return ch->write(ch, data, len);
}
int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
{
unsigned long flags;
int res;
spin_lock_irqsave(&smd_lock, flags);
res = ch->write(ch, data, len);
spin_unlock_irqrestore(&smd_lock, flags);
return res;
}
int smd_read_avail(smd_channel_t *ch)
{
return ch->read_avail(ch);
}
int smd_write_avail(smd_channel_t *ch)
{
return ch->write_avail(ch);
}
int smd_wait_until_readable(smd_channel_t *ch, int bytes)
{
return -1;
}
int smd_wait_until_writable(smd_channel_t *ch, int bytes)
{
return -1;
}
int smd_cur_packet_size(smd_channel_t *ch)
{
return ch->current_packet;
}
/* ------------------------------------------------------------------------- */
void *smem_alloc(unsigned id, unsigned size)
{
return smem_find(id, size);
}
void __iomem *smem_item(unsigned id, unsigned *size)
{
struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
struct smem_heap_entry *toc = shared->heap_toc;
if (id >= SMEM_NUM_ITEMS)
return NULL;
if (toc[id].allocated) {
*size = toc[id].size;
return (MSM_SHARED_RAM_BASE + toc[id].offset);
} else {
*size = 0;
}
return NULL;
}
void *smem_find(unsigned id, unsigned size_in)
{
unsigned size;
void *ptr;
ptr = smem_item(id, &size);
if (!ptr)
return 0;
size_in = ALIGN(size_in, 8);
if (size_in != size) {
pr_err("smem_find(%d, %d): wrong size %d\n",
id, size_in, size);
return 0;
}
return ptr;
}
static irqreturn_t smsm_irq_handler(int irq, void *data)
{
unsigned long flags;
unsigned apps, modm;
spin_lock_irqsave(&smem_lock, flags);
apps = raw_smsm_get_state(SMSM_STATE_APPS);
modm = raw_smsm_get_state(SMSM_STATE_MODEM);
if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
pr_info("<SM %08x %08x>\n", apps, modm);
if (modm & SMSM_RESET)
handle_modem_crash();
do_smd_probe();
spin_unlock_irqrestore(&smem_lock, flags);
return IRQ_HANDLED;
}
int smsm_change_state(enum smsm_state_item item,
uint32_t clear_mask, uint32_t set_mask)
{
void __iomem *addr = smd_info.state + item * 4;
unsigned long flags;
unsigned state;
if (!smd_info.ready)
return -EIO;
spin_lock_irqsave(&smem_lock, flags);
if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
handle_modem_crash();
state = (readl(addr) & ~clear_mask) | set_mask;
writel(state, addr);
if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
pr_info("smsm_change_state %d %x\n", item, state);
notify_other_smsm();
spin_unlock_irqrestore(&smem_lock, flags);
return 0;
}
uint32_t smsm_get_state(enum smsm_state_item item)
{
unsigned long flags;
uint32_t rv;
spin_lock_irqsave(&smem_lock, flags);
rv = readl(smd_info.state + item * 4);
if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
handle_modem_crash();
spin_unlock_irqrestore(&smem_lock, flags);
return rv;
}
#ifdef CONFIG_ARCH_MSM_SCORPION
int smsm_set_sleep_duration(uint32_t delay)
{
struct msm_dem_slave_data *ptr;
ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
if (ptr == NULL) {
pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
return -EIO;
}
if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
pr_info("smsm_set_sleep_duration %d -> %d\n",
ptr->sleep_time, delay);
ptr->sleep_time = delay;
return 0;
}
#else
int smsm_set_sleep_duration(uint32_t delay)
{
uint32_t *ptr;
ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
if (ptr == NULL) {
pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
return -EIO;
}
if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
pr_info("smsm_set_sleep_duration %d -> %d\n",
*ptr, delay);
*ptr = delay;
return 0;
}
#endif
int smd_core_init(void)
{
int r;
/* wait for essential items to be initialized */
for (;;) {
unsigned size;
void __iomem *state;
state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
smd_info.state = state;
break;
}
}
smd_info.ready = 1;
r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
IRQF_TRIGGER_RISING, "smd_dev", 0);
if (r < 0)
return r;
r = enable_irq_wake(INT_A9_M2A_0);
if (r < 0)
pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
IRQF_TRIGGER_RISING, "smsm_dev", 0);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
return r;
}
r = enable_irq_wake(INT_A9_M2A_5);
if (r < 0)
pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
#if defined(CONFIG_QDSP6)
r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
IRQF_TRIGGER_RISING, "smd_dsp", 0);
if (r < 0) {
free_irq(INT_A9_M2A_0, 0);
free_irq(INT_A9_M2A_5, 0);
return r;
}
#endif
/* check for any SMD channels that may already exist */
do_smd_probe();
/* indicate that we're up and running */
smsm_change_state(SMSM_STATE_APPS,
~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
#ifdef CONFIG_ARCH_MSM_SCORPION
smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
#endif
return 0;
}
static int msm_smd_probe(struct platform_device *pdev)
{
/*
* If we haven't waited for the ARM9 to boot up till now,
* then we need to wait here. Otherwise this should just
* return immediately.
*/
proc_comm_boot_wait();
INIT_WORK(&probe_work, smd_channel_probe_worker);
if (smd_core_init()) {
pr_err("smd_core_init() failed\n");
return -1;
}
do_smd_probe();
msm_check_for_modem_crash = check_for_modem_crash;
msm_init_last_radio_log(THIS_MODULE);
smd_initialized = 1;
return 0;
}
static struct platform_driver msm_smd_driver = {
.probe = msm_smd_probe,
.driver = {
.name = MODULE_NAME,
},
};
static int __init msm_smd_init(void)
{
return platform_driver_register(&msm_smd_driver);
}
module_init(msm_smd_init);
MODULE_DESCRIPTION("MSM Shared Memory Core");
MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
MODULE_LICENSE("GPL");
/* arch/arm/mach-msm/smd_debug.c
*
* Copyright (C) 2007 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/debugfs.h>
#include <linux/list.h>
#include <mach/msm_iomap.h>
#include "smd_private.h"
#if defined(CONFIG_DEBUG_FS)
static char *chstate(unsigned n)
{
switch (n) {
case SMD_SS_CLOSED:
return "CLOSED";
case SMD_SS_OPENING:
return "OPENING";
case SMD_SS_OPENED:
return "OPENED";
case SMD_SS_FLUSHING:
return "FLUSHING";
case SMD_SS_CLOSING:
return "CLOSING";
case SMD_SS_RESET:
return "RESET";
case SMD_SS_RESET_OPENING:
return "ROPENING";
default:
return "UNKNOWN";
}
}
static int dump_ch(char *buf, int max, struct smd_channel *ch)
{
volatile struct smd_half_channel *s = ch->send;
volatile struct smd_half_channel *r = ch->recv;
return scnprintf(
buf, max,
"ch%02d:"
" %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
" %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
chstate(s->state), s->tail, s->head,
s->fDSR ? 'D' : 'd',
s->fCTS ? 'C' : 'c',
s->fCD ? 'C' : 'c',
s->fRI ? 'I' : 'i',
s->fHEAD ? 'W' : 'w',
s->fTAIL ? 'R' : 'r',
s->fSTATE ? 'S' : 's',
chstate(r->state), r->tail, r->head,
r->fDSR ? 'D' : 'd',
r->fCTS ? 'R' : 'r',
r->fCD ? 'C' : 'c',
r->fRI ? 'I' : 'i',
r->fHEAD ? 'W' : 'w',
r->fTAIL ? 'R' : 'r',
r->fSTATE ? 'S' : 's',
ch->name
);
}
static int debug_read_stat(char *buf, int max)
{
char *msg;
int i = 0;
msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
i += scnprintf(buf + i, max - i,
"smsm: ARM9 HAS CRASHED\n");
i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
raw_smsm_get_state(SMSM_STATE_MODEM),
raw_smsm_get_state(SMSM_STATE_APPS));
#ifdef CONFIG_ARCH_MSM_SCORPION
i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
"qdsp6: %08x power: %08x time: %08x\n",
raw_smsm_get_state(SMSM_STATE_APPS_DEM),
raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
#endif
if (msg) {
msg[SZ_DIAG_ERR_MSG - 1] = 0;
i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
}
return i;
}
static int debug_read_mem(char *buf, int max)
{
unsigned n;
struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
struct smem_heap_entry *toc = shared->heap_toc;
int i = 0;
i += scnprintf(buf + i, max - i,
"heap: init=%d free=%d remain=%d\n",
shared->heap_info.initialized,
shared->heap_info.free_offset,
shared->heap_info.heap_remaining);
for (n = 0; n < SMEM_NUM_ITEMS; n++) {
if (toc[n].allocated == 0)
continue;
i += scnprintf(buf + i, max - i,
"%04d: offset %08x size %08x\n",
n, toc[n].offset, toc[n].size);
}
return i;
}
static int debug_read_ch(char *buf, int max)
{
struct smd_channel *ch;
unsigned long flags;
int i = 0;
spin_lock_irqsave(&smd_lock, flags);
list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
i += dump_ch(buf + i, max - i, ch);
list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
i += dump_ch(buf + i, max - i, ch);
list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
i += dump_ch(buf + i, max - i, ch);
spin_unlock_irqrestore(&smd_lock, flags);
return i;
}
static int debug_read_version(char *buf, int max)
{
struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
unsigned version = shared->version[VERSION_MODEM];
return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
}
static int debug_read_build_id(char *buf, int max)
{
unsigned size;
void *data;
data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
if (!data)
return 0;
if (size >= max)
size = max;
memcpy(buf, data, size);
return size;
}
static int debug_read_alloc_tbl(char *buf, int max)
{
struct smd_alloc_elm *shared;
int n, i = 0;
shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
for (n = 0; n < 64; n++) {
if (shared[n].ref_count == 0)
continue;
i += scnprintf(buf + i, max - i,
"%03d: %-20s cid=%02d type=%03d "
"kind=%02d ref_count=%d\n",
n, shared[n].name, shared[n].cid,
shared[n].ctype & 0xff,
(shared[n].ctype >> 8) & 0xf,
shared[n].ref_count);
}
return i;
}
#define DEBUG_BUFMAX 4096
static char debug_buffer[DEBUG_BUFMAX];
static ssize_t debug_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
int (*fill)(char *buf, int max) = file->private_data;
int bsize = fill(debug_buffer, DEBUG_BUFMAX);
return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
}
static const struct file_operations debug_ops = {
.read = debug_read,
.open = simple_open,
.llseek = default_llseek,
};
static void debug_create(const char *name, umode_t mode,
struct dentry *dent,
int (*fill)(char *buf, int max))
{
debugfs_create_file(name, mode, dent, fill, &debug_ops);
}
int __init smd_debugfs_init(void)
{
struct dentry *dent;
dent = debugfs_create_dir("smd", 0);
if (IS_ERR(dent))
return 1;
debug_create("ch", 0444, dent, debug_read_ch);
debug_create("stat", 0444, dent, debug_read_stat);
debug_create("mem", 0444, dent, debug_read_mem);
debug_create("version", 0444, dent, debug_read_version);
debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
debug_create("build", 0444, dent, debug_read_build_id);
return 0;
}
#endif
#define MAX_NUM_SLEEP_CLIENTS 64
#define MAX_SLEEP_NAME_LEN 8
#define NUM_GPIO_INT_REGISTERS 6
#define GPIO_SMEM_NUM_GROUPS 2
#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
struct tramp_gpio_save {
unsigned int enable;
unsigned int detect;
unsigned int polarity;
};
struct tramp_gpio_smem {
uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
uint32_t enabled[NUM_GPIO_INT_REGISTERS];
uint32_t detection[NUM_GPIO_INT_REGISTERS];
uint32_t polarity[NUM_GPIO_INT_REGISTERS];
};
void smsm_print_sleep_info(void)
{
unsigned long flags;
uint32_t *ptr;
#ifndef CONFIG_ARCH_MSM_SCORPION
struct tramp_gpio_smem *gpio;
struct smsm_interrupt_info *int_info;
#endif
spin_lock_irqsave(&smem_lock, flags);
ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
if (ptr)
pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
if (ptr)
pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
if (ptr)
pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
#ifndef CONFIG_ARCH_MSM_SCORPION
int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
if (int_info)
pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
int_info->interrupt_mask,
int_info->pending_interrupts,
int_info->wakeup_reason);
gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
if (gpio) {
int i;
for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
i, gpio->enabled[i], gpio->detection[i],
gpio->polarity[i]);
for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
i, gpio->num_fired[i], gpio->fired[i][0],
gpio->fired[i][1]);
}
#else
#endif
spin_unlock_irqrestore(&smem_lock, flags);
}
/* arch/arm/mach-msm/smd_private.h
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/io.h>
#include <mach/msm_iomap.h>
struct smem_heap_info {
unsigned initialized;
unsigned free_offset;
unsigned heap_remaining;
unsigned reserved;
};
struct smem_heap_entry {
unsigned allocated;
unsigned offset;
unsigned size;
unsigned reserved;
};
struct smem_proc_comm {
unsigned command;
unsigned status;
unsigned data1;
unsigned data2;
};
#define PC_APPS 0
#define PC_MODEM 1
#define VERSION_SMD 0
#define VERSION_QDSP6 4
#define VERSION_APPS_SBL 6
#define VERSION_MODEM_SBL 7
#define VERSION_APPS 8
#define VERSION_MODEM 9
struct smem_shared {
struct smem_proc_comm proc_comm[4];
unsigned version[32];
struct smem_heap_info heap_info;
struct smem_heap_entry heap_toc[512];
};
#define SMSM_V1_SIZE (sizeof(unsigned) * 8)
#define SMSM_V2_SIZE (sizeof(unsigned) * 4)
#ifdef CONFIG_MSM_SMD_PKG3
struct smsm_interrupt_info {
uint32_t interrupt_mask;
uint32_t pending_interrupts;
uint32_t wakeup_reason;
};
#else
#define DEM_MAX_PORT_NAME_LEN (20)
struct msm_dem_slave_data {
uint32_t sleep_time;
uint32_t interrupt_mask;
uint32_t resources_used;
uint32_t reserved1;
uint32_t wakeup_reason;
uint32_t pending_interrupts;
uint32_t rpc_prog;
uint32_t rpc_proc;
char smd_port_name[DEM_MAX_PORT_NAME_LEN];
uint32_t reserved2;
};
#endif
#define SZ_DIAG_ERR_MSG 0xC8
#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
#define SMSM_INIT 0x00000001
#define SMSM_SMDINIT 0x00000008
#define SMSM_RPCINIT 0x00000020
#define SMSM_RESET 0x00000040
#define SMSM_RSA 0x00000080
#define SMSM_RUN 0x00000100
#define SMSM_PWRC 0x00000200
#define SMSM_TIMEWAIT 0x00000400
#define SMSM_TIMEINIT 0x00000800
#define SMSM_PWRC_EARLY_EXIT 0x00001000
#define SMSM_WFPI 0x00002000
#define SMSM_SLEEP 0x00004000
#define SMSM_SLEEPEXIT 0x00008000
#define SMSM_APPS_REBOOT 0x00020000
#define SMSM_SYSTEM_POWER_DOWN 0x00040000
#define SMSM_SYSTEM_REBOOT 0x00080000
#define SMSM_SYSTEM_DOWNLOAD 0x00100000
#define SMSM_PWRC_SUSPEND 0x00200000
#define SMSM_APPS_SHUTDOWN 0x00400000
#define SMSM_SMD_LOOPBACK 0x00800000
#define SMSM_RUN_QUIET 0x01000000
#define SMSM_MODEM_WAIT 0x02000000
#define SMSM_MODEM_BREAK 0x04000000
#define SMSM_MODEM_CONTINUE 0x08000000
#define SMSM_UNKNOWN 0x80000000
#define SMSM_WKUP_REASON_RPC 0x00000001
#define SMSM_WKUP_REASON_INT 0x00000002
#define SMSM_WKUP_REASON_GPIO 0x00000004
#define SMSM_WKUP_REASON_TIMER 0x00000008
#define SMSM_WKUP_REASON_ALARM 0x00000010
#define SMSM_WKUP_REASON_RESET 0x00000020
#ifdef CONFIG_ARCH_MSM7X00A
enum smsm_state_item {
SMSM_STATE_APPS = 1,
SMSM_STATE_MODEM = 3,
SMSM_STATE_COUNT,
};
#else
enum smsm_state_item {
SMSM_STATE_APPS,
SMSM_STATE_MODEM,
SMSM_STATE_HEXAGON,
SMSM_STATE_APPS_DEM,
SMSM_STATE_MODEM_DEM,
SMSM_STATE_QDSP6_DEM,
SMSM_STATE_POWER_MASTER_DEM,
SMSM_STATE_TIME_MASTER_DEM,
SMSM_STATE_COUNT,
};
#endif
void *smem_alloc(unsigned id, unsigned size);
int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
uint32_t smsm_get_state(enum smsm_state_item item);
int smsm_set_sleep_duration(uint32_t delay);
void smsm_print_sleep_info(void);
#define SMEM_NUM_SMD_CHANNELS 64
typedef enum {
/* fixed items */
SMEM_PROC_COMM = 0,
SMEM_HEAP_INFO,
SMEM_ALLOCATION_TABLE,
SMEM_VERSION_INFO,
SMEM_HW_RESET_DETECT,
SMEM_AARM_WARM_BOOT,
SMEM_DIAG_ERR_MESSAGE,
SMEM_SPINLOCK_ARRAY,
SMEM_MEMORY_BARRIER_LOCATION,
/* dynamic items */
SMEM_AARM_PARTITION_TABLE,
SMEM_AARM_BAD_BLOCK_TABLE,
SMEM_RESERVE_BAD_BLOCKS,
SMEM_WM_UUID,
SMEM_CHANNEL_ALLOC_TBL,
SMEM_SMD_BASE_ID,
SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
SMEM_SMEM_LOG_EVENTS,
SMEM_SMEM_STATIC_LOG_IDX,
SMEM_SMEM_STATIC_LOG_EVENTS,
SMEM_SMEM_SLOW_CLOCK_SYNC,
SMEM_SMEM_SLOW_CLOCK_VALUE,
SMEM_BIO_LED_BUF,
SMEM_SMSM_SHARED_STATE,
SMEM_SMSM_INT_INFO,
SMEM_SMSM_SLEEP_DELAY,
SMEM_SMSM_LIMIT_SLEEP,
SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
SMEM_KEYPAD_KEYS_PRESSED,
SMEM_KEYPAD_STATE_UPDATED,
SMEM_KEYPAD_STATE_IDX,
SMEM_GPIO_INT,
SMEM_MDDI_LCD_IDX,
SMEM_MDDI_HOST_DRIVER_STATE,
SMEM_MDDI_LCD_DISP_STATE,
SMEM_LCD_CUR_PANEL,
SMEM_MARM_BOOT_SEGMENT_INFO,
SMEM_AARM_BOOT_SEGMENT_INFO,
SMEM_SLEEP_STATIC,
SMEM_SCORPION_FREQUENCY,
SMEM_SMD_PROFILES,
SMEM_TSSC_BUSY,
SMEM_HS_SUSPEND_FILTER_INFO,
SMEM_BATT_INFO,
SMEM_APPS_BOOT_MODE,
SMEM_VERSION_FIRST,
SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
SMEM_OSS_RRCASN1_BUF1,
SMEM_OSS_RRCASN1_BUF2,
SMEM_ID_VENDOR0,
SMEM_ID_VENDOR1,
SMEM_ID_VENDOR2,
SMEM_HW_SW_BUILD_ID,
SMEM_SMD_BLOCK_PORT_BASE_ID,
SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS,
SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS,
SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS,
SMEM_SCLK_CONVERSION,
SMEM_SMD_SMSM_INTR_MUX,
SMEM_SMSM_CPU_INTR_MASK,
SMEM_APPS_DEM_SLAVE_DATA,
SMEM_QDSP6_DEM_SLAVE_DATA,
SMEM_CLKREGIM_BSP,
SMEM_CLKREGIM_SOURCES,
SMEM_SMD_FIFO_BASE_ID,
SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS,
SMEM_POWER_ON_STATUS_INFO,
SMEM_DAL_AREA,
SMEM_SMEM_LOG_POWER_IDX,
SMEM_SMEM_LOG_POWER_WRAP,
SMEM_SMEM_LOG_POWER_EVENTS,
SMEM_ERR_CRASH_LOG,
SMEM_ERR_F3_TRACE_LOG,
SMEM_NUM_ITEMS,
} smem_mem_type;
#define SMD_SS_CLOSED 0x00000000
#define SMD_SS_OPENING 0x00000001
#define SMD_SS_OPENED 0x00000002
#define SMD_SS_FLUSHING 0x00000003
#define SMD_SS_CLOSING 0x00000004
#define SMD_SS_RESET 0x00000005
#define SMD_SS_RESET_OPENING 0x00000006
#define SMD_BUF_SIZE 8192
#define SMD_CHANNELS 64
#define SMD_HEADER_SIZE 20
struct smd_alloc_elm {
char name[20];
uint32_t cid;
uint32_t ctype;
uint32_t ref_count;
};
struct smd_half_channel {
unsigned state;
unsigned char fDSR;
unsigned char fCTS;
unsigned char fCD;
unsigned char fRI;
unsigned char fHEAD;
unsigned char fTAIL;
unsigned char fSTATE;
unsigned char fUNUSED;
unsigned tail;
unsigned head;
} __attribute__(( aligned(4), packed ));
/* Only used on SMD package v3 on msm7201a */
struct smd_shared_v1 {
struct smd_half_channel ch0;
unsigned char data0[SMD_BUF_SIZE];
struct smd_half_channel ch1;
unsigned char data1[SMD_BUF_SIZE];
};
/* Used on SMD package v4 */
struct smd_shared_v2 {
struct smd_half_channel ch0;
struct smd_half_channel ch1;
};
struct smd_channel {
volatile struct smd_half_channel *send;
volatile struct smd_half_channel *recv;
unsigned char *send_data;
unsigned char *recv_data;
unsigned fifo_mask;
unsigned fifo_size;
unsigned current_packet;
unsigned n;
struct list_head ch_list;
void *priv;
void (*notify)(void *priv, unsigned flags);
int (*read)(struct smd_channel *ch, void *data, int len);
int (*write)(struct smd_channel *ch, const void *data, int len);
int (*read_avail)(struct smd_channel *ch);
int (*write_avail)(struct smd_channel *ch);
void (*update_state)(struct smd_channel *ch);
unsigned last_state;
void (*notify_other_cpu)(void);
unsigned type;
char name[32];
struct platform_device pdev;
};
#define SMD_TYPE_MASK 0x0FF
#define SMD_TYPE_APPS_MODEM 0x000
#define SMD_TYPE_APPS_DSP 0x001
#define SMD_TYPE_MODEM_DSP 0x002
#define SMD_KIND_MASK 0xF00
#define SMD_KIND_UNKNOWN 0x000
#define SMD_KIND_STREAM 0x100
#define SMD_KIND_PACKET 0x200
extern struct list_head smd_ch_closed_list;
extern struct list_head smd_ch_list_modem;
extern struct list_head smd_ch_list_dsp;
extern spinlock_t smd_lock;
extern spinlock_t smem_lock;
void *smem_find(unsigned id, unsigned size);
void *smem_item(unsigned id, unsigned *size);
uint32_t raw_smsm_get_state(enum smsm_state_item item);
extern void msm_init_last_radio_log(struct module *);
#ifdef CONFIG_MSM_SMD_PKG3
/*
* This allocator assumes an SMD Package v3 which only exists on
* MSM7x00 SoC's.
*/
static inline int _smd_alloc_channel(struct smd_channel *ch)
{
struct smd_shared_v1 *shared1;
shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
if (!shared1) {
pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
return -1;
}
ch->send = &shared1->ch0;
ch->recv = &shared1->ch1;
ch->send_data = shared1->data0;
ch->recv_data = shared1->data1;
ch->fifo_size = SMD_BUF_SIZE;
return 0;
}
#else
/*
* This allocator assumes an SMD Package v4, the most common
* and the default.
*/
static inline int _smd_alloc_channel(struct smd_channel *ch)
{
struct smd_shared_v2 *shared2;
void *buffer;
unsigned buffer_sz;
shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
if (!buffer)
return -1;
/* buffer must be a power-of-two size */
if (buffer_sz & (buffer_sz - 1))
return -1;
buffer_sz /= 2;
ch->send = &shared2->ch0;
ch->recv = &shared2->ch1;
ch->send_data = buffer;
ch->recv_data = buffer + buffer_sz;
ch->fifo_size = buffer_sz;
return 0;
}
#endif /* CONFIG_MSM_SMD_PKG3 */
#if defined(CONFIG_ARCH_MSM7X30)
static inline void msm_a2m_int(uint32_t irq)
{
writel(1 << irq, MSM_GCC_BASE + 0x8);
}
#else
static inline void msm_a2m_int(uint32_t irq)
{
writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
}
#endif /* CONFIG_ARCH_MSM7X30 */
#endif
/* arch/arm/mach-msm/vreg.c
*
* Copyright (C) 2008 Google, Inc.
* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/string.h>
#include <mach/vreg.h>
#include "proc_comm.h"
struct vreg {
const char *name;
unsigned id;
int status;
unsigned refcnt;
};
#define VREG(_name, _id, _status, _refcnt) \
{ .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
static struct vreg vregs[] = {
VREG("msma", 0, 0, 0),
VREG("msmp", 1, 0, 0),
VREG("msme1", 2, 0, 0),
VREG("msmc1", 3, 0, 0),
VREG("msmc2", 4, 0, 0),
VREG("gp3", 5, 0, 0),
VREG("msme2", 6, 0, 0),
VREG("gp4", 7, 0, 0),
VREG("gp1", 8, 0, 0),
VREG("tcxo", 9, 0, 0),
VREG("pa", 10, 0, 0),
VREG("rftx", 11, 0, 0),
VREG("rfrx1", 12, 0, 0),
VREG("rfrx2", 13, 0, 0),
VREG("synt", 14, 0, 0),
VREG("wlan", 15, 0, 0),
VREG("usb", 16, 0, 0),
VREG("boost", 17, 0, 0),
VREG("mmc", 18, 0, 0),
VREG("ruim", 19, 0, 0),
VREG("msmc0", 20, 0, 0),
VREG("gp2", 21, 0, 0),
VREG("gp5", 22, 0, 0),
VREG("gp6", 23, 0, 0),
VREG("rf", 24, 0, 0),
VREG("rf_vco", 26, 0, 0),
VREG("mpll", 27, 0, 0),
VREG("s2", 28, 0, 0),
VREG("s3", 29, 0, 0),
VREG("rfubm", 30, 0, 0),
VREG("ncp", 31, 0, 0),
VREG("gp7", 32, 0, 0),
VREG("gp8", 33, 0, 0),
VREG("gp9", 34, 0, 0),
VREG("gp10", 35, 0, 0),
VREG("gp11", 36, 0, 0),
VREG("gp12", 37, 0, 0),
VREG("gp13", 38, 0, 0),
VREG("gp14", 39, 0, 0),
VREG("gp15", 40, 0, 0),
VREG("gp16", 41, 0, 0),
VREG("gp17", 42, 0, 0),
VREG("s4", 43, 0, 0),
VREG("usb2", 44, 0, 0),
VREG("wlan2", 45, 0, 0),
VREG("xo_out", 46, 0, 0),
VREG("lvsw0", 47, 0, 0),
VREG("lvsw1", 48, 0, 0),
};
struct vreg *vreg_get(struct device *dev, const char *id)
{
int n;
for (n = 0; n < ARRAY_SIZE(vregs); n++) {
if (!strcmp(vregs[n].name, id))
return vregs + n;
}
return ERR_PTR(-ENOENT);
}
void vreg_put(struct vreg *vreg)
{
}
int vreg_enable(struct vreg *vreg)
{
unsigned id = vreg->id;
unsigned enable = 1;
if (vreg->refcnt == 0)
vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
vreg->refcnt++;
return vreg->status;
}
int vreg_disable(struct vreg *vreg)
{
unsigned id = vreg->id;
unsigned enable = 0;
if (!vreg->refcnt)
return 0;
if (vreg->refcnt == 1)
vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
if (!vreg->status)
vreg->refcnt--;
return vreg->status;
}
int vreg_set_level(struct vreg *vreg, unsigned mv)
{
unsigned id = vreg->id;
vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
return vreg->status;
}
#if defined(CONFIG_DEBUG_FS)
static int vreg_debug_set(void *data, u64 val)
{
struct vreg *vreg = data;
switch (val) {
case 0:
vreg_disable(vreg);
break;
case 1:
vreg_enable(vreg);
break;
default:
vreg_set_level(vreg, val);
break;
}
return 0;
}
static int vreg_debug_get(void *data, u64 *val)
{
struct vreg *vreg = data;
if (!vreg->status)
*val = 0;
else
*val = 1;
return 0;
}
static int vreg_debug_count_set(void *data, u64 val)
{
struct vreg *vreg = data;
if (val > UINT_MAX)
val = UINT_MAX;
vreg->refcnt = val;
return 0;
}
static int vreg_debug_count_get(void *data, u64 *val)
{
struct vreg *vreg = data;
*val = vreg->refcnt;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
vreg_debug_count_set, "%llu\n");
static int __init vreg_debug_init(void)
{
struct dentry *dent;
int n;
char name[32];
const char *refcnt_name = "_refcnt";
dent = debugfs_create_dir("vreg", 0);
if (IS_ERR(dent))
return 0;
for (n = 0; n < ARRAY_SIZE(vregs); n++) {
(void) debugfs_create_file(vregs[n].name, 0644,
dent, vregs + n, &vreg_fops);
strlcpy(name, vregs[n].name, sizeof(name));
strlcat(name, refcnt_name, sizeof(name));
(void) debugfs_create_file(name, 0644,
dent, vregs + n, &vreg_count_fops);
}
return 0;
}
device_initcall(vreg_debug_init);
#endif
...@@ -184,7 +184,7 @@ static void __init mvebu_dt_init(void) ...@@ -184,7 +184,7 @@ static void __init mvebu_dt_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
static const char * const armada_370_xp_dt_compat[] = { static const char * const armada_370_xp_dt_compat[] __initconst = {
"marvell,armada-370-xp", "marvell,armada-370-xp",
NULL, NULL,
}; };
...@@ -205,7 +205,7 @@ DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") ...@@ -205,7 +205,7 @@ DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
.dt_compat = armada_370_xp_dt_compat, .dt_compat = armada_370_xp_dt_compat,
MACHINE_END MACHINE_END
static const char * const armada_375_dt_compat[] = { static const char * const armada_375_dt_compat[] __initconst = {
"marvell,armada375", "marvell,armada375",
NULL, NULL,
}; };
...@@ -219,7 +219,7 @@ DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") ...@@ -219,7 +219,7 @@ DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
.dt_compat = armada_375_dt_compat, .dt_compat = armada_375_dt_compat,
MACHINE_END MACHINE_END
static const char * const armada_38x_dt_compat[] = { static const char * const armada_38x_dt_compat[] __initconst = {
"marvell,armada380", "marvell,armada380",
"marvell,armada385", "marvell,armada385",
NULL, NULL,
......
...@@ -27,7 +27,7 @@ static void __init dove_init(void) ...@@ -27,7 +27,7 @@ static void __init dove_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
static const char * const dove_dt_compat[] = { static const char * const dove_dt_compat[] __initconst = {
"marvell,dove", "marvell,dove",
NULL NULL
}; };
......
...@@ -186,7 +186,7 @@ static void __init kirkwood_dt_init(void) ...@@ -186,7 +186,7 @@ static void __init kirkwood_dt_init(void)
of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL); of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
} }
static const char * const kirkwood_dt_board_compat[] = { static const char * const kirkwood_dt_board_compat[] __initconst = {
"marvell,kirkwood", "marvell,kirkwood",
NULL NULL
}; };
......
...@@ -176,12 +176,6 @@ config MACH_OMAP3_BEAGLE ...@@ -176,12 +176,6 @@ config MACH_OMAP3_BEAGLE
default y default y
select OMAP_PACKAGE_CBB select OMAP_PACKAGE_CBB
config MACH_DEVKIT8000
bool "DEVKIT8000 board"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
config MACH_OMAP_LDP config MACH_OMAP_LDP
bool "OMAP3 LDP board" bool "OMAP3 LDP board"
depends on ARCH_OMAP3 depends on ARCH_OMAP3
...@@ -226,12 +220,6 @@ config MACH_OMAP3_PANDORA ...@@ -226,12 +220,6 @@ config MACH_OMAP3_PANDORA
select OMAP_PACKAGE_CBB select OMAP_PACKAGE_CBB
select REGULATOR_FIXED_VOLTAGE if REGULATOR select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_TOUCHBOOK
bool "OMAP3 Touch Book"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
config MACH_NOKIA_N810 config MACH_NOKIA_N810
bool bool
...@@ -261,12 +249,6 @@ config MACH_CM_T35 ...@@ -261,12 +249,6 @@ config MACH_CM_T35
config MACH_CM_T3730 config MACH_CM_T3730
bool bool
config MACH_SBC3530
bool "OMAP3 SBC STALKER board"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
config OMAP3_SDRC_AC_TIMING config OMAP3_SDRC_AC_TIMING
bool "Enable SDRC AC timing register changes" bool "Enable SDRC AC timing register changes"
depends on ARCH_OMAP3 depends on ARCH_OMAP3
......
...@@ -243,7 +243,6 @@ obj-$(CONFIG_SOC_OMAP2420) += msdi.o ...@@ -243,7 +243,6 @@ obj-$(CONFIG_SOC_OMAP2420) += msdi.o
# Specific board support # Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o
obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
...@@ -254,9 +253,6 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o ...@@ -254,9 +253,6 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o
obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
# Platform specific device init code # Platform specific device init code
......
/*
* board-devkit8000.c - TimLL Devkit8000
*
* Copyright (C) 2009 Kim Botherway
* Copyright (C) 2010 Thomas Weber
*
* Modified from mach-omap2/board-omap3beagle.c
*
* Initial code: Syed Mohammed Khasim
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mmc/host.h>
#include <linux/usb/phy.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
#include "id.h"
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include "common.h"
#include "gpmc.h"
#include <linux/platform_data/mtd-nand-omap2.h>
#include <video/omapdss.h>
#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/dm9000.h>
#include <linux/interrupt.h>
#include "sdram-micron-mt46h32m32lf-6.h"
#include "mux.h"
#include "hsmmc.h"
#include "board-flash.h"
#include "common-board-devices.h"
#define NAND_CS 0
#define OMAP_DM9000_GPIO_IRQ 25
#define OMAP3_DEVKIT_TS_GPIO 27
static struct mtd_partition devkit8000_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
.name = "X-Loader",
.offset = 0,
.size = 4 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "U-Boot",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
.size = 15 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "U-Boot Env",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
.size = 1 * NAND_BLOCK_SIZE,
},
{
.name = "Kernel",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
.size = 32 * NAND_BLOCK_SIZE,
},
{
.name = "File System",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
.size = MTDPART_SIZ_FULL,
},
};
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
.deferred = true,
},
{} /* Terminator */
};
static struct regulator_consumer_supply devkit8000_vmmc1_supply[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
/* ads7846 on SPI */
static struct regulator_consumer_supply devkit8000_vio_supply[] = {
REGULATOR_SUPPLY("vcc", "spi2.0"),
};
static const struct display_timing devkit8000_lcd_videomode = {
.pixelclock = { 0, 40000000, 0 },
.hactive = { 0, 800, 0 },
.hfront_porch = { 0, 1, 0 },
.hback_porch = { 0, 1, 0 },
.hsync_len = { 0, 48, 0 },
.vactive = { 0, 480, 0 },
.vfront_porch = { 0, 12, 0 },
.vback_porch = { 0, 25, 0 },
.vsync_len = { 0, 3, 0 },
.flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
};
static struct panel_dpi_platform_data devkit8000_lcd_pdata = {
.name = "lcd",
.source = "dpi.0",
.data_lines = 24,
.display_timing = &devkit8000_lcd_videomode,
.enable_gpio = -1, /* filled in code */
.backlight_gpio = -1,
};
static struct platform_device devkit8000_lcd_device = {
.name = "panel-dpi",
.id = 0,
.dev.platform_data = &devkit8000_lcd_pdata,
};
static struct connector_dvi_platform_data devkit8000_dvi_connector_pdata = {
.name = "dvi",
.source = "tfp410.0",
.i2c_bus_num = 1,
};
static struct platform_device devkit8000_dvi_connector_device = {
.name = "connector-dvi",
.id = 0,
.dev.platform_data = &devkit8000_dvi_connector_pdata,
};
static struct encoder_tfp410_platform_data devkit8000_tfp410_pdata = {
.name = "tfp410.0",
.source = "dpi.0",
.data_lines = 24,
.power_down_gpio = -1, /* filled in code */
};
static struct platform_device devkit8000_tfp410_device = {
.name = "tfp410",
.id = 0,
.dev.platform_data = &devkit8000_tfp410_pdata,
};
static struct connector_atv_platform_data devkit8000_tv_pdata = {
.name = "tv",
.source = "venc.0",
.connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
.invert_polarity = false,
};
static struct platform_device devkit8000_tv_connector_device = {
.name = "connector-analog-tv",
.id = 0,
.dev.platform_data = &devkit8000_tv_pdata,
};
static struct omap_dss_board_info devkit8000_dss_data = {
.default_display_name = "lcd",
};
static uint32_t board_keymap[] = {
KEY(0, 0, KEY_1),
KEY(1, 0, KEY_2),
KEY(2, 0, KEY_3),
KEY(0, 1, KEY_4),
KEY(1, 1, KEY_5),
KEY(2, 1, KEY_6),
KEY(3, 1, KEY_F5),
KEY(0, 2, KEY_7),
KEY(1, 2, KEY_8),
KEY(2, 2, KEY_9),
KEY(3, 2, KEY_F6),
KEY(0, 3, KEY_F7),
KEY(1, 3, KEY_0),
KEY(2, 3, KEY_F8),
PERSISTENT_KEY(4, 5),
KEY(4, 4, KEY_VOLUMEUP),
KEY(5, 5, KEY_VOLUMEDOWN),
0
};
static struct matrix_keymap_data board_map_data = {
.keymap = board_keymap,
.keymap_size = ARRAY_SIZE(board_keymap),
};
static struct twl4030_keypad_data devkit8000_kp_data = {
.keymap_data = &board_map_data,
.rows = 6,
.cols = 6,
.rep = 1,
};
static struct gpio_led gpio_leds[];
static int devkit8000_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
omap_hsmmc_late_init(mmc);
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
/* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
devkit8000_lcd_pdata.enable_gpio = gpio + TWL4030_GPIO_MAX + 0;
/* gpio + 7 is "DVI_PD" (out, active low) */
devkit8000_tfp410_pdata.power_down_gpio = gpio + 7;
return 0;
}
static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
.use_leds = true,
.pulldowns = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
| BIT(15) | BIT(16) | BIT(17),
.setup = devkit8000_twl_gpio_setup,
};
static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
};
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data devkit8000_vmmc1 = {
.constraints = {
.min_uV = 1850000,
.max_uV = 3150000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(devkit8000_vmmc1_supply),
.consumer_supplies = devkit8000_vmmc1_supply,
};
/* VPLL1 for digital video outputs */
static struct regulator_init_data devkit8000_vpll1 = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
.consumer_supplies = devkit8000_vpll1_supplies,
};
/* VAUX4 for ads7846 and nubs */
static struct regulator_init_data devkit8000_vio = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(devkit8000_vio_supply),
.consumer_supplies = devkit8000_vio_supply,
};
static struct twl4030_platform_data devkit8000_twldata = {
/* platform_data for children goes here */
.gpio = &devkit8000_gpio_data,
.vmmc1 = &devkit8000_vmmc1,
.vpll1 = &devkit8000_vpll1,
.vio = &devkit8000_vio,
.keypad = &devkit8000_kp_data,
};
static int __init devkit8000_i2c_init(void)
{
omap3_pmic_get_config(&devkit8000_twldata,
TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
TWL_COMMON_REGULATOR_VDAC);
omap3_pmic_init("tps65930", &devkit8000_twldata);
/* Bus 3 is attached to the DVI port where devices like the pico DLP
* projector don't work reliably with 400kHz */
omap_register_i2c_bus(3, 400, NULL, 0);
return 0;
}
static struct gpio_led gpio_leds[] = {
{
.name = "led1",
.default_trigger = "heartbeat",
.gpio = 186,
.active_low = true,
},
{
.name = "led2",
.default_trigger = "mmc0",
.gpio = 163,
.active_low = true,
},
{
.name = "ledB",
.default_trigger = "none",
.gpio = 153,
.active_low = true,
},
{
.name = "led3",
.default_trigger = "none",
.gpio = 164,
.active_low = true,
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device leds_gpio = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
},
};
static struct gpio_keys_button gpio_buttons[] = {
{
.code = BTN_EXTRA,
.gpio = 26,
.desc = "user",
.wakeup = 1,
},
};
static struct gpio_keys_platform_data gpio_key_info = {
.buttons = gpio_buttons,
.nbuttons = ARRAY_SIZE(gpio_buttons),
};
static struct platform_device keys_gpio = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &gpio_key_info,
},
};
#define OMAP_DM9000_BASE 0x2c000000
static struct resource omap_dm9000_resources[] = {
[0] = {
.start = OMAP_DM9000_BASE,
.end = (OMAP_DM9000_BASE + 0x4 - 1),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = (OMAP_DM9000_BASE + 0x400),
.end = (OMAP_DM9000_BASE + 0x400 + 0x4 - 1),
.flags = IORESOURCE_MEM,
},
[2] = {
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct dm9000_plat_data omap_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device omap_dm9000_dev = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(omap_dm9000_resources),
.resource = omap_dm9000_resources,
.dev = {
.platform_data = &omap_dm9000_platdata,
},
};
static void __init omap_dm9000_init(void)
{
unsigned char *eth_addr = omap_dm9000_platdata.dev_addr;
struct omap_die_id odi;
int ret;
ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq");
if (ret < 0) {
printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
OMAP_DM9000_GPIO_IRQ);
return;
}
/* init the mac address using DIE id */
omap_get_die_id(&odi);
eth_addr[0] = 0x02; /* locally administered */
eth_addr[1] = odi.id_1 & 0xff;
eth_addr[2] = (odi.id_0 & 0xff000000) >> 24;
eth_addr[3] = (odi.id_0 & 0x00ff0000) >> 16;
eth_addr[4] = (odi.id_0 & 0x0000ff00) >> 8;
eth_addr[5] = (odi.id_0 & 0x000000ff);
}
static struct platform_device *devkit8000_devices[] __initdata = {
&leds_gpio,
&keys_gpio,
&omap_dm9000_dev,
&devkit8000_lcd_device,
&devkit8000_tfp410_device,
&devkit8000_dvi_connector_device,
&devkit8000_tv_connector_device,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
};
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* nCS and IRQ for Devkit8000 ethernet */
OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE0),
OMAP3_MUX(ETK_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
/* McSPI 2*/
OMAP3_MUX(MCSPI2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCSPI2_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(MCSPI2_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCSPI2_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(MCSPI2_CS1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
/* PENDOWN GPIO */
OMAP3_MUX(ETK_D13, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
/* mUSB */
OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* USB 1 */
OMAP3_MUX(ETK_CTL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
OMAP3_MUX(ETK_D8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D9, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D5, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D6, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP3_MUX(ETK_D7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
/* MMC 1 */
OMAP3_MUX(SDMMC1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(SDMMC1_DAT7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* McBSP 2 */
OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
/* I2C 1 */
OMAP3_MUX(I2C1_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(I2C1_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* I2C 2 */
OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* I2C 3 */
OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* I2C 4 */
OMAP3_MUX(I2C4_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(I2C4_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* serial ports */
OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* DSS */
OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
/* expansion port */
/* McSPI 1 */
OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
OMAP3_MUX(MCSPI1_CS3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
/* HDQ */
OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
/* McSPI4 */
OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
/* MMC 2 */
OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
/* I2C3 */
OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
/* TPS IRQ */
OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
OMAP_PIN_INPUT_PULLUP),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#endif
static void __init devkit8000_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_dm9000_init();
omap_hsmmc_init(mmc);
devkit8000_i2c_init();
omap_dm9000_resources[2].start = gpio_to_irq(OMAP_DM9000_GPIO_IRQ);
platform_add_devices(devkit8000_devices,
ARRAY_SIZE(devkit8000_devices));
omap_display_init(&devkit8000_dss_data);
omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
usbhs_init(&usbhs_bdata);
board_nand_init(devkit8000_nand_partitions,
ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
NAND_BUSWIDTH_16, NULL);
omap_twl4030_audio_init("omap3beagle", NULL);
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
.init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = devkit8000_init,
.init_late = omap35xx_init_late,
.init_time = omap3_secure_sync32k_timer_init,
.restart = omap3xxx_restart,
MACHINE_END
/*
* linux/arch/arm/mach-omap2/board-omap3evm.c
*
* Copyright (C) 2008 Guangzhou EMA-Tech
*
* Modified from mach-omap2/board-omap3evm.c
*
* Initial code: Syed Mohammed Khasim
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
#include <linux/mmc/host.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/smsc911x.h>
#include <linux/platform_data/at24.h>
#include <linux/usb/phy.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include "common.h"
#include "gpmc.h"
#include <linux/platform_data/mtd-nand-omap2.h>
#include <video/omapdss.h>
#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include "sdram-micron-mt46h32m32lf-6.h"
#include "mux.h"
#include "hsmmc.h"
#include "common-board-devices.h"
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
#include "gpmc-smsc911x.h"
#define OMAP3STALKER_ETHR_START 0x2c000000
#define OMAP3STALKER_ETHR_SIZE 1024
#define OMAP3STALKER_ETHR_GPIO_IRQ 19
#define OMAP3STALKER_SMC911X_CS 5
static struct omap_smsc911x_platform_data smsc911x_cfg = {
.cs = OMAP3STALKER_SMC911X_CS,
.gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ,
.gpio_reset = -EINVAL,
.flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
};
static inline void __init omap3stalker_init_eth(void)
{
omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
gpmc_smsc911x_init(&smsc911x_cfg);
}
#else
static inline void __init omap3stalker_init_eth(void)
{
return;
}
#endif
/*
* OMAP3 DSS control signals
*/
#define DSS_ENABLE_GPIO 199
#define LCD_PANEL_BKLIGHT_GPIO 210
#define ENABLE_VPLL2_DEV_GRP 0xE0
static void __init omap3_stalker_display_init(void)
{
return;
}
static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = {
.name = "dvi",
.source = "tfp410.0",
.i2c_bus_num = -1,
};
static struct platform_device omap3stalker_dvi_connector_device = {
.name = "connector-dvi",
.id = 0,
.dev.platform_data = &omap3stalker_dvi_connector_pdata,
};
static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = {
.name = "tfp410.0",
.source = "dpi.0",
.data_lines = 24,
.power_down_gpio = DSS_ENABLE_GPIO,
};
static struct platform_device omap3stalker_tfp410_device = {
.name = "tfp410",
.id = 0,
.dev.platform_data = &omap3stalker_tfp410_pdata,
};
static struct connector_atv_platform_data omap3stalker_tv_pdata = {
.name = "tv",
.source = "venc.0",
.connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE,
.invert_polarity = false,
};
static struct platform_device omap3stalker_tv_connector_device = {
.name = "connector-analog-tv",
.id = 0,
.dev.platform_data = &omap3stalker_tv_pdata,
};
static struct omap_dss_board_info omap3_stalker_dss_data = {
.default_display_name = "dvi",
};
static struct regulator_consumer_supply omap3stalker_vmmc1_supply[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
static struct regulator_consumer_supply omap3stalker_vsim_supply[] = {
REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
};
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data omap3stalker_vmmc1 = {
.constraints = {
.min_uV = 1850000,
.max_uV = 3150000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(omap3stalker_vmmc1_supply),
.consumer_supplies = omap3stalker_vmmc1_supply,
};
/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
static struct regulator_init_data omap3stalker_vsim = {
.constraints = {
.min_uV = 1800000,
.max_uV = 3000000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(omap3stalker_vsim_supply),
.consumer_supplies = omap3stalker_vsim_supply,
};
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
.caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 23,
.deferred = true,
},
{} /* Terminator */
};
static struct gpio_keys_button gpio_buttons[] = {
{
.code = BTN_EXTRA,
.gpio = 18,
.desc = "user",
.wakeup = 1,
},
};
static struct gpio_keys_platform_data gpio_key_info = {
.buttons = gpio_buttons,
.nbuttons = ARRAY_SIZE(gpio_buttons),
};
static struct platform_device keys_gpio = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &gpio_key_info,
},
};
static struct gpio_led gpio_leds[] = {
{
.name = "stalker:D8:usr0",
.default_trigger = "default-on",
.gpio = 126,
},
{
.name = "stalker:D9:usr1",
.default_trigger = "default-on",
.gpio = 127,
},
{
.name = "stalker:D3:mmc0",
.gpio = -EINVAL, /* gets replaced */
.active_low = true,
.default_trigger = "mmc0",
},
{
.name = "stalker:D4:heartbeat",
.gpio = -EINVAL, /* gets replaced */
.active_low = true,
.default_trigger = "heartbeat",
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device leds_gpio = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
},
};
static int
omap3stalker_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
omap_hsmmc_late_init(mmc);
/*
* Most GPIOs are for USB OTG. Some are mostly sent to
* the P2 connector; notably LEDA for the LCD backlight.
*/
/* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
"EN_LCD_BKL");
/* gpio + 7 == DVI Enable */
gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
/* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
/* GPIO + 13 == ledsync (out, heartbeat) */
gpio_leds[3].gpio = gpio + 13;
platform_device_register(&leds_gpio);
return 0;
}
static struct twl4030_gpio_platform_data omap3stalker_gpio_data = {
.use_leds = true,
.setup = omap3stalker_twl_gpio_setup,
};
static uint32_t board_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_DOWN),
KEY(0, 2, KEY_ENTER),
KEY(0, 3, KEY_M),
KEY(1, 0, KEY_RIGHT),
KEY(1, 1, KEY_UP),
KEY(1, 2, KEY_I),
KEY(1, 3, KEY_N),
KEY(2, 0, KEY_A),
KEY(2, 1, KEY_E),
KEY(2, 2, KEY_J),
KEY(2, 3, KEY_O),
KEY(3, 0, KEY_B),
KEY(3, 1, KEY_F),
KEY(3, 2, KEY_K),
KEY(3, 3, KEY_P)
};
static struct matrix_keymap_data board_map_data = {
.keymap = board_keymap,
.keymap_size = ARRAY_SIZE(board_keymap),
};
static struct twl4030_keypad_data omap3stalker_kp_data = {
.keymap_data = &board_map_data,
.rows = 4,
.cols = 4,
.rep = 1,
};
static struct twl4030_platform_data omap3stalker_twldata = {
/* platform_data for children goes here */
.keypad = &omap3stalker_kp_data,
.gpio = &omap3stalker_gpio_data,
.vmmc1 = &omap3stalker_vmmc1,
.vsim = &omap3stalker_vsim,
};
static struct at24_platform_data fram_info = {
.byte_len = (64 * 1024) / 8,
.page_size = 8192,
.flags = AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO,
};
static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = {
{
I2C_BOARD_INFO("24c64", 0x50),
.flags = I2C_CLIENT_WAKE,
.platform_data = &fram_info,
},
};
static int __init omap3_stalker_i2c_init(void)
{
omap3_pmic_get_config(&omap3stalker_twldata,
TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
TWL_COMMON_PDATA_AUDIO,
TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
omap3stalker_twldata.vdac->constraints.apply_uV = true;
omap3stalker_twldata.vpll2->constraints.apply_uV = true;
omap3stalker_twldata.vpll2->constraints.name = "VDVI";
omap3_pmic_init("twl4030", &omap3stalker_twldata);
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3,
ARRAY_SIZE(omap3stalker_i2c_boardinfo3));
return 0;
}
#define OMAP3_STALKER_TS_GPIO 175
static struct usbhs_phy_data phy_data[] __initdata = {
{
.port = 2,
.reset_gpio = 21,
.vcc_gpio = -EINVAL,
},
};
static struct platform_device *omap3_stalker_devices[] __initdata = {
&keys_gpio,
&omap3stalker_tfp410_device,
&omap3stalker_dvi_connector_device,
&omap3stalker_tv_connector_device,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
};
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
{.reg_offset = OMAP_MUX_TERMINATOR},
};
#endif
static struct regulator_consumer_supply dummy_supplies[] = {
REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
};
static void __init omap3_stalker_init(void)
{
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
omap_mux_init_gpio(23, OMAP_PIN_INPUT);
omap_hsmmc_init(mmc);
omap3_stalker_i2c_init();
platform_add_devices(omap3_stalker_devices,
ARRAY_SIZE(omap3_stalker_devices));
omap_display_init(&omap3_stalker_dss_data);
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
omap_mux_init_gpio(21, OMAP_PIN_OUTPUT);
omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
omap3stalker_init_eth();
omap3_stalker_display_init();
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
}
MACHINE_START(SBC3530, "OMAP3 STALKER")
/* Maintainer: Jason Lam -lzg@ema-tech.com */
.atag_offset = 0x100,
.map_io = omap3_map_io,
.init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3_stalker_init,
.init_late = omap35xx_init_late,
.init_time = omap3_secure_sync32k_timer_init,
.restart = omap3xxx_restart,
MACHINE_END
/*
* linux/arch/arm/mach-omap2/board-omap3touchbook.c
*
* Copyright (C) 2009 Always Innovating
*
* Modified from mach-omap2/board-omap3beagleboard.c
*
* Initial code: Grégoire Gentil, Tim Yamin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mmc/host.h>
#include <linux/usb/phy.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/system_info.h>
#include "common.h"
#include "gpmc.h"
#include <linux/platform_data/mtd-nand-omap2.h>
#include "mux.h"
#include "hsmmc.h"
#include "board-flash.h"
#include "common-board-devices.h"
#include <asm/setup.h>
#define OMAP3_AC_GPIO 136
#define OMAP3_TS_GPIO 162
#define TB_BL_PWM_TIMER 9
#define TB_KILL_POWER_GPIO 168
#define NAND_CS 0
static unsigned long touchbook_revision;
static struct mtd_partition omap3touchbook_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
.name = "X-Loader",
.offset = 0,
.size = 4 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "U-Boot",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
.size = 15 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "U-Boot Env",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
.size = 1 * NAND_BLOCK_SIZE,
},
{
.name = "Kernel",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
.size = 32 * NAND_BLOCK_SIZE,
},
{
.name = "File System",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
.size = MTDPART_SIZ_FULL,
},
};
#include "sdram-micron-mt46h32m32lf-6.h"
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
.deferred = true,
},
{} /* Terminator */
};
static struct regulator_consumer_supply touchbook_vmmc1_supply[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
static struct regulator_consumer_supply touchbook_vsim_supply[] = {
REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
};
static struct gpio_led gpio_leds[];
static int touchbook_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
omap_hsmmc_late_init(mmc);
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC");
/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
"nEN_USB_PWR");
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
return 0;
}
static struct twl4030_gpio_platform_data touchbook_gpio_data = {
.use_leds = true,
.pullups = BIT(1),
.pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
| BIT(15) | BIT(16) | BIT(17),
.setup = touchbook_twl_gpio_setup,
};
static struct regulator_consumer_supply touchbook_vdac_supply[] = {
{
.supply = "vdac",
},
};
static struct regulator_consumer_supply touchbook_vdvi_supply[] = {
{
.supply = "vdvi",
},
};
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data touchbook_vmmc1 = {
.constraints = {
.min_uV = 1850000,
.max_uV = 3150000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(touchbook_vmmc1_supply),
.consumer_supplies = touchbook_vmmc1_supply,
};
/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
static struct regulator_init_data touchbook_vsim = {
.constraints = {
.min_uV = 1800000,
.max_uV = 3000000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(touchbook_vsim_supply),
.consumer_supplies = touchbook_vsim_supply,
};
static struct twl4030_platform_data touchbook_twldata = {
/* platform_data for children goes here */
.gpio = &touchbook_gpio_data,
.vmmc1 = &touchbook_vmmc1,
.vsim = &touchbook_vsim,
};
static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
{
I2C_BOARD_INFO("bq27200", 0x55),
},
};
static int __init omap3_touchbook_i2c_init(void)
{
/* Standard TouchBook bus */
omap3_pmic_get_config(&touchbook_twldata,
TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
touchbook_twldata.vdac->num_consumer_supplies =
ARRAY_SIZE(touchbook_vdac_supply);
touchbook_twldata.vdac->consumer_supplies = touchbook_vdac_supply;
touchbook_twldata.vpll2->constraints.name = "VDVI";
touchbook_twldata.vpll2->num_consumer_supplies =
ARRAY_SIZE(touchbook_vdvi_supply);
touchbook_twldata.vpll2->consumer_supplies = touchbook_vdvi_supply;
omap3_pmic_init("twl4030", &touchbook_twldata);
/* Additional TouchBook bus */
omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
ARRAY_SIZE(touchBook_i2c_boardinfo));
return 0;
}
static struct ads7846_platform_data ads7846_pdata = {
.x_min = 100,
.y_min = 265,
.x_max = 3950,
.y_max = 3750,
.x_plate_ohms = 40,
.pressure_max = 255,
.debounce_max = 10,
.debounce_tol = 5,
.debounce_rep = 1,
.gpio_pendown = OMAP3_TS_GPIO,
.keep_vref_on = 1,
};
static struct gpio_led gpio_leds[] = {
{
.name = "touchbook::usr0",
.default_trigger = "heartbeat",
.gpio = 150,
},
{
.name = "touchbook::usr1",
.default_trigger = "mmc0",
.gpio = 149,
},
{
.name = "touchbook::pmu_stat",
.gpio = -EINVAL, /* gets replaced */
.active_low = true,
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device leds_gpio = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
},
};
static struct gpio_keys_button gpio_buttons[] = {
{
.code = BTN_EXTRA,
.gpio = 7,
.desc = "user",
.wakeup = 1,
},
{
.code = KEY_POWER,
.gpio = 183,
.desc = "power",
.wakeup = 1,
},
};
static struct gpio_keys_platform_data gpio_key_info = {
.buttons = gpio_buttons,
.nbuttons = ARRAY_SIZE(gpio_buttons),
};
static struct platform_device keys_gpio = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &gpio_key_info,
},
};
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#endif
static struct usbhs_phy_data phy_data[] __initdata = {
{
.port = 2,
.reset_gpio = 147,
.vcc_gpio = -EINVAL,
},
};
static struct platform_device *omap3_touchbook_devices[] __initdata = {
&leds_gpio,
&keys_gpio,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
};
static void omap3_touchbook_poweroff(void)
{
int pwr_off = TB_KILL_POWER_GPIO;
if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0)
printk(KERN_ERR "Unable to get kill power GPIO\n");
}
static int __init early_touchbook_revision(char *p)
{
if (!p)
return 0;
return kstrtoul(p, 10, &touchbook_revision);
}
early_param("tbr", early_touchbook_revision);
static void __init omap3_touchbook_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
pm_power_off = omap3_touchbook_poweroff;
if (system_rev >= 0x20 && system_rev <= 0x34301000) {
omap_mux_init_gpio(23, OMAP_PIN_INPUT);
mmc[0].gpio_wp = 23;
} else {
omap_mux_init_gpio(29, OMAP_PIN_INPUT);
}
omap_hsmmc_init(mmc);
omap3_touchbook_i2c_init();
platform_add_devices(omap3_touchbook_devices,
ARRAY_SIZE(omap3_touchbook_devices));
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
/* REVISIT leave DVI powered down until it's needed ... */
gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
/* Touchscreen and accelerometer */
omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
board_nand_init(omap3touchbook_nand_partitions,
ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
NAND_BUSWIDTH_16, NULL);
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
/* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
.init_early = omap3430_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3_touchbook_init,
.init_late = omap3430_init_late,
.init_time = omap3_secure_sync32k_timer_init,
.restart = omap3xxx_restart,
MACHINE_END
...@@ -12,8 +12,8 @@ obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o ...@@ -12,8 +12,8 @@ obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o
obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o pm-r8a7740.o obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o pm-r8a7740.o
obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o pm-r8a7790.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o pm-r8a7791.o obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
...@@ -46,10 +46,10 @@ smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o ...@@ -46,10 +46,10 @@ smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
# PM objects # PM objects
obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_PM_RCAR) += pm-rcar.o obj-$(CONFIG_PM_RCAR) += pm-rcar.o
obj-$(CONFIG_PM_RMOBILE) += pm-rmobile.o obj-$(CONFIG_PM_RMOBILE) += pm-rmobile.o
obj-$(CONFIG_ARCH_RCAR_GEN2) += pm-rcar-gen2.o
# special sh7372 handling for IRQ objects and low level sleep code # special sh7372 handling for IRQ objects and low level sleep code
obj-$(CONFIG_ARCH_SH7372) += entry-intc.o sleep-sh7372.o obj-$(CONFIG_ARCH_SH7372) += entry-intc.o sleep-sh7372.o
......
...@@ -23,8 +23,6 @@ struct clk; ...@@ -23,8 +23,6 @@ struct clk;
extern int shmobile_clk_init(void); extern int shmobile_clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *); extern void shmobile_handle_irq_intc(struct pt_regs *);
extern struct platform_suspend_ops shmobile_suspend_ops; extern struct platform_suspend_ops shmobile_suspend_ops;
struct cpuidle_driver;
extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv);
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
int shmobile_suspend_init(void); int shmobile_suspend_init(void);
...@@ -34,12 +32,6 @@ static inline int shmobile_suspend_init(void) { return 0; } ...@@ -34,12 +32,6 @@ static inline int shmobile_suspend_init(void) { return 0; }
static inline void shmobile_smp_apmu_suspend_init(void) { } static inline void shmobile_smp_apmu_suspend_init(void) { }
#endif #endif
#ifdef CONFIG_CPU_IDLE
int shmobile_cpuidle_init(void);
#else
static inline int shmobile_cpuidle_init(void) { return 0; }
#endif
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
int shmobile_cpufreq_init(void); int shmobile_cpufreq_init(void);
#else #else
...@@ -51,7 +43,6 @@ extern void __iomem *shmobile_scu_base; ...@@ -51,7 +43,6 @@ extern void __iomem *shmobile_scu_base;
static inline void __init shmobile_init_late(void) static inline void __init shmobile_init_late(void)
{ {
shmobile_suspend_init(); shmobile_suspend_init();
shmobile_cpuidle_init();
shmobile_cpufreq_init(); shmobile_cpufreq_init();
} }
......
/*
* CPUIdle support code for SH-Mobile ARM
*
* Copyright (C) 2011 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/pm.h>
#include <linux/cpuidle.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/err.h>
#include <asm/cpuidle.h>
#include <asm/io.h>
static struct cpuidle_driver shmobile_cpuidle_default_driver = {
.name = "shmobile_cpuidle",
.owner = THIS_MODULE,
.states[0] = ARM_CPUIDLE_WFI_STATE,
.safe_state_index = 0, /* C1 */
.state_count = 1,
};
static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver;
void __init shmobile_cpuidle_set_driver(struct cpuidle_driver *drv)
{
cpuidle_drv = drv;
}
int __init shmobile_cpuidle_init(void)
{
return cpuidle_register(cpuidle_drv, NULL);
}
/*
* r8a7790 Power management support
*
* Copyright (C) 2013 Renesas Electronics Corporation
* Copyright (C) 2011 Renesas Solutions Corp.
* Copyright (C) 2011 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/smp.h>
#include <asm/io.h>
#include "common.h"
#include "pm-rcar.h"
#include "r8a7790.h"
/* RST */
#define RST 0xe6160000
#define CA15BAR 0x0020
#define CA7BAR 0x0030
#define CA15RESCNT 0x0040
#define CA7RESCNT 0x0044
/* On-chip RAM */
#define MERAM 0xe8080000
/* SYSC */
#define SYSCIER 0x0c
#define SYSCIMR 0x10
#if defined(CONFIG_SMP)
static void __init r8a7790_sysc_init(void)
{
void __iomem *base = rcar_sysc_init(0xe6180000);
/* enable all interrupt sources, but do not use interrupt handler */
iowrite32(0x0131000e, base + SYSCIER);
iowrite32(0, base + SYSCIMR);
}
#else /* CONFIG_SMP */
static inline void r8a7790_sysc_init(void) {}
#endif /* CONFIG_SMP */
void __init r8a7790_pm_init(void)
{
void __iomem *p;
u32 bar;
static int once;
if (once++)
return;
/* MERAM for jump stub, because BAR requires 256KB aligned address */
p = ioremap_nocache(MERAM, shmobile_boot_size);
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
iounmap(p);
/* setup reset vectors */
p = ioremap_nocache(RST, 0x63);
bar = (MERAM >> 8) & 0xfffffc00;
writel_relaxed(bar, p + CA15BAR);
writel_relaxed(bar, p + CA7BAR);
writel_relaxed(bar | 0x10, p + CA15BAR);
writel_relaxed(bar | 0x10, p + CA7BAR);
/* de-assert reset for all CPUs */
writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000,
p + CA15RESCNT);
writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000,
p + CA7RESCNT);
iounmap(p);
r8a7790_sysc_init();
shmobile_smp_apmu_suspend_init();
}
/* /*
* r8a7791 Power management support * R-Car Generation 2 Power management support
* *
* Copyright (C) 2014 Renesas Electronics Corporation * Copyright (C) 2013 - 2015 Renesas Electronics Corporation
* Copyright (C) 2011 Renesas Solutions Corp. * Copyright (C) 2011 Renesas Solutions Corp.
* Copyright (C) 2011 Magnus Damm * Copyright (C) 2011 Magnus Damm
* *
...@@ -11,15 +11,22 @@ ...@@ -11,15 +11,22 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/of.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/io.h> #include <asm/io.h>
#include "common.h" #include "common.h"
#include "pm-rcar.h" #include "pm-rcar.h"
#include "r8a7791.h" #include "rcar-gen2.h"
/* RST */
#define RST 0xe6160000 #define RST 0xe6160000
#define CA15BAR 0x0020 #define CA15BAR 0x0020
#define CA7BAR 0x0030
#define CA15RESCNT 0x0040 #define CA15RESCNT 0x0040
#define CA7RESCNT 0x0044
/* On-chip RAM */
#define MERAM 0xe8080000
#define RAM 0xe6300000 #define RAM 0xe6300000
/* SYSC */ /* SYSC */
...@@ -28,46 +35,81 @@ ...@@ -28,46 +35,81 @@
#if defined(CONFIG_SMP) #if defined(CONFIG_SMP)
static void __init r8a7791_sysc_init(void) static void __init rcar_gen2_sysc_init(u32 syscier)
{ {
void __iomem *base = rcar_sysc_init(0xe6180000); void __iomem *base = rcar_sysc_init(0xe6180000);
/* enable all interrupt sources, but do not use interrupt handler */ /* enable all interrupt sources, but do not use interrupt handler */
iowrite32(0x0131000e, base + SYSCIER); iowrite32(syscier, base + SYSCIER);
iowrite32(0, base + SYSCIMR); iowrite32(0, base + SYSCIMR);
} }
#else /* CONFIG_SMP */ #else /* CONFIG_SMP */
static inline void r8a7791_sysc_init(void) {} static inline void rcar_gen2_sysc_init(u32 syscier) {}
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
void __init r8a7791_pm_init(void) void __init rcar_gen2_pm_init(void)
{ {
void __iomem *p; void __iomem *p;
u32 bar; u32 bar;
static int once; static int once;
struct device_node *np, *cpus;
bool has_a7 = false;
bool has_a15 = false;
phys_addr_t boot_vector_addr = 0;
u32 syscier = 0;
if (once++) if (once++)
return; return;
cpus = of_find_node_by_path("/cpus");
if (!cpus)
return;
for_each_child_of_node(cpus, np) {
if (of_device_is_compatible(np, "arm,cortex-a15"))
has_a15 = true;
else if (of_device_is_compatible(np, "arm,cortex-a7"))
has_a7 = true;
}
if (of_machine_is_compatible("renesas,r8a7790")) {
boot_vector_addr = MERAM;
syscier = 0x013111ef;
} else if (of_machine_is_compatible("renesas,r8a7791")) {
boot_vector_addr = RAM;
syscier = 0x00111003;
}
/* RAM for jump stub, because BAR requires 256KB aligned address */ /* RAM for jump stub, because BAR requires 256KB aligned address */
p = ioremap_nocache(RAM, shmobile_boot_size); p = ioremap_nocache(boot_vector_addr, shmobile_boot_size);
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
iounmap(p); iounmap(p);
/* setup reset vectors */ /* setup reset vectors */
p = ioremap_nocache(RST, 0x63); p = ioremap_nocache(RST, 0x63);
bar = (RAM >> 8) & 0xfffffc00; bar = (boot_vector_addr >> 8) & 0xfffffc00;
writel_relaxed(bar, p + CA15BAR); if (has_a15) {
writel_relaxed(bar | 0x10, p + CA15BAR); writel_relaxed(bar, p + CA15BAR);
writel_relaxed(bar | 0x10, p + CA15BAR);
/* de-assert reset for CA15 CPUs */
writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) |
0xa5a50000, p + CA15RESCNT);
}
if (has_a7) {
writel_relaxed(bar, p + CA7BAR);
writel_relaxed(bar | 0x10, p + CA7BAR);
/* enable clocks to all CPUs */ /* de-assert reset for CA7 CPUs */
writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) |
p + CA15RESCNT); 0x5a5a0000, p + CA7RESCNT);
}
iounmap(p); iounmap(p);
r8a7791_sysc_init(); rcar_gen2_sysc_init(syscier);
shmobile_smp_apmu_suspend_init(); shmobile_smp_apmu_suspend_init();
} }
...@@ -462,7 +462,7 @@ static struct cpuidle_driver sh7372_cpuidle_driver = { ...@@ -462,7 +462,7 @@ static struct cpuidle_driver sh7372_cpuidle_driver = {
static void __init sh7372_cpuidle_init(void) static void __init sh7372_cpuidle_init(void)
{ {
shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver); return cpuidle_register(cpuidle_drv, NULL);
} }
#else #else
static void __init sh7372_cpuidle_init(void) {} static void __init sh7372_cpuidle_init(void) {}
......
#ifndef __ASM_R8A7790_H__ #ifndef __ASM_R8A7790_H__
#define __ASM_R8A7790_H__ #define __ASM_R8A7790_H__
void r8a7790_pm_init(void);
extern struct smp_operations r8a7790_smp_ops; extern struct smp_operations r8a7790_smp_ops;
#endif /* __ASM_R8A7790_H__ */ #endif /* __ASM_R8A7790_H__ */
#ifndef __ASM_R8A7791_H__ #ifndef __ASM_R8A7791_H__
#define __ASM_R8A7791_H__ #define __ASM_R8A7791_H__
void r8a7791_pm_init(void);
extern struct smp_operations r8a7791_smp_ops; extern struct smp_operations r8a7791_smp_ops;
#endif /* __ASM_R8A7791_H__ */ #endif /* __ASM_R8A7791_H__ */
...@@ -5,5 +5,6 @@ void rcar_gen2_timer_init(void); ...@@ -5,5 +5,6 @@ void rcar_gen2_timer_init(void);
#define MD(nr) BIT(nr) #define MD(nr) BIT(nr)
u32 rcar_gen2_read_mode_pins(void); u32 rcar_gen2_read_mode_pins(void);
void rcar_gen2_reserve(void); void rcar_gen2_reserve(void);
void rcar_gen2_pm_init(void);
#endif /* __ASM_RCAR_GEN2_H__ */ #endif /* __ASM_RCAR_GEN2_H__ */
...@@ -842,13 +842,6 @@ static void __init r8a7740_generic_init(void) ...@@ -842,13 +842,6 @@ static void __init r8a7740_generic_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
#define RESCNT2 IOMEM(0xe6188020)
static void r8a7740_restart(enum reboot_mode mode, const char *cmd)
{
/* Do soft power on reset */
writel(1 << 31, RESCNT2);
}
static const char *r8a7740_boards_compat_dt[] __initdata = { static const char *r8a7740_boards_compat_dt[] __initdata = {
"renesas,r8a7740", "renesas,r8a7740",
NULL, NULL,
...@@ -861,7 +854,6 @@ DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") ...@@ -861,7 +854,6 @@ DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
.init_machine = r8a7740_generic_init, .init_machine = r8a7740_generic_init,
.init_late = shmobile_init_late, .init_late = shmobile_init_late,
.dt_compat = r8a7740_boards_compat_dt, .dt_compat = r8a7740_boards_compat_dt,
.restart = r8a7740_restart,
MACHINE_END MACHINE_END
#endif /* CONFIG_USE_OF */ #endif /* CONFIG_USE_OF */
...@@ -50,9 +50,7 @@ u32 rcar_gen2_read_mode_pins(void) ...@@ -50,9 +50,7 @@ u32 rcar_gen2_read_mode_pins(void)
void __init rcar_gen2_timer_init(void) void __init rcar_gen2_timer_init(void)
{ {
#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
u32 mode = rcar_gen2_read_mode_pins(); u32 mode = rcar_gen2_read_mode_pins();
#endif
#ifdef CONFIG_ARM_ARCH_TIMER #ifdef CONFIG_ARM_ARCH_TIMER
void __iomem *base; void __iomem *base;
int extal_mhz = 0; int extal_mhz = 0;
...@@ -128,9 +126,7 @@ void __init rcar_gen2_timer_init(void) ...@@ -128,9 +126,7 @@ void __init rcar_gen2_timer_init(void)
iounmap(base); iounmap(base);
#endif /* CONFIG_ARM_ARCH_TIMER */ #endif /* CONFIG_ARM_ARCH_TIMER */
#ifdef CONFIG_COMMON_CLK
rcar_gen2_clocks_init(mode); rcar_gen2_clocks_init(mode);
#endif
#ifdef CONFIG_ARCH_SHMOBILE_MULTI #ifdef CONFIG_ARCH_SHMOBILE_MULTI
clocksource_of_init(); clocksource_of_init();
#endif #endif
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "common.h" #include "common.h"
#include "platsmp-apmu.h" #include "platsmp-apmu.h"
#include "pm-rcar.h" #include "pm-rcar.h"
#include "rcar-gen2.h"
#include "r8a7790.h" #include "r8a7790.h"
static struct rcar_sysc_ch r8a7790_ca15_scu = { static struct rcar_sysc_ch r8a7790_ca15_scu = {
...@@ -54,7 +55,7 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) ...@@ -54,7 +55,7 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
ARRAY_SIZE(r8a7790_apmu_config)); ARRAY_SIZE(r8a7790_apmu_config));
/* turn on power to SCU */ /* turn on power to SCU */
r8a7790_pm_init(); rcar_gen2_pm_init();
rcar_sysc_power_up(&r8a7790_ca15_scu); rcar_sysc_power_up(&r8a7790_ca15_scu);
rcar_sysc_power_up(&r8a7790_ca7_scu); rcar_sysc_power_up(&r8a7790_ca7_scu);
} }
......
...@@ -39,7 +39,7 @@ static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) ...@@ -39,7 +39,7 @@ static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
r8a7791_apmu_config, r8a7791_apmu_config,
ARRAY_SIZE(r8a7791_apmu_config)); ARRAY_SIZE(r8a7791_apmu_config));
r8a7791_pm_init(); rcar_gen2_pm_init();
} }
static int r8a7791_smp_boot_secondary(unsigned int cpu, static int r8a7791_smp_boot_secondary(unsigned int cpu,
......
...@@ -272,14 +272,6 @@ config GPIO_MPC8XXX ...@@ -272,14 +272,6 @@ config GPIO_MPC8XXX
Say Y here if you're going to use hardware that connects to the Say Y here if you're going to use hardware that connects to the
MPC512x/831x/834x/837x/8572/8610 GPIOs. MPC512x/831x/834x/837x/8572/8610 GPIOs.
config GPIO_MSM_V1
tristate "Qualcomm MSM GPIO v1"
depends on GPIOLIB && ARCH_MSM && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50)
help
Say yes here to support the GPIO interface on ARM v6 based
Qualcomm MSM chips. Most of the pins on the MSM can be
selected for GPIO, and are controlled by this driver.
config GPIO_MSM_V2 config GPIO_MSM_V2
tristate "Qualcomm MSM GPIO v2" tristate "Qualcomm MSM GPIO v2"
depends on GPIOLIB && OF && ARCH_QCOM depends on GPIOLIB && OF && ARCH_QCOM
......
...@@ -60,7 +60,6 @@ obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o ...@@ -60,7 +60,6 @@ obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
......
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <mach/msm_gpiomux.h>
/* see 80-VA736-2 Rev C pp 695-751
**
** These are actually the *shadow* gpio registers, since the
** real ones (which allow full access) are only available to the
** ARM9 side of the world.
**
** Since the _BASE need to be page-aligned when we're mapping them
** to virtual addresses, adjust for the additional offset in these
** macros.
*/
#define MSM_GPIO1_REG(off) (off)
#define MSM_GPIO2_REG(off) (off)
#define MSM_GPIO1_SHADOW_REG(off) (off)
#define MSM_GPIO2_SHADOW_REG(off) (off)
/*
* MSM7X00 registers
*/
/* output value */
#define MSM7X00_GPIO_OUT_0 MSM_GPIO1_SHADOW_REG(0x00) /* gpio 15-0 */
#define MSM7X00_GPIO_OUT_1 MSM_GPIO2_SHADOW_REG(0x00) /* gpio 42-16 */
#define MSM7X00_GPIO_OUT_2 MSM_GPIO1_SHADOW_REG(0x04) /* gpio 67-43 */
#define MSM7X00_GPIO_OUT_3 MSM_GPIO1_SHADOW_REG(0x08) /* gpio 94-68 */
#define MSM7X00_GPIO_OUT_4 MSM_GPIO1_SHADOW_REG(0x0C) /* gpio 106-95 */
#define MSM7X00_GPIO_OUT_5 MSM_GPIO1_SHADOW_REG(0x50) /* gpio 107-121 */
/* same pin map as above, output enable */
#define MSM7X00_GPIO_OE_0 MSM_GPIO1_SHADOW_REG(0x10)
#define MSM7X00_GPIO_OE_1 MSM_GPIO2_SHADOW_REG(0x08)
#define MSM7X00_GPIO_OE_2 MSM_GPIO1_SHADOW_REG(0x14)
#define MSM7X00_GPIO_OE_3 MSM_GPIO1_SHADOW_REG(0x18)
#define MSM7X00_GPIO_OE_4 MSM_GPIO1_SHADOW_REG(0x1C)
#define MSM7X00_GPIO_OE_5 MSM_GPIO1_SHADOW_REG(0x54)
/* same pin map as above, input read */
#define MSM7X00_GPIO_IN_0 MSM_GPIO1_SHADOW_REG(0x34)
#define MSM7X00_GPIO_IN_1 MSM_GPIO2_SHADOW_REG(0x20)
#define MSM7X00_GPIO_IN_2 MSM_GPIO1_SHADOW_REG(0x38)
#define MSM7X00_GPIO_IN_3 MSM_GPIO1_SHADOW_REG(0x3C)
#define MSM7X00_GPIO_IN_4 MSM_GPIO1_SHADOW_REG(0x40)
#define MSM7X00_GPIO_IN_5 MSM_GPIO1_SHADOW_REG(0x44)
/* same pin map as above, 1=edge 0=level interrup */
#define MSM7X00_GPIO_INT_EDGE_0 MSM_GPIO1_SHADOW_REG(0x60)
#define MSM7X00_GPIO_INT_EDGE_1 MSM_GPIO2_SHADOW_REG(0x50)
#define MSM7X00_GPIO_INT_EDGE_2 MSM_GPIO1_SHADOW_REG(0x64)
#define MSM7X00_GPIO_INT_EDGE_3 MSM_GPIO1_SHADOW_REG(0x68)
#define MSM7X00_GPIO_INT_EDGE_4 MSM_GPIO1_SHADOW_REG(0x6C)
#define MSM7X00_GPIO_INT_EDGE_5 MSM_GPIO1_SHADOW_REG(0xC0)
/* same pin map as above, 1=positive 0=negative */
#define MSM7X00_GPIO_INT_POS_0 MSM_GPIO1_SHADOW_REG(0x70)
#define MSM7X00_GPIO_INT_POS_1 MSM_GPIO2_SHADOW_REG(0x58)
#define MSM7X00_GPIO_INT_POS_2 MSM_GPIO1_SHADOW_REG(0x74)
#define MSM7X00_GPIO_INT_POS_3 MSM_GPIO1_SHADOW_REG(0x78)
#define MSM7X00_GPIO_INT_POS_4 MSM_GPIO1_SHADOW_REG(0x7C)
#define MSM7X00_GPIO_INT_POS_5 MSM_GPIO1_SHADOW_REG(0xBC)
/* same pin map as above, interrupt enable */
#define MSM7X00_GPIO_INT_EN_0 MSM_GPIO1_SHADOW_REG(0x80)
#define MSM7X00_GPIO_INT_EN_1 MSM_GPIO2_SHADOW_REG(0x60)
#define MSM7X00_GPIO_INT_EN_2 MSM_GPIO1_SHADOW_REG(0x84)
#define MSM7X00_GPIO_INT_EN_3 MSM_GPIO1_SHADOW_REG(0x88)
#define MSM7X00_GPIO_INT_EN_4 MSM_GPIO1_SHADOW_REG(0x8C)
#define MSM7X00_GPIO_INT_EN_5 MSM_GPIO1_SHADOW_REG(0xB8)
/* same pin map as above, write 1 to clear interrupt */
#define MSM7X00_GPIO_INT_CLEAR_0 MSM_GPIO1_SHADOW_REG(0x90)
#define MSM7X00_GPIO_INT_CLEAR_1 MSM_GPIO2_SHADOW_REG(0x68)
#define MSM7X00_GPIO_INT_CLEAR_2 MSM_GPIO1_SHADOW_REG(0x94)
#define MSM7X00_GPIO_INT_CLEAR_3 MSM_GPIO1_SHADOW_REG(0x98)
#define MSM7X00_GPIO_INT_CLEAR_4 MSM_GPIO1_SHADOW_REG(0x9C)
#define MSM7X00_GPIO_INT_CLEAR_5 MSM_GPIO1_SHADOW_REG(0xB4)
/* same pin map as above, 1=interrupt pending */
#define MSM7X00_GPIO_INT_STATUS_0 MSM_GPIO1_SHADOW_REG(0xA0)
#define MSM7X00_GPIO_INT_STATUS_1 MSM_GPIO2_SHADOW_REG(0x70)
#define MSM7X00_GPIO_INT_STATUS_2 MSM_GPIO1_SHADOW_REG(0xA4)
#define MSM7X00_GPIO_INT_STATUS_3 MSM_GPIO1_SHADOW_REG(0xA8)
#define MSM7X00_GPIO_INT_STATUS_4 MSM_GPIO1_SHADOW_REG(0xAC)
#define MSM7X00_GPIO_INT_STATUS_5 MSM_GPIO1_SHADOW_REG(0xB0)
/*
* QSD8X50 registers
*/
/* output value */
#define QSD8X50_GPIO_OUT_0 MSM_GPIO1_SHADOW_REG(0x00) /* gpio 15-0 */
#define QSD8X50_GPIO_OUT_1 MSM_GPIO2_SHADOW_REG(0x00) /* gpio 42-16 */
#define QSD8X50_GPIO_OUT_2 MSM_GPIO1_SHADOW_REG(0x04) /* gpio 67-43 */
#define QSD8X50_GPIO_OUT_3 MSM_GPIO1_SHADOW_REG(0x08) /* gpio 94-68 */
#define QSD8X50_GPIO_OUT_4 MSM_GPIO1_SHADOW_REG(0x0C) /* gpio 103-95 */
#define QSD8X50_GPIO_OUT_5 MSM_GPIO1_SHADOW_REG(0x10) /* gpio 121-104 */
#define QSD8X50_GPIO_OUT_6 MSM_GPIO1_SHADOW_REG(0x14) /* gpio 152-122 */
#define QSD8X50_GPIO_OUT_7 MSM_GPIO1_SHADOW_REG(0x18) /* gpio 164-153 */
/* same pin map as above, output enable */
#define QSD8X50_GPIO_OE_0 MSM_GPIO1_SHADOW_REG(0x20)
#define QSD8X50_GPIO_OE_1 MSM_GPIO2_SHADOW_REG(0x08)
#define QSD8X50_GPIO_OE_2 MSM_GPIO1_SHADOW_REG(0x24)
#define QSD8X50_GPIO_OE_3 MSM_GPIO1_SHADOW_REG(0x28)
#define QSD8X50_GPIO_OE_4 MSM_GPIO1_SHADOW_REG(0x2C)
#define QSD8X50_GPIO_OE_5 MSM_GPIO1_SHADOW_REG(0x30)
#define QSD8X50_GPIO_OE_6 MSM_GPIO1_SHADOW_REG(0x34)
#define QSD8X50_GPIO_OE_7 MSM_GPIO1_SHADOW_REG(0x38)
/* same pin map as above, input read */
#define QSD8X50_GPIO_IN_0 MSM_GPIO1_SHADOW_REG(0x50)
#define QSD8X50_GPIO_IN_1 MSM_GPIO2_SHADOW_REG(0x20)
#define QSD8X50_GPIO_IN_2 MSM_GPIO1_SHADOW_REG(0x54)
#define QSD8X50_GPIO_IN_3 MSM_GPIO1_SHADOW_REG(0x58)
#define QSD8X50_GPIO_IN_4 MSM_GPIO1_SHADOW_REG(0x5C)
#define QSD8X50_GPIO_IN_5 MSM_GPIO1_SHADOW_REG(0x60)
#define QSD8X50_GPIO_IN_6 MSM_GPIO1_SHADOW_REG(0x64)
#define QSD8X50_GPIO_IN_7 MSM_GPIO1_SHADOW_REG(0x68)
/* same pin map as above, 1=edge 0=level interrup */
#define QSD8X50_GPIO_INT_EDGE_0 MSM_GPIO1_SHADOW_REG(0x70)
#define QSD8X50_GPIO_INT_EDGE_1 MSM_GPIO2_SHADOW_REG(0x50)
#define QSD8X50_GPIO_INT_EDGE_2 MSM_GPIO1_SHADOW_REG(0x74)
#define QSD8X50_GPIO_INT_EDGE_3 MSM_GPIO1_SHADOW_REG(0x78)
#define QSD8X50_GPIO_INT_EDGE_4 MSM_GPIO1_SHADOW_REG(0x7C)
#define QSD8X50_GPIO_INT_EDGE_5 MSM_GPIO1_SHADOW_REG(0x80)
#define QSD8X50_GPIO_INT_EDGE_6 MSM_GPIO1_SHADOW_REG(0x84)
#define QSD8X50_GPIO_INT_EDGE_7 MSM_GPIO1_SHADOW_REG(0x88)
/* same pin map as above, 1=positive 0=negative */
#define QSD8X50_GPIO_INT_POS_0 MSM_GPIO1_SHADOW_REG(0x90)
#define QSD8X50_GPIO_INT_POS_1 MSM_GPIO2_SHADOW_REG(0x58)
#define QSD8X50_GPIO_INT_POS_2 MSM_GPIO1_SHADOW_REG(0x94)
#define QSD8X50_GPIO_INT_POS_3 MSM_GPIO1_SHADOW_REG(0x98)
#define QSD8X50_GPIO_INT_POS_4 MSM_GPIO1_SHADOW_REG(0x9C)
#define QSD8X50_GPIO_INT_POS_5 MSM_GPIO1_SHADOW_REG(0xA0)
#define QSD8X50_GPIO_INT_POS_6 MSM_GPIO1_SHADOW_REG(0xA4)
#define QSD8X50_GPIO_INT_POS_7 MSM_GPIO1_SHADOW_REG(0xA8)
/* same pin map as above, interrupt enable */
#define QSD8X50_GPIO_INT_EN_0 MSM_GPIO1_SHADOW_REG(0xB0)
#define QSD8X50_GPIO_INT_EN_1 MSM_GPIO2_SHADOW_REG(0x60)
#define QSD8X50_GPIO_INT_EN_2 MSM_GPIO1_SHADOW_REG(0xB4)
#define QSD8X50_GPIO_INT_EN_3 MSM_GPIO1_SHADOW_REG(0xB8)
#define QSD8X50_GPIO_INT_EN_4 MSM_GPIO1_SHADOW_REG(0xBC)
#define QSD8X50_GPIO_INT_EN_5 MSM_GPIO1_SHADOW_REG(0xC0)
#define QSD8X50_GPIO_INT_EN_6 MSM_GPIO1_SHADOW_REG(0xC4)
#define QSD8X50_GPIO_INT_EN_7 MSM_GPIO1_SHADOW_REG(0xC8)
/* same pin map as above, write 1 to clear interrupt */
#define QSD8X50_GPIO_INT_CLEAR_0 MSM_GPIO1_SHADOW_REG(0xD0)
#define QSD8X50_GPIO_INT_CLEAR_1 MSM_GPIO2_SHADOW_REG(0x68)
#define QSD8X50_GPIO_INT_CLEAR_2 MSM_GPIO1_SHADOW_REG(0xD4)
#define QSD8X50_GPIO_INT_CLEAR_3 MSM_GPIO1_SHADOW_REG(0xD8)
#define QSD8X50_GPIO_INT_CLEAR_4 MSM_GPIO1_SHADOW_REG(0xDC)
#define QSD8X50_GPIO_INT_CLEAR_5 MSM_GPIO1_SHADOW_REG(0xE0)
#define QSD8X50_GPIO_INT_CLEAR_6 MSM_GPIO1_SHADOW_REG(0xE4)
#define QSD8X50_GPIO_INT_CLEAR_7 MSM_GPIO1_SHADOW_REG(0xE8)
/* same pin map as above, 1=interrupt pending */
#define QSD8X50_GPIO_INT_STATUS_0 MSM_GPIO1_SHADOW_REG(0xF0)
#define QSD8X50_GPIO_INT_STATUS_1 MSM_GPIO2_SHADOW_REG(0x70)
#define QSD8X50_GPIO_INT_STATUS_2 MSM_GPIO1_SHADOW_REG(0xF4)
#define QSD8X50_GPIO_INT_STATUS_3 MSM_GPIO1_SHADOW_REG(0xF8)
#define QSD8X50_GPIO_INT_STATUS_4 MSM_GPIO1_SHADOW_REG(0xFC)
#define QSD8X50_GPIO_INT_STATUS_5 MSM_GPIO1_SHADOW_REG(0x100)
#define QSD8X50_GPIO_INT_STATUS_6 MSM_GPIO1_SHADOW_REG(0x104)
#define QSD8X50_GPIO_INT_STATUS_7 MSM_GPIO1_SHADOW_REG(0x108)
/*
* MSM7X30 registers
*/
/* output value */
#define MSM7X30_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
#define MSM7X30_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 43-16 */
#define MSM7X30_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-44 */
#define MSM7X30_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
#define MSM7X30_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */
#define MSM7X30_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 133-107 */
#define MSM7X30_GPIO_OUT_6 MSM_GPIO1_REG(0xC4) /* gpio 150-134 */
#define MSM7X30_GPIO_OUT_7 MSM_GPIO1_REG(0x214) /* gpio 181-151 */
/* same pin map as above, output enable */
#define MSM7X30_GPIO_OE_0 MSM_GPIO1_REG(0x10)
#define MSM7X30_GPIO_OE_1 MSM_GPIO2_REG(0x08)
#define MSM7X30_GPIO_OE_2 MSM_GPIO1_REG(0x14)
#define MSM7X30_GPIO_OE_3 MSM_GPIO1_REG(0x18)
#define MSM7X30_GPIO_OE_4 MSM_GPIO1_REG(0x1C)
#define MSM7X30_GPIO_OE_5 MSM_GPIO1_REG(0x54)
#define MSM7X30_GPIO_OE_6 MSM_GPIO1_REG(0xC8)
#define MSM7X30_GPIO_OE_7 MSM_GPIO1_REG(0x218)
/* same pin map as above, input read */
#define MSM7X30_GPIO_IN_0 MSM_GPIO1_REG(0x34)
#define MSM7X30_GPIO_IN_1 MSM_GPIO2_REG(0x20)
#define MSM7X30_GPIO_IN_2 MSM_GPIO1_REG(0x38)
#define MSM7X30_GPIO_IN_3 MSM_GPIO1_REG(0x3C)
#define MSM7X30_GPIO_IN_4 MSM_GPIO1_REG(0x40)
#define MSM7X30_GPIO_IN_5 MSM_GPIO1_REG(0x44)
#define MSM7X30_GPIO_IN_6 MSM_GPIO1_REG(0xCC)
#define MSM7X30_GPIO_IN_7 MSM_GPIO1_REG(0x21C)
/* same pin map as above, 1=edge 0=level interrup */
#define MSM7X30_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60)
#define MSM7X30_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
#define MSM7X30_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64)
#define MSM7X30_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68)
#define MSM7X30_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C)
#define MSM7X30_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0)
#define MSM7X30_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0xD0)
#define MSM7X30_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x240)
/* same pin map as above, 1=positive 0=negative */
#define MSM7X30_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70)
#define MSM7X30_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
#define MSM7X30_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74)
#define MSM7X30_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78)
#define MSM7X30_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C)
#define MSM7X30_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC)
#define MSM7X30_GPIO_INT_POS_6 MSM_GPIO1_REG(0xD4)
#define MSM7X30_GPIO_INT_POS_7 MSM_GPIO1_REG(0x228)
/* same pin map as above, interrupt enable */
#define MSM7X30_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80)
#define MSM7X30_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
#define MSM7X30_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84)
#define MSM7X30_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88)
#define MSM7X30_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C)
#define MSM7X30_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8)
#define MSM7X30_GPIO_INT_EN_6 MSM_GPIO1_REG(0xD8)
#define MSM7X30_GPIO_INT_EN_7 MSM_GPIO1_REG(0x22C)
/* same pin map as above, write 1 to clear interrupt */
#define MSM7X30_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90)
#define MSM7X30_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
#define MSM7X30_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94)
#define MSM7X30_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98)
#define MSM7X30_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C)
#define MSM7X30_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4)
#define MSM7X30_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xDC)
#define MSM7X30_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0x230)
/* same pin map as above, 1=interrupt pending */
#define MSM7X30_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0)
#define MSM7X30_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
#define MSM7X30_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4)
#define MSM7X30_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8)
#define MSM7X30_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC)
#define MSM7X30_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0)
#define MSM7X30_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0xE0)
#define MSM7X30_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x234)
#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
#define MSM_GPIO_BANK(soc, bank, first, last) \
{ \
.regs[MSM_GPIO_OUT] = soc##_GPIO_OUT_##bank, \
.regs[MSM_GPIO_IN] = soc##_GPIO_IN_##bank, \
.regs[MSM_GPIO_INT_STATUS] = soc##_GPIO_INT_STATUS_##bank, \
.regs[MSM_GPIO_INT_CLEAR] = soc##_GPIO_INT_CLEAR_##bank, \
.regs[MSM_GPIO_INT_EN] = soc##_GPIO_INT_EN_##bank, \
.regs[MSM_GPIO_INT_EDGE] = soc##_GPIO_INT_EDGE_##bank, \
.regs[MSM_GPIO_INT_POS] = soc##_GPIO_INT_POS_##bank, \
.regs[MSM_GPIO_OE] = soc##_GPIO_OE_##bank, \
.chip = { \
.base = (first), \
.ngpio = (last) - (first) + 1, \
.get = msm_gpio_get, \
.set = msm_gpio_set, \
.direction_input = msm_gpio_direction_input, \
.direction_output = msm_gpio_direction_output, \
.to_irq = msm_gpio_to_irq, \
.request = msm_gpio_request, \
.free = msm_gpio_free, \
} \
}
#define MSM_GPIO_BROKEN_INT_CLEAR 1
enum msm_gpio_reg {
MSM_GPIO_IN,
MSM_GPIO_OUT,
MSM_GPIO_INT_STATUS,
MSM_GPIO_INT_CLEAR,
MSM_GPIO_INT_EN,
MSM_GPIO_INT_EDGE,
MSM_GPIO_INT_POS,
MSM_GPIO_OE,
MSM_GPIO_REG_NR
};
struct msm_gpio_chip {
spinlock_t lock;
struct gpio_chip chip;
unsigned long regs[MSM_GPIO_REG_NR];
#if MSM_GPIO_BROKEN_INT_CLEAR
unsigned int_status_copy;
#endif
unsigned int both_edge_detect;
unsigned int int_enable[2]; /* 0: awake, 1: sleep */
void __iomem *base;
};
struct msm_gpio_initdata {
struct msm_gpio_chip *chips;
int count;
};
static void msm_gpio_writel(struct msm_gpio_chip *chip, u32 val,
enum msm_gpio_reg reg)
{
writel(val, chip->base + chip->regs[reg]);
}
static u32 msm_gpio_readl(struct msm_gpio_chip *chip, enum msm_gpio_reg reg)
{
return readl(chip->base + chip->regs[reg]);
}
static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
unsigned offset, unsigned on)
{
unsigned mask = BIT(offset);
unsigned val;
val = msm_gpio_readl(msm_chip, MSM_GPIO_OUT);
if (on)
msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_OUT);
else
msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_OUT);
return 0;
}
static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
{
int loop_limit = 100;
unsigned pol, val, val2, intstat;
do {
val = msm_gpio_readl(msm_chip, MSM_GPIO_IN);
pol = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS);
pol = (pol & ~msm_chip->both_edge_detect) |
(~val & msm_chip->both_edge_detect);
msm_gpio_writel(msm_chip, pol, MSM_GPIO_INT_POS);
intstat = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS);
val2 = msm_gpio_readl(msm_chip, MSM_GPIO_IN);
if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
return;
} while (loop_limit-- > 0);
printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
"failed to reach stable state %x != %x\n", val, val2);
}
static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
unsigned offset)
{
unsigned bit = BIT(offset);
#if MSM_GPIO_BROKEN_INT_CLEAR
/* Save interrupts that already triggered before we loose them. */
/* Any interrupt that triggers between the read of int_status */
/* and the write to int_clear will still be lost though. */
msm_chip->int_status_copy |=
msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS);
msm_chip->int_status_copy &= ~bit;
#endif
msm_gpio_writel(msm_chip, bit, MSM_GPIO_INT_CLEAR);
msm_gpio_update_both_edge_detect(msm_chip);
return 0;
}
static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct msm_gpio_chip *msm_chip;
unsigned long irq_flags;
u32 val;
msm_chip = container_of(chip, struct msm_gpio_chip, chip);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) & ~BIT(offset);
msm_gpio_writel(msm_chip, val, MSM_GPIO_OE);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
return 0;
}
static int
msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
struct msm_gpio_chip *msm_chip;
unsigned long irq_flags;
u32 val;
msm_chip = container_of(chip, struct msm_gpio_chip, chip);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
msm_gpio_write(msm_chip, offset, value);
val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) | BIT(offset);
msm_gpio_writel(msm_chip, val, MSM_GPIO_OE);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
return 0;
}
static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct msm_gpio_chip *msm_chip;
msm_chip = container_of(chip, struct msm_gpio_chip, chip);
return (msm_gpio_readl(msm_chip, MSM_GPIO_IN) & (1U << offset)) ? 1 : 0;
}
static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct msm_gpio_chip *msm_chip;
unsigned long irq_flags;
msm_chip = container_of(chip, struct msm_gpio_chip, chip);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
msm_gpio_write(msm_chip, offset, value);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
}
static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
return MSM_GPIO_TO_INT(chip->base + offset);
}
#ifdef CONFIG_MSM_GPIOMUX
static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
{
return msm_gpiomux_get(chip->base + offset);
}
static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
{
msm_gpiomux_put(chip->base + offset);
}
#else
#define msm_gpio_request NULL
#define msm_gpio_free NULL
#endif
static struct msm_gpio_chip *msm_gpio_chips;
static int msm_gpio_count;
static struct msm_gpio_chip msm_gpio_chips_msm7x01[] = {
MSM_GPIO_BANK(MSM7X00, 0, 0, 15),
MSM_GPIO_BANK(MSM7X00, 1, 16, 42),
MSM_GPIO_BANK(MSM7X00, 2, 43, 67),
MSM_GPIO_BANK(MSM7X00, 3, 68, 94),
MSM_GPIO_BANK(MSM7X00, 4, 95, 106),
MSM_GPIO_BANK(MSM7X00, 5, 107, 121),
};
static struct msm_gpio_initdata msm_gpio_7x01_init = {
.chips = msm_gpio_chips_msm7x01,
.count = ARRAY_SIZE(msm_gpio_chips_msm7x01),
};
static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = {
MSM_GPIO_BANK(MSM7X30, 0, 0, 15),
MSM_GPIO_BANK(MSM7X30, 1, 16, 43),
MSM_GPIO_BANK(MSM7X30, 2, 44, 67),
MSM_GPIO_BANK(MSM7X30, 3, 68, 94),
MSM_GPIO_BANK(MSM7X30, 4, 95, 106),
MSM_GPIO_BANK(MSM7X30, 5, 107, 133),
MSM_GPIO_BANK(MSM7X30, 6, 134, 150),
MSM_GPIO_BANK(MSM7X30, 7, 151, 181),
};
static struct msm_gpio_initdata msm_gpio_7x30_init = {
.chips = msm_gpio_chips_msm7x30,
.count = ARRAY_SIZE(msm_gpio_chips_msm7x30),
};
static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = {
MSM_GPIO_BANK(QSD8X50, 0, 0, 15),
MSM_GPIO_BANK(QSD8X50, 1, 16, 42),
MSM_GPIO_BANK(QSD8X50, 2, 43, 67),
MSM_GPIO_BANK(QSD8X50, 3, 68, 94),
MSM_GPIO_BANK(QSD8X50, 4, 95, 103),
MSM_GPIO_BANK(QSD8X50, 5, 104, 121),
MSM_GPIO_BANK(QSD8X50, 6, 122, 152),
MSM_GPIO_BANK(QSD8X50, 7, 153, 164),
};
static struct msm_gpio_initdata msm_gpio_8x50_init = {
.chips = msm_gpio_chips_qsd8x50,
.count = ARRAY_SIZE(msm_gpio_chips_qsd8x50),
};
static void msm_gpio_irq_ack(struct irq_data *d)
{
unsigned long irq_flags;
struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
msm_gpio_clear_detect_status(msm_chip,
d->irq - gpio_to_irq(msm_chip->chip.base));
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
}
static void msm_gpio_irq_mask(struct irq_data *d)
{
unsigned long irq_flags;
struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
/* level triggered interrupts are also latched */
if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset)))
msm_gpio_clear_detect_status(msm_chip, offset);
msm_chip->int_enable[0] &= ~BIT(offset);
msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
}
static void msm_gpio_irq_unmask(struct irq_data *d)
{
unsigned long irq_flags;
struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
/* level triggered interrupts are also latched */
if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset)))
msm_gpio_clear_detect_status(msm_chip, offset);
msm_chip->int_enable[0] |= BIT(offset);
msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
}
static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned long irq_flags;
struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
if (on)
msm_chip->int_enable[1] |= BIT(offset);
else
msm_chip->int_enable[1] &= ~BIT(offset);
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
return 0;
}
static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
unsigned long irq_flags;
struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
unsigned val, mask = BIT(offset);
spin_lock_irqsave(&msm_chip->lock, irq_flags);
val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE);
if (flow_type & IRQ_TYPE_EDGE_BOTH) {
msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_INT_EDGE);
__irq_set_handler_locked(d->irq, handle_edge_irq);
} else {
msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_INT_EDGE);
__irq_set_handler_locked(d->irq, handle_level_irq);
}
if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
msm_chip->both_edge_detect |= mask;
msm_gpio_update_both_edge_detect(msm_chip);
} else {
msm_chip->both_edge_detect &= ~mask;
val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS);
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
val |= mask;
else
val &= ~mask;
msm_gpio_writel(msm_chip, val, MSM_GPIO_INT_POS);
}
spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
return 0;
}
static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int i, j, mask;
unsigned val;
for (i = 0; i < msm_gpio_count; i++) {
struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS);
val &= msm_chip->int_enable[0];
while (val) {
mask = val & -val;
j = fls(mask) - 1;
/* printk("%s %08x %08x bit %d gpio %d irq %d\n",
__func__, v, m, j, msm_chip->chip.start + j,
FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
val &= ~mask;
generic_handle_irq(FIRST_GPIO_IRQ +
msm_chip->chip.base + j);
}
}
desc->irq_data.chip->irq_ack(&desc->irq_data);
}
static struct irq_chip msm_gpio_irq_chip = {
.name = "msmgpio",
.irq_ack = msm_gpio_irq_ack,
.irq_mask = msm_gpio_irq_mask,
.irq_unmask = msm_gpio_irq_unmask,
.irq_set_wake = msm_gpio_irq_set_wake,
.irq_set_type = msm_gpio_irq_set_type,
};
static int gpio_msm_v1_probe(struct platform_device *pdev)
{
int i, j = 0;
const struct platform_device_id *dev_id = platform_get_device_id(pdev);
struct msm_gpio_initdata *data;
int irq1, irq2;
struct resource *res;
void __iomem *base1, __iomem *base2;
data = (struct msm_gpio_initdata *)dev_id->driver_data;
msm_gpio_chips = data->chips;
msm_gpio_count = data->count;
irq1 = platform_get_irq(pdev, 0);
if (irq1 < 0)
return irq1;
irq2 = platform_get_irq(pdev, 1);
if (irq2 < 0)
return irq2;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base1 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base1))
return PTR_ERR(base1);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
base2 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base2))
return PTR_ERR(base2);
for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
if (i - FIRST_GPIO_IRQ >=
msm_gpio_chips[j].chip.base +
msm_gpio_chips[j].chip.ngpio)
j++;
irq_set_chip_data(i, &msm_gpio_chips[j]);
irq_set_chip_and_handler(i, &msm_gpio_irq_chip,
handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < msm_gpio_count; i++) {
if (i == 1)
msm_gpio_chips[i].base = base2;
else
msm_gpio_chips[i].base = base1;
spin_lock_init(&msm_gpio_chips[i].lock);
msm_gpio_writel(&msm_gpio_chips[i], 0, MSM_GPIO_INT_EN);
gpiochip_add(&msm_gpio_chips[i].chip);
}
irq_set_chained_handler(irq1, msm_gpio_irq_handler);
irq_set_chained_handler(irq2, msm_gpio_irq_handler);
irq_set_irq_wake(irq1, 1);
irq_set_irq_wake(irq2, 1);
return 0;
}
static struct platform_device_id gpio_msm_v1_device_ids[] = {
{ "gpio-msm-7201", (unsigned long)&msm_gpio_7x01_init },
{ "gpio-msm-7x30", (unsigned long)&msm_gpio_7x30_init },
{ "gpio-msm-8x50", (unsigned long)&msm_gpio_8x50_init },
{ }
};
MODULE_DEVICE_TABLE(platform, gpio_msm_v1_device_ids);
static struct platform_driver gpio_msm_v1_driver = {
.driver = {
.name = "gpio-msm-v1",
},
.probe = gpio_msm_v1_probe,
.id_table = gpio_msm_v1_device_ids,
};
static int __init gpio_msm_v1_init(void)
{
return platform_driver_register(&gpio_msm_v1_driver);
}
postcore_initcall(gpio_msm_v1_init);
MODULE_LICENSE("GPL v2");
...@@ -408,14 +408,6 @@ config MMC_SDHCI_MSM ...@@ -408,14 +408,6 @@ config MMC_SDHCI_MSM
If unsure, say N. If unsure, say N.
config MMC_MSM
tristate "Qualcomm SDCC Controller Support"
depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50)
help
This provides support for the SD/MMC cell found in the
MSM and QSD SOCs from Qualcomm. The controller also has
support for SDIO devices.
config MMC_MXC config MMC_MXC
tristate "Freescale i.MX21/27/31 or MPC512x Multimedia Card support" tristate "Freescale i.MX21/27/31 or MPC512x Multimedia Card support"
depends on ARCH_MXC || PPC_MPC512x depends on ARCH_MXC || PPC_MPC512x
......
...@@ -24,7 +24,6 @@ obj-$(CONFIG_MMC_OMAP) += omap.o ...@@ -24,7 +24,6 @@ obj-$(CONFIG_MMC_OMAP) += omap.o
obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
obj-$(CONFIG_MMC_MSM) += msm_sdcc.o
obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
obj-$(CONFIG_MMC_GOLDFISH) += android-goldfish.o obj-$(CONFIG_MMC_GOLDFISH) += android-goldfish.o
......
/*
* linux/drivers/mmc/host/msm_sdcc.c - Qualcomm MSM 7X00A SDCC Driver
*
* Copyright (C) 2007 Google Inc,
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
* Copyright (C) 2009, Code Aurora Forum. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Based on mmci.c
*
* Author: San Mehat (san@android.com)
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/highmem.h>
#include <linux/log2.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/memory.h>
#include <linux/gfp.h>
#include <linux/gpio.h>
#include <asm/cacheflush.h>
#include <asm/div64.h>
#include <asm/sizes.h>
#include <linux/platform_data/mmc-msm_sdcc.h>
#include <mach/dma.h>
#include <mach/clk.h>
#include "msm_sdcc.h"
#define DRIVER_NAME "msm-sdcc"
#define BUSCLK_PWRSAVE 1
#define BUSCLK_TIMEOUT (HZ)
static unsigned int msmsdcc_fmin = 144000;
static unsigned int msmsdcc_fmax = 50000000;
static unsigned int msmsdcc_4bit = 1;
static unsigned int msmsdcc_pwrsave = 1;
static unsigned int msmsdcc_piopoll = 1;
static unsigned int msmsdcc_sdioirq;
#define PIO_SPINMAX 30
#define CMD_SPINMAX 20
static inline void
msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr)
{
WARN_ON(!host->clks_on);
BUG_ON(host->curr.mrq);
if (deferr) {
mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT);
} else {
del_timer_sync(&host->busclk_timer);
/* Need to check clks_on again in case the busclk
* timer fired
*/
if (host->clks_on) {
clk_disable(host->clk);
clk_disable(host->pclk);
host->clks_on = 0;
}
}
}
static inline int
msmsdcc_enable_clocks(struct msmsdcc_host *host)
{
int rc;
del_timer_sync(&host->busclk_timer);
if (!host->clks_on) {
rc = clk_enable(host->pclk);
if (rc)
return rc;
rc = clk_enable(host->clk);
if (rc) {
clk_disable(host->pclk);
return rc;
}
udelay(1 + ((3 * USEC_PER_SEC) /
(host->clk_rate ? host->clk_rate : msmsdcc_fmin)));
host->clks_on = 1;
}
return 0;
}
static inline unsigned int
msmsdcc_readl(struct msmsdcc_host *host, unsigned int reg)
{
return readl(host->base + reg);
}
static inline void
msmsdcc_writel(struct msmsdcc_host *host, u32 data, unsigned int reg)
{
writel(data, host->base + reg);
/* 3 clk delay required! */
udelay(1 + ((3 * USEC_PER_SEC) /
(host->clk_rate ? host->clk_rate : msmsdcc_fmin)));
}
static void
msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
u32 c);
static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
{
u32 mci_clk = 0;
u32 mci_mask0 = 0;
int ret = 0;
/* Save the controller state */
mci_clk = readl(host->base + MMCICLOCK);
mci_mask0 = readl(host->base + MMCIMASK0);
/* Reset the controller */
ret = clk_reset(host->clk, CLK_RESET_ASSERT);
if (ret)
pr_err("%s: Clock assert failed at %u Hz with err %d\n",
mmc_hostname(host->mmc), host->clk_rate, ret);
ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
if (ret)
pr_err("%s: Clock deassert failed at %u Hz with err %d\n",
mmc_hostname(host->mmc), host->clk_rate, ret);
pr_info("%s: Controller has been re-initialiazed\n",
mmc_hostname(host->mmc));
/* Restore the contoller state */
writel(host->pwr, host->base + MMCIPOWER);
writel(mci_clk, host->base + MMCICLOCK);
writel(mci_mask0, host->base + MMCIMASK0);
ret = clk_set_rate(host->clk, host->clk_rate);
if (ret)
pr_err("%s: Failed to set clk rate %u Hz (%d)\n",
mmc_hostname(host->mmc), host->clk_rate, ret);
}
static void
msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
{
BUG_ON(host->curr.data);
host->curr.mrq = NULL;
host->curr.cmd = NULL;
if (mrq->data)
mrq->data->bytes_xfered = host->curr.data_xfered;
if (mrq->cmd->error == -ETIMEDOUT)
mdelay(5);
#if BUSCLK_PWRSAVE
msmsdcc_disable_clocks(host, 1);
#endif
/*
* Need to drop the host lock here; mmc_request_done may call
* back into the driver...
*/
spin_unlock(&host->lock);
mmc_request_done(host->mmc, mrq);
spin_lock(&host->lock);
}
static void
msmsdcc_stop_data(struct msmsdcc_host *host)
{
host->curr.data = NULL;
host->curr.got_dataend = 0;
}
uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
{
return host->memres->start + MMCIFIFO;
}
static inline void
msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c) {
msmsdcc_writel(host, arg, MMCIARGUMENT);
msmsdcc_writel(host, c, MMCICOMMAND);
}
static void
msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
{
struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data;
msmsdcc_writel(host, host->cmd_timeout, MMCIDATATIMER);
msmsdcc_writel(host, (unsigned int)host->curr.xfer_size,
MMCIDATALENGTH);
msmsdcc_writel(host, (msmsdcc_readl(host, MMCIMASK0) &
(~MCI_IRQ_PIO)) | host->cmd_pio_irqmask, MMCIMASK0);
msmsdcc_writel(host, host->cmd_datactrl, MMCIDATACTRL);
if (host->cmd_cmd) {
msmsdcc_start_command_exec(host,
(u32) host->cmd_cmd->arg,
(u32) host->cmd_c);
}
host->dma.active = 1;
}
static void
msmsdcc_dma_complete_tlet(unsigned long data)
{
struct msmsdcc_host *host = (struct msmsdcc_host *)data;
unsigned long flags;
struct mmc_request *mrq;
struct msm_dmov_errdata err;
spin_lock_irqsave(&host->lock, flags);
host->dma.active = 0;
err = host->dma.err;
mrq = host->curr.mrq;
BUG_ON(!mrq);
WARN_ON(!mrq->data);
if (!(host->dma.result & DMOV_RSLT_VALID)) {
pr_err("msmsdcc: Invalid DataMover result\n");
goto out;
}
if (host->dma.result & DMOV_RSLT_DONE) {
host->curr.data_xfered = host->curr.xfer_size;
} else {
/* Error or flush */
if (host->dma.result & DMOV_RSLT_ERROR)
pr_err("%s: DMA error (0x%.8x)\n",
mmc_hostname(host->mmc), host->dma.result);
if (host->dma.result & DMOV_RSLT_FLUSH)
pr_err("%s: DMA channel flushed (0x%.8x)\n",
mmc_hostname(host->mmc), host->dma.result);
pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n",
err.flush[0], err.flush[1], err.flush[2],
err.flush[3], err.flush[4], err.flush[5]);
msmsdcc_reset_and_restore(host);
if (!mrq->data->error)
mrq->data->error = -EIO;
}
dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents,
host->dma.dir);
host->dma.sg = NULL;
host->dma.busy = 0;
if (host->curr.got_dataend || mrq->data->error) {
/*
* If we've already gotten our DATAEND / DATABLKEND
* for this request, then complete it through here.
*/
msmsdcc_stop_data(host);
if (!mrq->data->error)
host->curr.data_xfered = host->curr.xfer_size;
if (!mrq->data->stop || mrq->cmd->error) {
host->curr.mrq = NULL;
host->curr.cmd = NULL;
mrq->data->bytes_xfered = host->curr.data_xfered;
spin_unlock_irqrestore(&host->lock, flags);
#if BUSCLK_PWRSAVE
msmsdcc_disable_clocks(host, 1);
#endif
mmc_request_done(host->mmc, mrq);
return;
} else
msmsdcc_start_command(host, mrq->data->stop, 0);
}
out:
spin_unlock_irqrestore(&host->lock, flags);
return;
}
static void
msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
unsigned int result,
struct msm_dmov_errdata *err)
{
struct msmsdcc_dma_data *dma_data =
container_of(cmd, struct msmsdcc_dma_data, hdr);
struct msmsdcc_host *host = dma_data->host;
dma_data->result = result;
if (err)
memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata));
tasklet_schedule(&host->dma_tlet);
}
static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data)
{
if (host->dma.channel == -1)
return -ENOENT;
if ((data->blksz * data->blocks) < MCI_FIFOSIZE)
return -EINVAL;
if ((data->blksz * data->blocks) % MCI_FIFOSIZE)
return -EINVAL;
return 0;
}
static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
{
struct msmsdcc_nc_dmadata *nc;
dmov_box *box;
uint32_t rows;
uint32_t crci;
unsigned int n;
int i, rc;
struct scatterlist *sg = data->sg;
rc = validate_dma(host, data);
if (rc)
return rc;
host->dma.sg = data->sg;
host->dma.num_ents = data->sg_len;
BUG_ON(host->dma.num_ents > NR_SG); /* Prevent memory corruption */
nc = host->dma.nc;
switch (host->pdev_id) {
case 1:
crci = MSMSDCC_CRCI_SDC1;
break;
case 2:
crci = MSMSDCC_CRCI_SDC2;
break;
case 3:
crci = MSMSDCC_CRCI_SDC3;
break;
case 4:
crci = MSMSDCC_CRCI_SDC4;
break;
default:
host->dma.sg = NULL;
host->dma.num_ents = 0;
return -ENOENT;
}
if (data->flags & MMC_DATA_READ)
host->dma.dir = DMA_FROM_DEVICE;
else
host->dma.dir = DMA_TO_DEVICE;
host->curr.user_pages = 0;
box = &nc->cmd[0];
/* location of command block must be 64 bit aligned */
BUG_ON(host->dma.cmd_busaddr & 0x07);
nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
host->dma.num_ents, host->dma.dir);
if (n == 0) {
pr_err("%s: Unable to map in all sg elements\n",
mmc_hostname(host->mmc));
host->dma.sg = NULL;
host->dma.num_ents = 0;
return -ENOMEM;
}
for_each_sg(host->dma.sg, sg, n, i) {
box->cmd = CMD_MODE_BOX;
if (i == n - 1)
box->cmd |= CMD_LC;
rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
(sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
(sg_dma_len(sg) / MCI_FIFOSIZE) ;
if (data->flags & MMC_DATA_READ) {
box->src_row_addr = msmsdcc_fifo_addr(host);
box->dst_row_addr = sg_dma_address(sg);
box->src_dst_len = (MCI_FIFOSIZE << 16) |
(MCI_FIFOSIZE);
box->row_offset = MCI_FIFOSIZE;
box->num_rows = rows * ((1 << 16) + 1);
box->cmd |= CMD_SRC_CRCI(crci);
} else {
box->src_row_addr = sg_dma_address(sg);
box->dst_row_addr = msmsdcc_fifo_addr(host);
box->src_dst_len = (MCI_FIFOSIZE << 16) |
(MCI_FIFOSIZE);
box->row_offset = (MCI_FIFOSIZE << 16);
box->num_rows = rows * ((1 << 16) + 1);
box->cmd |= CMD_DST_CRCI(crci);
}
box++;
}
return 0;
}
static int
snoop_cccr_abort(struct mmc_command *cmd)
{
if ((cmd->opcode == 52) &&
(cmd->arg & 0x80000000) &&
(((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT))
return 1;
return 0;
}
static void
msmsdcc_start_command_deferred(struct msmsdcc_host *host,
struct mmc_command *cmd, u32 *c)
{
*c |= (cmd->opcode | MCI_CPSM_ENABLE);
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
*c |= MCI_CPSM_LONGRSP;
*c |= MCI_CPSM_RESPONSE;
}
if (/*interrupt*/0)
*c |= MCI_CPSM_INTERRUPT;
if ((((cmd->opcode == 17) || (cmd->opcode == 18)) ||
((cmd->opcode == 24) || (cmd->opcode == 25))) ||
(cmd->opcode == 53))
*c |= MCI_CSPM_DATCMD;
if (host->prog_scan && (cmd->opcode == 12)) {
*c |= MCI_CPSM_PROGENA;
host->prog_enable = true;
}
if (cmd == cmd->mrq->stop)
*c |= MCI_CSPM_MCIABORT;
if (snoop_cccr_abort(cmd))
*c |= MCI_CSPM_MCIABORT;
if (host->curr.cmd != NULL) {
pr_err("%s: Overlapping command requests\n",
mmc_hostname(host->mmc));
}
host->curr.cmd = cmd;
}
static void
msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
struct mmc_command *cmd, u32 c)
{
unsigned int datactrl, timeout;
unsigned long long clks;
unsigned int pio_irqmask = 0;
host->curr.data = data;
host->curr.xfer_size = data->blksz * data->blocks;
host->curr.xfer_remain = host->curr.xfer_size;
host->curr.data_xfered = 0;
host->curr.got_dataend = 0;
memset(&host->pio, 0, sizeof(host->pio));
datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
if (!msmsdcc_config_dma(host, data))
datactrl |= MCI_DPSM_DMAENABLE;
else {
host->pio.sg = data->sg;
host->pio.sg_len = data->sg_len;
host->pio.sg_off = 0;
if (data->flags & MMC_DATA_READ) {
pio_irqmask = MCI_RXFIFOHALFFULLMASK;
if (host->curr.xfer_remain < MCI_FIFOSIZE)
pio_irqmask |= MCI_RXDATAAVLBLMASK;
} else
pio_irqmask = MCI_TXFIFOHALFEMPTYMASK;
}
if (data->flags & MMC_DATA_READ)
datactrl |= MCI_DPSM_DIRECTION;
clks = (unsigned long long)data->timeout_ns * host->clk_rate;
do_div(clks, NSEC_PER_SEC);
timeout = data->timeout_clks + (unsigned int)clks*2 ;
if (datactrl & MCI_DPSM_DMAENABLE) {
/* Save parameters for the exec function */
host->cmd_timeout = timeout;
host->cmd_pio_irqmask = pio_irqmask;
host->cmd_datactrl = datactrl;
host->cmd_cmd = cmd;
host->dma.hdr.execute_func = msmsdcc_dma_exec_func;
host->dma.hdr.data = (void *)host;
host->dma.busy = 1;
if (cmd) {
msmsdcc_start_command_deferred(host, cmd, &c);
host->cmd_c = c;
}
msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
if (data->flags & MMC_DATA_WRITE)
host->prog_scan = true;
} else {
msmsdcc_writel(host, timeout, MMCIDATATIMER);
msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH);
msmsdcc_writel(host, (msmsdcc_readl(host, MMCIMASK0) &
(~MCI_IRQ_PIO)) | pio_irqmask, MMCIMASK0);
msmsdcc_writel(host, datactrl, MMCIDATACTRL);
if (cmd) {
/* Daisy-chain the command if requested */
msmsdcc_start_command(host, cmd, c);
}
}
}
static void
msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c)
{
if (cmd == cmd->mrq->stop)
c |= MCI_CSPM_MCIABORT;
host->stats.cmds++;
msmsdcc_start_command_deferred(host, cmd, &c);
msmsdcc_start_command_exec(host, cmd->arg, c);
}
static void
msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data,
unsigned int status)
{
if (status & MCI_DATACRCFAIL) {
pr_err("%s: Data CRC error\n", mmc_hostname(host->mmc));
pr_err("%s: opcode 0x%.8x\n", __func__,
data->mrq->cmd->opcode);
pr_err("%s: blksz %d, blocks %d\n", __func__,
data->blksz, data->blocks);
data->error = -EILSEQ;
} else if (status & MCI_DATATIMEOUT) {
pr_err("%s: Data timeout\n", mmc_hostname(host->mmc));
data->error = -ETIMEDOUT;
} else if (status & MCI_RXOVERRUN) {
pr_err("%s: RX overrun\n", mmc_hostname(host->mmc));
data->error = -EIO;
} else if (status & MCI_TXUNDERRUN) {
pr_err("%s: TX underrun\n", mmc_hostname(host->mmc));
data->error = -EIO;
} else {
pr_err("%s: Unknown error (0x%.8x)\n",
mmc_hostname(host->mmc), status);
data->error = -EIO;
}
}
static int
msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain)
{
uint32_t *ptr = (uint32_t *) buffer;
int count = 0;
if (remain % 4)
remain = ((remain >> 2) + 1) << 2;
while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) {
*ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE));
ptr++;
count += sizeof(uint32_t);
remain -= sizeof(uint32_t);
if (remain == 0)
break;
}
return count;
}
static int
msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer,
unsigned int remain, u32 status)
{
void __iomem *base = host->base;
char *ptr = buffer;
do {
unsigned int count, maxcnt, sz;
maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE :
MCI_FIFOHALFSIZE;
count = min(remain, maxcnt);
sz = count % 4 ? (count >> 2) + 1 : (count >> 2);
writesl(base + MMCIFIFO, ptr, sz);
ptr += count;
remain -= count;
if (remain == 0)
break;
status = msmsdcc_readl(host, MMCISTATUS);
} while (status & MCI_TXFIFOHALFEMPTY);
return ptr - buffer;
}
static int
msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin)
{
while (maxspin) {
if ((msmsdcc_readl(host, MMCISTATUS) & mask))
return 0;
udelay(1);
--maxspin;
}
return -ETIMEDOUT;
}
static irqreturn_t
msmsdcc_pio_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
uint32_t status;
u32 mci_mask0;
status = msmsdcc_readl(host, MMCISTATUS);
mci_mask0 = msmsdcc_readl(host, MMCIMASK0);
if (((mci_mask0 & status) & MCI_IRQ_PIO) == 0)
return IRQ_NONE;
do {
unsigned long flags;
unsigned int remain, len;
char *buffer;
if (!(status & (MCI_TXFIFOHALFEMPTY | MCI_RXDATAAVLBL))) {
if (host->curr.xfer_remain == 0 || !msmsdcc_piopoll)
break;
if (msmsdcc_spin_on_status(host,
(MCI_TXFIFOHALFEMPTY |
MCI_RXDATAAVLBL),
PIO_SPINMAX)) {
break;
}
}
/* Map the current scatter buffer */
local_irq_save(flags);
buffer = kmap_atomic(sg_page(host->pio.sg))
+ host->pio.sg->offset;
buffer += host->pio.sg_off;
remain = host->pio.sg->length - host->pio.sg_off;
len = 0;
if (status & MCI_RXACTIVE)
len = msmsdcc_pio_read(host, buffer, remain);
if (status & MCI_TXACTIVE)
len = msmsdcc_pio_write(host, buffer, remain, status);
/* Unmap the buffer */
kunmap_atomic(buffer);
local_irq_restore(flags);
host->pio.sg_off += len;
host->curr.xfer_remain -= len;
host->curr.data_xfered += len;
remain -= len;
if (remain == 0) {
/* This sg page is full - do some housekeeping */
if (status & MCI_RXACTIVE && host->curr.user_pages)
flush_dcache_page(sg_page(host->pio.sg));
if (!--host->pio.sg_len) {
memset(&host->pio, 0, sizeof(host->pio));
break;
}
/* Advance to next sg */
host->pio.sg++;
host->pio.sg_off = 0;
}
status = msmsdcc_readl(host, MMCISTATUS);
} while (1);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE)
msmsdcc_writel(host, (mci_mask0 & (~MCI_IRQ_PIO)) |
MCI_RXDATAAVLBLMASK, MMCIMASK0);
if (!host->curr.xfer_remain)
msmsdcc_writel(host, (mci_mask0 & (~MCI_IRQ_PIO)) | 0,
MMCIMASK0);
return IRQ_HANDLED;
}
static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
{
struct mmc_command *cmd = host->curr.cmd;
host->curr.cmd = NULL;
cmd->resp[0] = msmsdcc_readl(host, MMCIRESPONSE0);
cmd->resp[1] = msmsdcc_readl(host, MMCIRESPONSE1);
cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2);
cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3);
if (status & MCI_CMDTIMEOUT) {
cmd->error = -ETIMEDOUT;
} else if (status & MCI_CMDCRCFAIL &&
cmd->flags & MMC_RSP_CRC) {
pr_err("%s: Command CRC error\n", mmc_hostname(host->mmc));
cmd->error = -EILSEQ;
}
if (!cmd->data || cmd->error) {
if (host->curr.data && host->dma.sg)
msm_dmov_stop_cmd(host->dma.channel,
&host->dma.hdr, 0);
else if (host->curr.data) { /* Non DMA */
msmsdcc_reset_and_restore(host);
msmsdcc_stop_data(host);
msmsdcc_request_end(host, cmd->mrq);
} else { /* host->data == NULL */
if (!cmd->error && host->prog_enable) {
if (status & MCI_PROGDONE) {
host->prog_scan = false;
host->prog_enable = false;
msmsdcc_request_end(host, cmd->mrq);
} else {
host->curr.cmd = cmd;
}
} else {
if (host->prog_enable) {
host->prog_scan = false;
host->prog_enable = false;
}
msmsdcc_request_end(host, cmd->mrq);
}
}
} else if (cmd->data)
if (!(cmd->data->flags & MMC_DATA_READ))
msmsdcc_start_data(host, cmd->data,
NULL, 0);
}
static void
msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
void __iomem *base)
{
struct mmc_data *data = host->curr.data;
if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
msmsdcc_do_cmdirq(host, status);
}
if (!data)
return;
/* Check for data errors */
if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT |
MCI_TXUNDERRUN | MCI_RXOVERRUN)) {
msmsdcc_data_err(host, data, status);
host->curr.data_xfered = 0;
if (host->dma.sg)
msm_dmov_stop_cmd(host->dma.channel,
&host->dma.hdr, 0);
else {
msmsdcc_reset_and_restore(host);
if (host->curr.data)
msmsdcc_stop_data(host);
if (!data->stop)
msmsdcc_request_end(host, data->mrq);
else
msmsdcc_start_command(host, data->stop, 0);
}
}
/* Check for data done */
if (!host->curr.got_dataend && (status & MCI_DATAEND))
host->curr.got_dataend = 1;
/*
* If DMA is still in progress, we complete via the completion handler
*/
if (host->curr.got_dataend && !host->dma.busy) {
/*
* There appears to be an issue in the controller where
* if you request a small block transfer (< fifo size),
* you may get your DATAEND/DATABLKEND irq without the
* PIO data irq.
*
* Check to see if there is still data to be read,
* and simulate a PIO irq.
*/
if (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL)
msmsdcc_pio_irq(1, host);
msmsdcc_stop_data(host);
if (!data->error)
host->curr.data_xfered = host->curr.xfer_size;
if (!data->stop)
msmsdcc_request_end(host, data->mrq);
else
msmsdcc_start_command(host, data->stop, 0);
}
}
static irqreturn_t
msmsdcc_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
void __iomem *base = host->base;
u32 status;
int ret = 0;
int cardint = 0;
spin_lock(&host->lock);
do {
status = msmsdcc_readl(host, MMCISTATUS);
status &= msmsdcc_readl(host, MMCIMASK0);
if ((status & (~MCI_IRQ_PIO)) == 0)
break;
msmsdcc_writel(host, status, MMCICLEAR);
if (status & MCI_SDIOINTR)
status &= ~MCI_SDIOINTR;
if (!status)
break;
msmsdcc_handle_irq_data(host, status, base);
if (status & MCI_SDIOINTOPER) {
cardint = 1;
status &= ~MCI_SDIOINTOPER;
}
ret = 1;
} while (status);
spin_unlock(&host->lock);
/*
* We have to delay handling the card interrupt as it calls
* back into the driver.
*/
if (cardint)
mmc_signal_sdio_irq(host->mmc);
return IRQ_RETVAL(ret);
}
static void
msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct msmsdcc_host *host = mmc_priv(mmc);
unsigned long flags;
WARN_ON(host->curr.mrq != NULL);
WARN_ON(host->pwr == 0);
spin_lock_irqsave(&host->lock, flags);
host->stats.reqs++;
if (host->eject) {
if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) {
mrq->cmd->error = 0;
mrq->data->bytes_xfered = mrq->data->blksz *
mrq->data->blocks;
} else
mrq->cmd->error = -ENOMEDIUM;
spin_unlock_irqrestore(&host->lock, flags);
mmc_request_done(mmc, mrq);
return;
}
msmsdcc_enable_clocks(host);
host->curr.mrq = mrq;
if (mrq->data && mrq->data->flags & MMC_DATA_READ)
/* Queue/read data, daisy-chain command when data starts */
msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);
else
msmsdcc_start_command(host, mrq->cmd, 0);
if (host->cmdpoll && !msmsdcc_spin_on_status(host,
MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT,
CMD_SPINMAX)) {
uint32_t status = msmsdcc_readl(host, MMCISTATUS);
msmsdcc_do_cmdirq(host, status);
msmsdcc_writel(host,
MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT,
MMCICLEAR);
host->stats.cmdpoll_hits++;
} else {
host->stats.cmdpoll_misses++;
}
spin_unlock_irqrestore(&host->lock, flags);
}
static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable)
{
struct msm_mmc_gpio_data *curr;
int i, rc = 0;
if (!host->plat->gpio_data || host->gpio_config_status == enable)
return;
curr = host->plat->gpio_data;
for (i = 0; i < curr->size; i++) {
if (enable) {
rc = gpio_request(curr->gpio[i].no,
curr->gpio[i].name);
if (rc) {
pr_err("%s: gpio_request(%d, %s) failed %d\n",
mmc_hostname(host->mmc),
curr->gpio[i].no,
curr->gpio[i].name, rc);
goto free_gpios;
}
} else {
gpio_free(curr->gpio[i].no);
}
}
host->gpio_config_status = enable;
return;
free_gpios:
for (; i >= 0; i--)
gpio_free(curr->gpio[i].no);
}
static void
msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct msmsdcc_host *host = mmc_priv(mmc);
u32 clk = 0, pwr = 0;
int rc;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
msmsdcc_enable_clocks(host);
spin_unlock_irqrestore(&host->lock, flags);
if (ios->clock) {
if (ios->clock != host->clk_rate) {
rc = clk_set_rate(host->clk, ios->clock);
if (rc < 0)
pr_err("%s: Error setting clock rate (%d)\n",
mmc_hostname(host->mmc), rc);
else
host->clk_rate = ios->clock;
}
clk |= MCI_CLK_ENABLE;
}
if (ios->bus_width == MMC_BUS_WIDTH_4)
clk |= (2 << 10); /* Set WIDEBUS */
if (ios->clock > 400000 && msmsdcc_pwrsave)
clk |= (1 << 9); /* PWRSAVE */
clk |= (1 << 12); /* FLOW_ENA */
clk |= (1 << 15); /* feedback clock */
if (host->plat->translate_vdd)
pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
switch (ios->power_mode) {
case MMC_POWER_OFF:
msmsdcc_setup_gpio(host, false);
break;
case MMC_POWER_UP:
pwr |= MCI_PWR_UP;
msmsdcc_setup_gpio(host, true);
break;
case MMC_POWER_ON:
pwr |= MCI_PWR_ON;
break;
}
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
pwr |= MCI_OD;
msmsdcc_writel(host, clk, MMCICLOCK);
if (host->pwr != pwr) {
host->pwr = pwr;
msmsdcc_writel(host, pwr, MMCIPOWER);
}
#if BUSCLK_PWRSAVE
spin_lock_irqsave(&host->lock, flags);
msmsdcc_disable_clocks(host, 1);
spin_unlock_irqrestore(&host->lock, flags);
#endif
}
static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct msmsdcc_host *host = mmc_priv(mmc);
unsigned long flags;
u32 status;
spin_lock_irqsave(&host->lock, flags);
if (msmsdcc_sdioirq == 1) {
status = msmsdcc_readl(host, MMCIMASK0);
if (enable)
status |= MCI_SDIOINTOPERMASK;
else
status &= ~MCI_SDIOINTOPERMASK;
host->saved_irq0mask = status;
msmsdcc_writel(host, status, MMCIMASK0);
}
spin_unlock_irqrestore(&host->lock, flags);
}
static void msmsdcc_init_card(struct mmc_host *mmc, struct mmc_card *card)
{
struct msmsdcc_host *host = mmc_priv(mmc);
if (host->plat->init_card)
host->plat->init_card(card);
}
static const struct mmc_host_ops msmsdcc_ops = {
.request = msmsdcc_request,
.set_ios = msmsdcc_set_ios,
.enable_sdio_irq = msmsdcc_enable_sdio_irq,
.init_card = msmsdcc_init_card,
};
static void
msmsdcc_check_status(unsigned long data)
{
struct msmsdcc_host *host = (struct msmsdcc_host *)data;
unsigned int status;
if (!host->plat->status) {
mmc_detect_change(host->mmc, 0);
goto out;
}
status = host->plat->status(mmc_dev(host->mmc));
host->eject = !status;
if (status ^ host->oldstat) {
pr_info("%s: Slot status change detected (%d -> %d)\n",
mmc_hostname(host->mmc), host->oldstat, status);
if (status)
mmc_detect_change(host->mmc, (5 * HZ) / 2);
else
mmc_detect_change(host->mmc, 0);
}
host->oldstat = status;
out:
if (host->timer.function)
mod_timer(&host->timer, jiffies + HZ);
}
static irqreturn_t
msmsdcc_platform_status_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
pr_debug("%s: %d\n", __func__, irq);
msmsdcc_check_status((unsigned long) host);
return IRQ_HANDLED;
}
static void
msmsdcc_status_notify_cb(int card_present, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
pr_debug("%s: card_present %d\n", mmc_hostname(host->mmc),
card_present);
msmsdcc_check_status((unsigned long) host);
}
static void
msmsdcc_busclk_expired(unsigned long _data)
{
struct msmsdcc_host *host = (struct msmsdcc_host *) _data;
if (host->clks_on)
msmsdcc_disable_clocks(host, 0);
}
static int
msmsdcc_init_dma(struct msmsdcc_host *host)
{
memset(&host->dma, 0, sizeof(struct msmsdcc_dma_data));
host->dma.host = host;
host->dma.channel = -1;
if (!host->dmares)
return -ENODEV;
host->dma.nc = dma_alloc_coherent(NULL,
sizeof(struct msmsdcc_nc_dmadata),
&host->dma.nc_busaddr,
GFP_KERNEL);
if (host->dma.nc == NULL) {
pr_err("Unable to allocate DMA buffer\n");
return -ENOMEM;
}
memset(host->dma.nc, 0x00, sizeof(struct msmsdcc_nc_dmadata));
host->dma.cmd_busaddr = host->dma.nc_busaddr;
host->dma.cmdptr_busaddr = host->dma.nc_busaddr +
offsetof(struct msmsdcc_nc_dmadata, cmdptr);
host->dma.channel = host->dmares->start;
return 0;
}
static int
msmsdcc_probe(struct platform_device *pdev)
{
struct msm_mmc_platform_data *plat = pdev->dev.platform_data;
struct msmsdcc_host *host;
struct mmc_host *mmc;
struct resource *cmd_irqres = NULL;
struct resource *stat_irqres = NULL;
struct resource *memres = NULL;
struct resource *dmares = NULL;
int ret;
/* must have platform data */
if (!plat) {
pr_err("%s: Platform data not available\n", __func__);
ret = -EINVAL;
goto out;
}
if (pdev->id < 1 || pdev->id > 4)
return -EINVAL;
if (pdev->resource == NULL || pdev->num_resources < 2) {
pr_err("%s: Invalid resource\n", __func__);
return -ENXIO;
}
memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
cmd_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
"cmd_irq");
stat_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
"status_irq");
if (!cmd_irqres || !memres) {
pr_err("%s: Invalid resource\n", __func__);
return -ENXIO;
}
/*
* Setup our host structure
*/
mmc = mmc_alloc_host(sizeof(struct msmsdcc_host), &pdev->dev);
if (!mmc) {
ret = -ENOMEM;
goto out;
}
host = mmc_priv(mmc);
host->pdev_id = pdev->id;
host->plat = plat;
host->mmc = mmc;
host->curr.cmd = NULL;
init_timer(&host->busclk_timer);
host->busclk_timer.data = (unsigned long) host;
host->busclk_timer.function = msmsdcc_busclk_expired;
host->cmdpoll = 1;
host->base = ioremap(memres->start, PAGE_SIZE);
if (!host->base) {
ret = -ENOMEM;
goto host_free;
}
host->cmd_irqres = cmd_irqres;
host->memres = memres;
host->dmares = dmares;
spin_lock_init(&host->lock);
tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet,
(unsigned long)host);
/*
* Setup DMA
*/
if (host->dmares) {
ret = msmsdcc_init_dma(host);
if (ret)
goto ioremap_free;
} else {
host->dma.channel = -1;
}
/* Get our clocks */
host->pclk = clk_get(&pdev->dev, "sdc_pclk");
if (IS_ERR(host->pclk)) {
ret = PTR_ERR(host->pclk);
goto dma_free;
}
host->clk = clk_get(&pdev->dev, "sdc_clk");
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
goto pclk_put;
}
ret = clk_set_rate(host->clk, msmsdcc_fmin);
if (ret) {
pr_err("%s: Clock rate set failed (%d)\n", __func__, ret);
goto clk_put;
}
ret = clk_prepare(host->pclk);
if (ret)
goto clk_put;
ret = clk_prepare(host->clk);
if (ret)
goto clk_unprepare_p;
/* Enable clocks */
ret = msmsdcc_enable_clocks(host);
if (ret)
goto clk_unprepare;
host->pclk_rate = clk_get_rate(host->pclk);
host->clk_rate = clk_get_rate(host->clk);
/*
* Setup MMC host structure
*/
mmc->ops = &msmsdcc_ops;
mmc->f_min = msmsdcc_fmin;
mmc->f_max = msmsdcc_fmax;
mmc->ocr_avail = plat->ocr_mask;
if (msmsdcc_4bit)
mmc->caps |= MMC_CAP_4_BIT_DATA;
if (msmsdcc_sdioirq)
mmc->caps |= MMC_CAP_SDIO_IRQ;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
mmc->max_segs = NR_SG;
mmc->max_blk_size = 4096; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */
mmc->max_blk_count = 65536;
mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */
mmc->max_seg_size = mmc->max_req_size;
msmsdcc_writel(host, 0, MMCIMASK0);
msmsdcc_writel(host, 0x5e007ff, MMCICLEAR);
msmsdcc_writel(host, MCI_IRQENABLE, MMCIMASK0);
host->saved_irq0mask = MCI_IRQENABLE;
/*
* Setup card detect change
*/
memset(&host->timer, 0, sizeof(host->timer));
if (stat_irqres && !(stat_irqres->flags & IORESOURCE_DISABLED)) {
unsigned long irqflags = IRQF_SHARED |
(stat_irqres->flags & IRQF_TRIGGER_MASK);
host->stat_irq = stat_irqres->start;
ret = request_irq(host->stat_irq,
msmsdcc_platform_status_irq,
irqflags,
DRIVER_NAME " (slot)",
host);
if (ret) {
pr_err("%s: Unable to get slot IRQ %d (%d)\n",
mmc_hostname(mmc), host->stat_irq, ret);
goto clk_disable;
}
} else if (plat->register_status_notify) {
plat->register_status_notify(msmsdcc_status_notify_cb, host);
} else if (!plat->status)
pr_err("%s: No card detect facilities available\n",
mmc_hostname(mmc));
else {
init_timer(&host->timer);
host->timer.data = (unsigned long)host;
host->timer.function = msmsdcc_check_status;
host->timer.expires = jiffies + HZ;
add_timer(&host->timer);
}
if (plat->status) {
host->oldstat = host->plat->status(mmc_dev(host->mmc));
host->eject = !host->oldstat;
}
ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED,
DRIVER_NAME " (cmd)", host);
if (ret)
goto stat_irq_free;
ret = request_irq(cmd_irqres->start, msmsdcc_pio_irq, IRQF_SHARED,
DRIVER_NAME " (pio)", host);
if (ret)
goto cmd_irq_free;
platform_set_drvdata(pdev, mmc);
mmc_add_host(mmc);
pr_info("%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n",
mmc_hostname(mmc), (unsigned long long)memres->start,
(unsigned int) cmd_irqres->start,
(unsigned int) host->stat_irq, host->dma.channel);
pr_info("%s: 4 bit data mode %s\n", mmc_hostname(mmc),
(mmc->caps & MMC_CAP_4_BIT_DATA ? "enabled" : "disabled"));
pr_info("%s: MMC clock %u -> %u Hz, PCLK %u Hz\n",
mmc_hostname(mmc), msmsdcc_fmin, msmsdcc_fmax, host->pclk_rate);
pr_info("%s: Slot eject status = %d\n", mmc_hostname(mmc), host->eject);
pr_info("%s: Power save feature enable = %d\n",
mmc_hostname(mmc), msmsdcc_pwrsave);
if (host->dma.channel != -1) {
pr_info("%s: DM non-cached buffer at %p, dma_addr 0x%.8x\n",
mmc_hostname(mmc), host->dma.nc, host->dma.nc_busaddr);
pr_info("%s: DM cmd busaddr 0x%.8x, cmdptr busaddr 0x%.8x\n",
mmc_hostname(mmc), host->dma.cmd_busaddr,
host->dma.cmdptr_busaddr);
} else
pr_info("%s: PIO transfer enabled\n", mmc_hostname(mmc));
if (host->timer.function)
pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
return 0;
cmd_irq_free:
free_irq(cmd_irqres->start, host);
stat_irq_free:
if (host->stat_irq)
free_irq(host->stat_irq, host);
clk_disable:
msmsdcc_disable_clocks(host, 0);
clk_unprepare:
clk_unprepare(host->clk);
clk_unprepare_p:
clk_unprepare(host->pclk);
clk_put:
clk_put(host->clk);
pclk_put:
clk_put(host->pclk);
dma_free:
if (host->dmares)
dma_free_coherent(NULL, sizeof(struct msmsdcc_nc_dmadata),
host->dma.nc, host->dma.nc_busaddr);
ioremap_free:
tasklet_kill(&host->dma_tlet);
iounmap(host->base);
host_free:
mmc_free_host(mmc);
out:
return ret;
}
#ifdef CONFIG_PM
static int
msmsdcc_suspend(struct platform_device *dev, pm_message_t state)
{
struct mmc_host *mmc = platform_get_drvdata(dev);
if (mmc) {
struct msmsdcc_host *host = mmc_priv(mmc);
if (host->stat_irq)
disable_irq(host->stat_irq);
msmsdcc_writel(host, 0, MMCIMASK0);
if (host->clks_on)
msmsdcc_disable_clocks(host, 0);
}
return 0;
}
static int
msmsdcc_resume(struct platform_device *dev)
{
struct mmc_host *mmc = platform_get_drvdata(dev);
if (mmc) {
struct msmsdcc_host *host = mmc_priv(mmc);
msmsdcc_enable_clocks(host);
msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0);
if (host->stat_irq)
enable_irq(host->stat_irq);
#if BUSCLK_PWRSAVE
msmsdcc_disable_clocks(host, 1);
#endif
}
return 0;
}
#else
#define msmsdcc_suspend 0
#define msmsdcc_resume 0
#endif
static struct platform_driver msmsdcc_driver = {
.probe = msmsdcc_probe,
.suspend = msmsdcc_suspend,
.resume = msmsdcc_resume,
.driver = {
.name = "msm_sdcc",
},
};
module_platform_driver(msmsdcc_driver);
MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver");
MODULE_LICENSE("GPL");
/*
* linux/drivers/mmc/host/msmsdcc.h - QCT MSM7K SDC Controller
*
* Copyright (C) 2008 Google, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* - Based on mmci.h
*/
#ifndef _MSM_SDCC_H
#define _MSM_SDCC_H
#define MSMSDCC_CRCI_SDC1 6
#define MSMSDCC_CRCI_SDC2 7
#define MSMSDCC_CRCI_SDC3 12
#define MSMSDCC_CRCI_SDC4 13
#define MMCIPOWER 0x000
#define MCI_PWR_OFF 0x00
#define MCI_PWR_UP 0x02
#define MCI_PWR_ON 0x03
#define MCI_OD (1 << 6)
#define MMCICLOCK 0x004
#define MCI_CLK_ENABLE (1 << 8)
#define MCI_CLK_PWRSAVE (1 << 9)
#define MCI_CLK_WIDEBUS (1 << 10)
#define MCI_CLK_FLOWENA (1 << 12)
#define MCI_CLK_INVERTOUT (1 << 13)
#define MCI_CLK_SELECTIN (1 << 14)
#define MMCIARGUMENT 0x008
#define MMCICOMMAND 0x00c
#define MCI_CPSM_RESPONSE (1 << 6)
#define MCI_CPSM_LONGRSP (1 << 7)
#define MCI_CPSM_INTERRUPT (1 << 8)
#define MCI_CPSM_PENDING (1 << 9)
#define MCI_CPSM_ENABLE (1 << 10)
#define MCI_CPSM_PROGENA (1 << 11)
#define MCI_CSPM_DATCMD (1 << 12)
#define MCI_CSPM_MCIABORT (1 << 13)
#define MCI_CSPM_CCSENABLE (1 << 14)
#define MCI_CSPM_CCSDISABLE (1 << 15)
#define MMCIRESPCMD 0x010
#define MMCIRESPONSE0 0x014
#define MMCIRESPONSE1 0x018
#define MMCIRESPONSE2 0x01c
#define MMCIRESPONSE3 0x020
#define MMCIDATATIMER 0x024
#define MMCIDATALENGTH 0x028
#define MMCIDATACTRL 0x02c
#define MCI_DPSM_ENABLE (1 << 0)
#define MCI_DPSM_DIRECTION (1 << 1)
#define MCI_DPSM_MODE (1 << 2)
#define MCI_DPSM_DMAENABLE (1 << 3)
#define MMCIDATACNT 0x030
#define MMCISTATUS 0x034
#define MCI_CMDCRCFAIL (1 << 0)
#define MCI_DATACRCFAIL (1 << 1)
#define MCI_CMDTIMEOUT (1 << 2)
#define MCI_DATATIMEOUT (1 << 3)
#define MCI_TXUNDERRUN (1 << 4)
#define MCI_RXOVERRUN (1 << 5)
#define MCI_CMDRESPEND (1 << 6)
#define MCI_CMDSENT (1 << 7)
#define MCI_DATAEND (1 << 8)
#define MCI_DATABLOCKEND (1 << 10)
#define MCI_CMDACTIVE (1 << 11)
#define MCI_TXACTIVE (1 << 12)
#define MCI_RXACTIVE (1 << 13)
#define MCI_TXFIFOHALFEMPTY (1 << 14)
#define MCI_RXFIFOHALFFULL (1 << 15)
#define MCI_TXFIFOFULL (1 << 16)
#define MCI_RXFIFOFULL (1 << 17)
#define MCI_TXFIFOEMPTY (1 << 18)
#define MCI_RXFIFOEMPTY (1 << 19)
#define MCI_TXDATAAVLBL (1 << 20)
#define MCI_RXDATAAVLBL (1 << 21)
#define MCI_SDIOINTR (1 << 22)
#define MCI_PROGDONE (1 << 23)
#define MCI_ATACMDCOMPL (1 << 24)
#define MCI_SDIOINTOPER (1 << 25)
#define MCI_CCSTIMEOUT (1 << 26)
#define MMCICLEAR 0x038
#define MCI_CMDCRCFAILCLR (1 << 0)
#define MCI_DATACRCFAILCLR (1 << 1)
#define MCI_CMDTIMEOUTCLR (1 << 2)
#define MCI_DATATIMEOUTCLR (1 << 3)
#define MCI_TXUNDERRUNCLR (1 << 4)
#define MCI_RXOVERRUNCLR (1 << 5)
#define MCI_CMDRESPENDCLR (1 << 6)
#define MCI_CMDSENTCLR (1 << 7)
#define MCI_DATAENDCLR (1 << 8)
#define MCI_DATABLOCKENDCLR (1 << 10)
#define MMCIMASK0 0x03c
#define MCI_CMDCRCFAILMASK (1 << 0)
#define MCI_DATACRCFAILMASK (1 << 1)
#define MCI_CMDTIMEOUTMASK (1 << 2)
#define MCI_DATATIMEOUTMASK (1 << 3)
#define MCI_TXUNDERRUNMASK (1 << 4)
#define MCI_RXOVERRUNMASK (1 << 5)
#define MCI_CMDRESPENDMASK (1 << 6)
#define MCI_CMDSENTMASK (1 << 7)
#define MCI_DATAENDMASK (1 << 8)
#define MCI_DATABLOCKENDMASK (1 << 10)
#define MCI_CMDACTIVEMASK (1 << 11)
#define MCI_TXACTIVEMASK (1 << 12)
#define MCI_RXACTIVEMASK (1 << 13)
#define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
#define MCI_RXFIFOHALFFULLMASK (1 << 15)
#define MCI_TXFIFOFULLMASK (1 << 16)
#define MCI_RXFIFOFULLMASK (1 << 17)
#define MCI_TXFIFOEMPTYMASK (1 << 18)
#define MCI_RXFIFOEMPTYMASK (1 << 19)
#define MCI_TXDATAAVLBLMASK (1 << 20)
#define MCI_RXDATAAVLBLMASK (1 << 21)
#define MCI_SDIOINTMASK (1 << 22)
#define MCI_PROGDONEMASK (1 << 23)
#define MCI_ATACMDCOMPLMASK (1 << 24)
#define MCI_SDIOINTOPERMASK (1 << 25)
#define MCI_CCSTIMEOUTMASK (1 << 26)
#define MMCIMASK1 0x040
#define MMCIFIFOCNT 0x044
#define MCICCSTIMER 0x058
#define MMCIFIFO 0x080 /* to 0x0bc */
#define MCI_IRQENABLE \
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
#define MCI_IRQ_PIO \
(MCI_RXDATAAVLBLMASK | MCI_TXDATAAVLBLMASK | MCI_RXFIFOEMPTYMASK | \
MCI_TXFIFOEMPTYMASK | MCI_RXFIFOFULLMASK | MCI_TXFIFOFULLMASK | \
MCI_RXFIFOHALFFULLMASK | MCI_TXFIFOHALFEMPTYMASK | \
MCI_RXACTIVEMASK | MCI_TXACTIVEMASK)
/*
* The size of the FIFO in bytes.
*/
#define MCI_FIFOSIZE (16*4)
#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
#define NR_SG 32
struct clk;
struct msmsdcc_nc_dmadata {
dmov_box cmd[NR_SG];
uint32_t cmdptr;
};
struct msmsdcc_dma_data {
struct msmsdcc_nc_dmadata *nc;
dma_addr_t nc_busaddr;
dma_addr_t cmd_busaddr;
dma_addr_t cmdptr_busaddr;
struct msm_dmov_cmd hdr;
enum dma_data_direction dir;
struct scatterlist *sg;
int num_ents;
int channel;
struct msmsdcc_host *host;
int busy; /* Set if DM is busy */
int active;
unsigned int result;
struct msm_dmov_errdata err;
};
struct msmsdcc_pio_data {
struct scatterlist *sg;
unsigned int sg_len;
unsigned int sg_off;
};
struct msmsdcc_curr_req {
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
unsigned int xfer_size; /* Total data size */
unsigned int xfer_remain; /* Bytes remaining to send */
unsigned int data_xfered; /* Bytes acked by BLKEND irq */
int got_dataend;
int user_pages;
};
struct msmsdcc_stats {
unsigned int reqs;
unsigned int cmds;
unsigned int cmdpoll_hits;
unsigned int cmdpoll_misses;
};
struct msmsdcc_host {
struct resource *cmd_irqres;
struct resource *memres;
struct resource *dmares;
void __iomem *base;
int pdev_id;
unsigned int stat_irq;
struct msmsdcc_curr_req curr;
struct mmc_host *mmc;
struct clk *clk; /* main MMC bus clock */
struct clk *pclk; /* SDCC peripheral bus clock */
unsigned int clks_on; /* set if clocks are enabled */
struct timer_list busclk_timer;
unsigned int eject; /* eject state */
spinlock_t lock;
unsigned int clk_rate; /* Current clock rate */
unsigned int pclk_rate;
u32 pwr;
u32 saved_irq0mask; /* MMCIMASK0 reg value */
struct msm_mmc_platform_data *plat;
struct timer_list timer;
unsigned int oldstat;
struct msmsdcc_dma_data dma;
struct msmsdcc_pio_data pio;
int cmdpoll;
struct msmsdcc_stats stats;
struct tasklet_struct dma_tlet;
/* Command parameters */
unsigned int cmd_timeout;
unsigned int cmd_pio_irqmask;
unsigned int cmd_datactrl;
struct mmc_command *cmd_cmd;
u32 cmd_c;
bool gpio_config_status;
bool prog_scan;
bool prog_enable;
};
#endif
...@@ -275,6 +275,7 @@ config BFIN_CFPCMCIA ...@@ -275,6 +275,7 @@ config BFIN_CFPCMCIA
config AT91_CF config AT91_CF
tristate "AT91 CompactFlash Controller" tristate "AT91 CompactFlash Controller"
depends on PCI
depends on PCMCIA && ARCH_AT91 depends on PCMCIA && ARCH_AT91
depends on !ARCH_MULTIPLATFORM depends on !ARCH_MULTIPLATFORM
help help
......
...@@ -317,13 +317,14 @@ static int at91_cf_probe(struct platform_device *pdev) ...@@ -317,13 +317,14 @@ static int at91_cf_probe(struct platform_device *pdev)
} else } else
cf->socket.pci_irq = nr_irqs + 1; cf->socket.pci_irq = nr_irqs + 1;
/* pcmcia layer only remaps "real" memory not iospace */ /*
cf->socket.io_offset = (unsigned long) devm_ioremap(&pdev->dev, * pcmcia layer only remaps "real" memory not iospace
cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); * io_offset is set to 0x10000 to avoid the check in static_find_io().
if (!cf->socket.io_offset) { * */
status = -ENXIO; cf->socket.io_offset = 0x10000;
status = pci_ioremap_io(0x10000, cf->phys_baseaddr + CF_IO_PHYS);
if (status)
goto fail0a; goto fail0a;
}
/* reserve chip-select regions */ /* reserve chip-select regions */
if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) { if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) {
......
#ifndef __MMC_MSM_SDCC_H
#define __MMC_MSM_SDCC_H
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
struct msm_mmc_gpio {
unsigned no;
const char *name;
};
struct msm_mmc_gpio_data {
struct msm_mmc_gpio *gpio;
u8 size;
};
struct msm_mmc_platform_data {
unsigned int ocr_mask; /* available voltages */
u32 (*translate_vdd)(struct device *, unsigned int);
unsigned int (*status)(struct device *);
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
struct msm_mmc_gpio_data *gpio_data;
void (*init_card)(struct mmc_card *card);
};
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册