Commit baaa68a9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ARM SoC updates from Arnd Bergmann:
 "SoC specific code is generally used for older platforms that don't
  (yet) use device tree to do the same things.

   - Support is added for i.MXRT10xx, a Cortex-M7 based microcontroller
     from NXP. At the moment this is still incomplete as other portions
     are merged through different trees.

   - Long abandoned support for running NOMMU ARMv4 or ARMv5 platforms
     gets removed, now the Arm NOMMU platforms are limited to the
     Cortex-M family of microcontrollers

   - Two old PXA boards get removed, along with corresponding driver
     bits.

   - Continued cleanup of the Intel IXP4xx platforms, removing some
     remnants of the old board files.

   - Minor Cleanups and fixes for Orion, PXA, MMP, Mstar, Samsung

   - CPU idle support for AT91

   - A system controller driver for Polarfire"

* tag 'arm-soc-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (29 commits)
  ARM: remove support for NOMMU ARMv4/v5
  ARM: PXA: fix up decompressor code
  soc: microchip: make mpfs_sys_controller_put static
  ARM: pxa: remove Intel Imote2 and Stargate 2 boards
  ARM: mmp: Fix failure to remove sram device
  ARM: mstar: Select ARM_ERRATA_814220
  soc: add microchip polarfire soc system controller
  ARM: at91: Kconfig: select PM_OPP
  ARM: at91: PM: add cpu idle support for sama7g5
  ARM: at91: ddr: fix typo to align with datasheet naming
  ARM: at91: ddr: align macro definitions
  ARM: at91: ddr: remove CONFIG_SOC_SAMA7 dependency
  ARM: ixp4xx: Convert to SPARSE_IRQ and P2V
  ARM: ixp4xx: Drop all common code
  ARM: ixp4xx: Drop custom DMA coherency and bouncing
  ARM: ixp4xx: Remove feature bit accessors
  net: ixp4xx_hss: Check features using syscon
  net: ixp4xx_eth: Drop platform data support
  soc: ixp4xx-npe: Access syscon regs using regmap
  soc: ixp4xx: Add features from regmap helper
  ...
parents 8ffa5709 2f618d5e
......@@ -17,13 +17,6 @@ description: |
child nodes, each representing a serial sub-node device. The mode setting
selects which particular function will be used.
Refer to next bindings documentation for information on protocol subnodes that
can exist under USI node:
[1] Documentation/devicetree/bindings/serial/samsung_uart.yaml
[2] Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
[3] Documentation/devicetree/bindings/spi/samsung,spi.yaml
properties:
$nodename:
pattern: "^usi@[0-9a-f]+$"
......@@ -71,10 +64,17 @@ properties:
This property is optional.
patternProperties:
# All other properties should be child nodes
"^(serial|spi|i2c)@[0-9a-f]+$":
"^i2c@[0-9a-f]+$":
$ref: /schemas/i2c/i2c-exynos5.yaml
description: Child node describing underlying I2C
"^serial@[0-9a-f]+$":
$ref: /schemas/serial/samsung_uart.yaml
description: Child node describing underlying UART/serial
"^spi@[0-9a-f]+$":
type: object
description: Child node describing underlying USI serial protocol
description: Child node describing underlying SPI
required:
- compatible
......
......@@ -2117,13 +2117,6 @@ F: Documentation/devicetree/bindings/arm/intel,keembay.yaml
F: arch/arm64/boot/dts/intel/keembay-evm.dts
F: arch/arm64/boot/dts/intel/keembay-soc.dtsi
ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
M: Jonathan Cameron <jic23@cam.ac.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-pxa/stargate2.c
F: drivers/pcmcia/pxa2xx_stargate2.c
ARM/INTEL XSC3 (MANZANO) ARM CORE
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......
......@@ -233,9 +233,6 @@ config ARCH_MAY_HAVE_PC_FDC
config ARCH_SUPPORTS_UPROBES
def_bool y
config ARCH_HAS_DMA_SET_COHERENT_MASK
bool
config GENERIC_ISA_DMA
bool
......@@ -279,7 +276,7 @@ config PHYS_OFFSET
hex "Physical address of main memory" if MMU
depends on !ARM_PATCH_PHYS_VIRT
default DRAM_BASE if !MMU
default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX
default 0x00000000 if ARCH_FOOTBRIDGE
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
default 0x30000000 if ARCH_S3C24XX
default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
......@@ -307,6 +304,17 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
config ARM_SINGLE_ARMV7M
def_bool !MMU
select ARM_NVIC
select AUTO_ZRELADDR
select TIMER_OF
select COMMON_CLK
select CPU_V7M
select NO_IOPORT_MAP
select SPARSE_IRQ
select USE_OF
config ARCH_MMAP_RND_BITS_MIN
default 8
......@@ -321,12 +329,11 @@ config ARCH_MMAP_RND_BITS_MAX
#
choice
prompt "ARM system type"
default ARM_SINGLE_ARMV7M if !MMU
default ARCH_MULTIPLATFORM if MMU
depends on MMU
default ARCH_MULTIPLATFORM
config ARCH_MULTIPLATFORM
bool "Allow multiple platforms to be selected"
depends on MMU
select ARCH_FLATMEM_ENABLE
select ARCH_SPARSEMEM_ENABLE
select ARCH_SELECT_MEMORY_MODEL
......@@ -340,18 +347,6 @@ config ARCH_MULTIPLATFORM
select SPARSE_IRQ
select USE_OF
config ARM_SINGLE_ARMV7M
bool "ARMv7-M based platforms (Cortex-M0/M3/M4)"
depends on !MMU
select ARM_NVIC
select AUTO_ZRELADDR
select TIMER_OF
select COMMON_CLK
select CPU_V7M
select NO_IOPORT_MAP
select SPARSE_IRQ
select USE_OF
config ARCH_EP93XX
bool "EP93xx-based"
select ARCH_SPARSEMEM_ENABLE
......@@ -370,7 +365,6 @@ config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
select FOOTBRIDGE
select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H
help
Support for systems based on the DC21285 companion chip
......@@ -378,7 +372,6 @@ config ARCH_FOOTBRIDGE
config ARCH_IOP32X
bool "IOP32x-based"
depends on MMU
select CPU_XSCALE
select GPIO_IOP
select GPIOLIB
......@@ -390,18 +383,15 @@ config ARCH_IOP32X
config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_PATCH_PHYS_VIRT
select CPU_XSCALE
select DMABOUNCE if PCI
select GPIO_IXP4XX
select GPIOLIB
select HAVE_PCI
select IXP4XX_IRQ
select IXP4XX_TIMER
# With the new PCI driver this is not needed
select NEED_MACH_IO_H if IXP4XX_PCI_LEGACY
select SPARSE_IRQ
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
help
......@@ -423,7 +413,6 @@ config ARCH_DOVE
config ARCH_PXA
bool "PXA2xx/PXA3xx-based"
depends on MMU
select ARCH_MTD_XIP
select ARM_CPU_SUSPEND if PM
select AUTO_ZRELADDR
......@@ -442,7 +431,6 @@ config ARCH_PXA
config ARCH_RPC
bool "RiscPC"
depends on MMU
depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000
select ARCH_ACORN
select ARCH_MAY_HAVE_PC_FDC
......@@ -497,7 +485,6 @@ config ARCH_S3C24XX
config ARCH_OMAP1
bool "TI OMAP1"
depends on MMU
select ARCH_OMAP
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
......
......@@ -41,8 +41,6 @@ CONFIG_MACH_EXEDA=y
CONFIG_MACH_CM_X300=y
CONFIG_MACH_CAPC7117=y
CONFIG_ARCH_GUMSTIX=y
CONFIG_MACH_INTELMOTE2=y
CONFIG_MACH_STARGATE2=y
CONFIG_MACH_XCEP=y
CONFIG_TRIZEPS_PXA=y
CONFIG_MACH_TRIZEPS4WL=y
......@@ -487,7 +485,6 @@ CONFIG_SND_SOC_ZYLONITE=m
CONFIG_SND_PXA2XX_SOC_HX4700=m
CONFIG_SND_PXA2XX_SOC_MAGICIAN=m
CONFIG_SND_PXA2XX_SOC_MIOA701=m
CONFIG_SND_PXA2XX_SOC_IMOTE2=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SIMPLE_CARD=m
......
......@@ -63,6 +63,7 @@ config SOC_SAMA7G5
select HAVE_AT91_GENERATED_CLK
select HAVE_AT91_SAM9X60_PLL
select HAVE_AT91_UTMI
select PM_OPP
select SOC_SAMA7
help
Select this if you are using one of Microchip's SAMA7G5 family SoC.
......
......@@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void)
at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}
static void sama7g5_standby(void)
{
int pwrtmg, ratio;
pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL);
ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO);
/*
* Place RAM into self-refresh after a maximum idle clocks. The maximum
* idle clocks is configured by bootloader in
* UDDRC_PWRMGT.SELFREF_TO_X32.
*/
writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN,
soc_pm.data.ramc[0] + UDDRC_PWRCTL);
/* Divide CPU clock by 16. */
writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO);
cpu_do_idle();
/* Restore previous configuration. */
writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO);
writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL);
}
struct ramc_info {
void (*idle)(void);
unsigned int memctrl;
......@@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = {
{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
{ .idle = sama7g5_standby, },
};
static const struct of_device_id ramc_ids[] __initconst = {
......@@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = {
{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
{ .compatible = "microchip,sama7g5-uddrc", },
{ .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], },
{ /*sentinel*/ }
};
......
......@@ -159,7 +159,7 @@ sr_ena_1:
/* Switch to self-refresh. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_ena_2:
......@@ -276,7 +276,7 @@ sr_dis_5:
/* Trigger self-refresh exit. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_dis_6:
......
......@@ -185,7 +185,6 @@ config ARCH_BCM_53573
config ARCH_BCM_63XX
bool "Broadcom BCM63xx DSL SoC"
depends on ARCH_MULTI_V7
depends on MMU
select ARCH_HAS_RESET_CONTROLLER
select ARM_ERRATA_754322
select ARM_ERRATA_764369 if SMP
......
......@@ -73,12 +73,12 @@ void __init dove_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-71.
*/
orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);
orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
}
......@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
/*
* Exynos3250 doesn't need to send smc command for secondary CPU boot
* because Exynos3250 removes WFE in secure mode.
*
* On Exynos5 devices the call is ignored by trustzone firmware.
*/
if (soc_is_exynos3250())
if (!soc_is_exynos4210() && !soc_is_exynos4412())
return 0;
/*
......
......@@ -21,32 +21,26 @@
* 0xf0000000 0x80000000 16MB ISA memory
*/
#ifdef CONFIG_MMU
#define MMU_IO(a, b) (a)
#else
#define MMU_IO(a, b) (b)
#endif
#define XBUS_SIZE 0x00100000
#define XBUS_BASE MMU_IO(0xff800000, 0x40000000)
#define XBUS_BASE 0xff800000
#define ARMCSR_SIZE 0x00100000
#define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000)
#define ARMCSR_BASE 0xfe000000
#define WFLUSH_SIZE 0x00100000
#define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000)
#define WFLUSH_BASE 0xfd000000
#define PCIIACK_SIZE 0x00100000
#define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000)
#define PCIIACK_BASE 0xfc000000
#define PCICFG1_SIZE 0x01000000
#define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000)
#define PCICFG1_BASE 0xfb000000
#define PCICFG0_SIZE 0x01000000
#define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000)
#define PCICFG0_BASE 0xfa000000
#define PCIMEM_SIZE 0x01000000
#define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000)
#define PCIMEM_BASE 0xf0000000
#define XBUS_CS2 0x40012000
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/mach-footbridge/include/mach/io.h
*
* Copyright (C) 1997-1999 Russell King
*
* Modifications:
* 06-12-1997 RMK Created.
* 07-04-1999 RMK Major cleanup
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
/*
* Translation of various i/o addresses to host addresses for !CONFIG_MMU
*/
#define PCIO_BASE 0x7c000000
#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
#endif
......@@ -227,6 +227,13 @@ config SOC_IMX7ULP
help
This enables support for Freescale i.MX7 Ultra Low Power processor.
config SOC_IMXRT
bool "i.MXRT support"
depends on ARM_SINGLE_ARMV7M
select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
help
This enables support for Freescale i.MXRT Crossover processor.
config SOC_VF610
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7
......
......@@ -63,6 +63,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
obj-$(CONFIG_SOC_VF610) += mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019
* Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
*/
#include <linux/kernel.h>
#include <asm/mach/arch.h>
#include <asm/v7m.h>
static const char *const imxrt_compat[] __initconst = {
"fsl,imxrt1050",
NULL
};
DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
.dt_compat = imxrt_compat,
.restart = armv7m_restart,
MACHINE_END
......@@ -42,24 +42,12 @@ config INTEGRATOR_IMPD1
allows ARM(R) Ltd PrimeCells to be developed and evaluated.
The IM-PD1 can be found on the Integrator/PP2 platform.
config INTEGRATOR_CM7TDMI
bool "Integrator/CM7TDMI core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4 && !MMU
select CPU_ARM7TDMI
config INTEGRATOR_CM720T
bool "Integrator/CM720T core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4T
select CPU_ARM720T
config INTEGRATOR_CM740T
bool "Integrator/CM740T core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4T && !MMU
select CPU_ARM740T
config INTEGRATOR_CM920T
bool "Integrator/CM920T core module"
depends on ARCH_INTEGRATOR_AP
......@@ -78,23 +66,6 @@ config INTEGRATOR_CM926EJS
depends on ARCH_MULTI_V5
select CPU_ARM926T
config INTEGRATOR_CM940T
bool "Integrator/CM940T core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4T && !MMU
select CPU_ARM940T
config INTEGRATOR_CM946ES
bool "Integrator/CM946E-S core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V5 && !MMU
select CPU_ARM946E
config INTEGRATOR_CM966ES
bool "Integrator/CM966E-S core module"
depends on ARCH_INTEGRATOR_AP
depends on BROKEN # no kernel support
config INTEGRATOR_CM10200E_REV0
bool "Integrator/CM10200E rev.0 core module"
depends on ARCH_INTEGRATOR_AP && n
......@@ -127,7 +98,7 @@ config INTEGRATOR_CM1136JFS
config ARCH_INTEGRATOR_CP
bool "Support Integrator/CP platform"
depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6)
depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
select ARM_TIMER_SP804
select SERIAL_AMBA_PL011 if TTY
select SERIAL_AMBA_PL011_CONSOLE if TTY
......@@ -135,12 +106,6 @@ config ARCH_INTEGRATOR_CP
help
Include support for the ARM(R) Integrator CP platform.
config INTEGRATOR_CT7T
bool "Integrator/CT7TD (ARM7TDMI) core tile"
depends on ARCH_INTEGRATOR_CP
depends on ARCH_MULTI_V4T && !MMU
select CPU_ARM7TDMI
config INTEGRATOR_CT926
bool "Integrator/CT926 (ARM926EJ-S) core tile"
depends on ARCH_INTEGRATOR_CP
......
......@@ -16,12 +16,7 @@
#define IO_START INTEGRATOR_HDR_BASE // PA of IO
/* macro to get at IO space when running virtually */
#ifdef CONFIG_MMU
#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
#else
#define IO_ADDRESS(x) (x)
#endif
#define __io_address(n) ((void __iomem *)IO_ADDRESS(n))
/*
......
......@@ -17,63 +17,6 @@ config MACH_IXP4XX_OF
help
Say 'Y' here to support Device Tree-based IXP4xx platforms.
config MACH_GATEWAY7001
bool "Gateway 7001"
depends on IXP4XX_PCI_LEGACY
help
Say 'Y' here if you want your kernel to support Gateway's
7001 Access Point. For more information on this platform,
see http://openwrt.org
config MACH_GORAMO_MLR
bool "GORAMO Multi Link Router"
depends on IXP4XX_PCI_LEGACY
help
Say 'Y' here if you want your kernel to support GORAMO
MultiLink router.
config ARCH_PRPMC1100
bool "PrPMC1100"
help
Say 'Y' here if you want your kernel to support the Motorola
PrPCM1100 Processor Mezanine Module. For more information on
this platform, see <file:Documentation/arm/ixp4xx.rst>.
comment "IXP4xx Options"
config IXP4XX_PCI_LEGACY
bool "IXP4xx legacy PCI driver support"
depends on PCI
help
Selects legacy PCI driver.
Not recommended for new development.
config IXP4XX_INDIRECT_PCI
bool "Use indirect PCI memory access"
depends on IXP4XX_PCI_LEGACY
help
IXP4xx provides two methods of accessing PCI memory space:
1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
To access PCI via this space, we simply ioremap() the BAR
into the kernel and we can use the standard read[bwl]/write[bwl]
macros. This is the preferred method due to speed but it
limits the system to just 64MB of PCI memory. This can be
problematic if using video cards and other memory-heavy devices.
2) If > 64MB of memory space is required, the IXP4xx can be
configured to use indirect registers to access the whole PCI
memory space. This currently allows for up to 1 GB (0x10000000
to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
is that every PCI access requires three local register accesses
plus a spinlock, but in some cases the performance hit is
acceptable. In addition, you cannot mmap() PCI devices in this
case due to the indirect nature of the PCI window.
By default, the direct method is used. Choose this option if you
need to use the indirect method instead. If you don't know
what you need, leave this option unselected.
endmenu
endif
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the linux kernel.
#
obj-pci-y :=
obj-pci-n :=
# Device tree platform
obj-pci-$(CONFIG_MACH_IXP4XX_OF) += ixp4xx-of.o
obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
obj-y += common.o
obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o
obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
obj-y += ixp4xx-of.o
// SPDX-License-Identifier: GPL-2.0-only
/*
* arch/arm/mach-ixp4xx/common-pci.c
*
* IXP4XX PCI routines for all platforms
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/export.h>
#include <asm/dma-mapping.h>
#include <asm/cputype.h>
#include <asm/irq.h>
#include <linux/sizes.h>
#include <asm/mach/pci.h>
#include <mach/hardware.h>
/*
* IXP4xx PCI read function is dependent on whether we are
* running A0 or B0 (AppleGate) silicon.
*/
int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
/*
* Base address for PCI register region
*/
unsigned long ixp4xx_pci_reg_base = 0;
/*
* PCI cfg an I/O routines are done by programming a
* command/byte enable register, and then read/writing
* the data from a data register. We need to ensure
* these transactions are atomic or we will end up
* with corrupt data on the bus or in a driver.
*/
static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock);
/*
* Read from PCI config space
*/
static void crp_read(u32 ad_cbe, u32 *data)
{
unsigned long flags;
raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_CRP_AD_CBE = ad_cbe;
*data = *PCI_CRP_RDATA;
raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
}
/*
* Write to PCI config space
*/
static void crp_write(u32 ad_cbe, u32 data)
{
unsigned long flags;
raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
*PCI_CRP_WDATA = data;
raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
}
static inline int check_master_abort(void)
{
/* check Master Abort bit after access */
unsigned long isr = *PCI_ISR;
if (isr & PCI_ISR_PFE) {
/* make sure the Master Abort bit is reset */
*PCI_ISR = PCI_ISR_PFE;
pr_debug("%s failed\n", __func__);
return 1;
}
return 0;
}
int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
{
unsigned long flags;
int retval = 0;
int i;
raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/*
* PCI workaround - only works if NP PCI space reads have
* no side effects!!! Read 8 times. last one will be good.
*/
for (i = 0; i < 8; i++) {
*PCI_NP_CBE = cmd;
*data = *PCI_NP_RDATA;
*data = *PCI_NP_RDATA;
}
if(check_master_abort())
retval = 1;
raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
{
unsigned long flags;
int retval = 0;
raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/* set up and execute the read */
*PCI_NP_CBE = cmd;
/* the result of the read is now in NP_RDATA */
*data = *PCI_NP_RDATA;
if(check_master_abort())
retval = 1;
raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
{
unsigned long flags;
int retval = 0;
raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/* set up the write */
*PCI_NP_CBE = cmd;
/* execute the write by writing to NP_WDATA */
*PCI_NP_WDATA = data;
if(check_master_abort())
retval = 1;
raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
{
u32 addr;
if (!bus_num) {
/* type 0 */
addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
(where & ~3);
} else {
/* type 1 */
addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
}
return addr;
}
/*
* Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
* 0 and 3 are not valid indexes...
*/
static u32 bytemask[] = {
/*0*/ 0,
/*1*/ 0xff,
/*2*/ 0xffff,
/*3*/ 0,
/*4*/ 0xffffffff,
};
static u32 local_byte_lane_enable_bits(u32 n, int size)
{
if (size == 1)
return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
if (size == 2)
return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
if (size == 4)
return 0;
return 0xffffffff;
}
static int local_read_config(int where, int size, u32 *value)
{
u32 n, data;
pr_debug("local_read_config from %d size %d\n", where, size);
n = where % 4;
crp_read(where & ~3, &data);
*value = (data >> (8*n)) & bytemask[size];
pr_debug("local_read_config read %#x\n", *value);
return PCIBIOS_SUCCESSFUL;
}
static int local_write_config(int where, int size, u32 value)
{
u32 n, byte_enables, data;
pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
n = where % 4;
byte_enables = local_byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
data = value << (8*n);
crp_write((where & ~3) | byte_enables, data);
return PCIBIOS_SUCCESSFUL;
}
static u32 byte_lane_enable_bits(u32 n, int size)
{
if (size == 1)
return (0xf & ~BIT(n)) << 4;
if (size == 2)
return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
if (size == 4)
return 0;
return 0xffffffff;
}
static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
u32 n, byte_enables, addr, data;
u8 bus_num = bus->number;
pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
*value = 0xffffffff;
n = where % 4;
byte_enables = byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
addr = ixp4xx_config_addr(bus_num, devfn, where);
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = (data >> (8*n)) & bytemask[size];
pr_debug("read_config_byte read %#x\n", *value);
return PCIBIOS_SUCCESSFUL;
}
static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
u32 n, byte_enables, addr, data;
u8 bus_num = bus->number;
pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
n = where % 4;
byte_enables = byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
addr = ixp4xx_config_addr(bus_num, devfn, where);
data = value << (8*n);
if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops ixp4xx_ops = {
.read = ixp4xx_pci_read_config,
.write = ixp4xx_pci_write_config,
};
/*
* PCI abort handler
*/
static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
u32 isr, status;
isr = *PCI_ISR;
local_read_config(PCI_STATUS, 2, &status);
pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
"status = %#x\n", addr, isr, status);
/* make sure the Master Abort bit is reset */
*PCI_ISR = PCI_ISR_PFE;
status |= PCI_STATUS_REC_MASTER_ABORT;
local_write_config(PCI_STATUS, 2, status);
/*
* If it was an imprecise abort, then we need to correct the
* return address to be _after_ the instruction.
*/
if (fsr & (1 << 10))
regs->ARM_pc += 4;
return 0;
}
void __init ixp4xx_pci_preinit(void)
{
unsigned long cpuid = read_cpuid_id();
#ifdef CONFIG_IXP4XX_INDIRECT_PCI
pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */
#else
pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */
#endif
/*
* Determine which PCI read method to use.
* Rev 0 IXP425 requires workaround.
*/
if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
printk("PCI: IXP42x A0 silicon detected - "
"PCI Non-Prefetch Workaround Enabled\n");
ixp4xx_pci_read = ixp4xx_pci_read_errata;
} else
ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
/* hook in our fault handler for PCI errors */
hook_fault_code(16+6, abort_handler, SIGBUS, 0,
"imprecise external abort");
pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
/*
* We use identity AHB->PCI address translation
* in the 0x48000000 to 0x4bffffff address space
*/
*PCI_PCIMEMBASE = 0x48494A4B;
/*
* We also use identity PCI->AHB address translation
* in 4 16MB BARs that begin at the physical memory start
*/
*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
((PHYS_OFFSET & 0xFF000000) >> 8) +
((PHYS_OFFSET & 0xFF000000) >> 16) +
((PHYS_OFFSET & 0xFF000000) >> 24) +
0x00010203;
if (*PCI_CSR & PCI_CSR_HOST) {
printk("PCI: IXP4xx is host\n");
pr_debug("setup BARs in controller\n");
/*
* We configure the PCI inbound memory windows to be
* 1:1 mapped to SDRAM
*/
local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
local_write_config(PCI_BASE_ADDRESS_3, 4,
PHYS_OFFSET + SZ_32M + SZ_16M);
/*
* Enable CSR window at 64 MiB to allow PCI masters
* to continue prefetching past 64 MiB boundary.
*/
local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
/*
* Enable the IO window to be way up high, at 0xfffffc00
*/
local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
} else {
printk("PCI: IXP4xx is target - No bus scan performed\n");
}
printk("PCI: IXP4xx Using %s access for memory space\n",
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
"direct"
#else
"indirect"
#endif
);
pr_debug("clear error bits in ISR\n");
*PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
/*
* Set Initialize Complete in PCI Control Register: allow IXP4XX to
* respond to PCI configuration cycles. Specify that the AHB bus is
* operating in big endian mode. Set up byte lane swapping between
* little-endian PCI and the big-endian AHB bus
*/
#ifdef __ARMEB__
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
#else
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
#endif
pr_debug("DONE\n");
}
int ixp4xx_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
if (nr >= 1)
return 0;
res = kcalloc(2, sizeof(*res), GFP_KERNEL);
if (res == NULL) {
/*
* If we're out of memory this early, something is wrong,
* so we might as well catch it here.
*/
panic("PCI: unable to allocate resources?\n");
}
local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
res[0].name = "PCI I/O Space";
res[0].start = 0x00000000;
res[0].end = 0x0000ffff;
res[0].flags = IORESOURCE_IO;
res[1].name = "PCI Memory Space";
res[1].start = PCIBIOS_MIN_MEM;
res[1].end = PCIBIOS_MAX_MEM;
res[1].flags = IORESOURCE_MEM;
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
return 1;
}
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);
/*
* arch/arm/mach-ixp4xx/common.c
*
* Generic code shared across all IXP4XX platforms
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2002 (c) Intel Corporation
* Copyright 2003-2004 (c) MontaVista, Software, Inc.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/cpu.h>
#include <linux/pci.h>
#include <linux/sched_clock.h>
#include <linux/soc/ixp4xx/cpu.h>
#include <linux/irqchip/irq-ixp4xx.h>
#include <linux/platform_data/timer-ixp4xx.h>
#include <linux/dma-map-ops.h>
#include <mach/udc.h>
#include <mach/hardware.h>
#include <linux/uaccess.h>
#include <asm/page.h>
#include <asm/exception.h>
#include <asm/irq.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include "irqs.h"
u32 ixp4xx_read_feature_bits(void)
{
u32 val = ~__raw_readl(IXP4XX_EXP_CFG2);
if (cpu_is_ixp42x_rev_a0())
return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
IXP4XX_FEATURE_AES);
if (cpu_is_ixp42x())
return val & IXP42X_FEATURE_MASK;
if (cpu_is_ixp43x())
return val & IXP43X_FEATURE_MASK;
return val & IXP46X_FEATURE_MASK;
}
EXPORT_SYMBOL(ixp4xx_read_feature_bits);
void ixp4xx_write_feature_bits(u32 value)
{
__raw_writel(~value, IXP4XX_EXP_CFG2);
}
EXPORT_SYMBOL(ixp4xx_write_feature_bits);
#define IXP4XX_TIMER_FREQ 66666000
/*************************************************************************
* IXP4xx chipset I/O mapping
*************************************************************************/
static struct map_desc ixp4xx_io_desc[] __initdata = {
{ /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
.virtual = (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
.length = IXP4XX_PERIPHERAL_REGION_SIZE,
.type = MT_DEVICE
}, { /* Expansion Bus Config Registers */
.virtual = (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
.length = IXP4XX_EXP_CFG_REGION_SIZE,
.type = MT_DEVICE
}, { /* PCI Registers */
.virtual = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
.length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE
},
};
void __init ixp4xx_map_io(void)
{
iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
}
void __init ixp4xx_init_irq(void)
{
/*
* ixp4xx does not implement the XScale PWRMODE register
* so it must not call cpu_do_idle().
*/
cpu_idle_poll_ctrl(true);
ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
(cpu_is_ixp46x() || cpu_is_ixp43x()));
}
void __init ixp4xx_timer_init(void)
{
return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
IRQ_IXP4XX_TIMER1,
IXP4XX_TIMER_FREQ);
}
static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
{
memcpy(&ixp4xx_udc_info, info, sizeof *info);
}
static struct resource ixp4xx_udc_resources[] = {
[0] = {
.start = 0xc800b000,
.end = 0xc800bfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IXP4XX_USB,
.end = IRQ_IXP4XX_USB,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ixp4xx_gpio_resource[] = {
{
.start = IXP4XX_GPIO_BASE_PHYS,
.end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ixp4xx_gpio_device = {
.name = "ixp4xx-gpio",
.id = -1,
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.resource = ixp4xx_gpio_resource,
.num_resources = ARRAY_SIZE(ixp4xx_gpio_resource),
};
/*
* USB device controller. The IXP4xx uses the same controller as PXA25X,
* so we just use the same device.
*/
static struct platform_device ixp4xx_udc_device = {
.name = "pxa25x-udc",
.id = -1,
.num_resources = 2,
.resource = ixp4xx_udc_resources,
.dev = {
.platform_data = &ixp4xx_udc_info,
},
};
static struct resource ixp4xx_npe_resources[] = {
{
.start = IXP4XX_NPEA_BASE_PHYS,
.end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_NPEB_BASE_PHYS,
.end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_NPEC_BASE_PHYS,
.end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ixp4xx_npe_device = {
.name = "ixp4xx-npe",
.id = -1,
.num_resources = ARRAY_SIZE(ixp4xx_npe_resources),
.resource = ixp4xx_npe_resources,
};
static struct resource ixp4xx_qmgr_resources[] = {
{
.start = IXP4XX_QMGR_BASE_PHYS,
.end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_IXP4XX_QM1,
.end = IRQ_IXP4XX_QM1,
.flags = IORESOURCE_IRQ,
},
{
.start = IRQ_IXP4XX_QM2,
.end = IRQ_IXP4XX_QM2,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device ixp4xx_qmgr_device = {
.name = "ixp4xx-qmgr",
.id = -1,
.num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources),
.resource = ixp4xx_qmgr_resources,
};
static struct platform_device *ixp4xx_devices[] __initdata = {
&ixp4xx_npe_device,
&ixp4xx_qmgr_device,
&ixp4xx_gpio_device,
&ixp4xx_udc_device,
};
static struct resource ixp46x_i2c_resources[] = {
[0] = {
.start = 0xc8011000,
.end = 0xc801101c,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IXP4XX_I2C,
.end = IRQ_IXP4XX_I2C,
.flags = IORESOURCE_IRQ
}
};
/* A single 32-bit register on IXP46x */
#define IXP4XX_HWRANDOM_BASE_PHYS 0x70002100
static struct resource ixp46x_hwrandom_resource[] = {
{
.start = IXP4XX_HWRANDOM_BASE_PHYS,
.end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ixp46x_hwrandom_device = {
.name = "ixp4xx-hwrandom",
.id = -1,
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.resource = ixp46x_hwrandom_resource,
.num_resources = ARRAY_SIZE(ixp46x_hwrandom_resource),
};
/*
* I2C controller. The IXP46x uses the same block as the IOP3xx, so
* we just use the same device name.
*/
static struct platform_device ixp46x_i2c_controller = {
.name = "IOP3xx-I2C",
.id = 0,
.num_resources = 2,
.resource = ixp46x_i2c_resources
};
static struct resource ixp46x_ptp_resources[] = {
DEFINE_RES_MEM(IXP4XX_TIMESYNC_BASE_PHYS, SZ_4K),
DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO8, "master"),
DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO7, "slave"),
};
static struct platform_device ixp46x_ptp = {
.name = "ptp-ixp46x",
.id = -1,
.resource = ixp46x_ptp_resources,
.num_resources = ARRAY_SIZE(ixp46x_ptp_resources),
};
static struct platform_device *ixp46x_devices[] __initdata = {
&ixp46x_hwrandom_device,
&ixp46x_i2c_controller,
&ixp46x_ptp,
};
unsigned long ixp4xx_exp_bus_size;
EXPORT_SYMBOL(ixp4xx_exp_bus_size);
static struct platform_device_info ixp_dev_info __initdata = {
.name = "ixp4xx_crypto",
.id = 0,
.dma_mask = DMA_BIT_MASK(32),
};
static int __init ixp_crypto_register(void)
{
struct platform_device *pdev;
if (!(~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
printk(KERN_ERR "ixp_crypto: No HW crypto available\n");
return -ENODEV;
}
pdev = platform_device_register_full(&ixp_dev_info);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
return 0;
}
void __init ixp4xx_sys_init(void)
{
ixp4xx_exp_bus_size = SZ_16M;
platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
if (IS_ENABLED(CONFIG_CRYPTO_DEV_IXP4XX))
ixp_crypto_register();
if (cpu_is_ixp46x()) {
int region;
platform_add_devices(ixp46x_devices,
ARRAY_SIZE(ixp46x_devices));
for (region = 0; region < 7; region++) {
if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
ixp4xx_exp_bus_size = SZ_32M;
break;
}
}
}
printk("IXP4xx: Using %luMiB expansion bus window size\n",
ixp4xx_exp_bus_size >> 20);
}
unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
EXPORT_SYMBOL(ixp4xx_timer_freq);
void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
{
if (mode == REBOOT_SOFT) {
/* Jump into ROM at address 0 */
soft_restart(0);
} else {
/* Use on-chip reset capability */
/* set the "key" register to enable access to
* "timer" and "enable" registers
*/
*IXP4XX_OSWK = IXP4XX_WDT_KEY;
/* write 0 to the timer register for an immediate reset */
*IXP4XX_OSWT = 0;
*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
}
}
#ifdef CONFIG_PCI
static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
{
return (dma_addr + size) > SZ_64M;
}
static int ixp4xx_platform_notify_remove(struct device *dev)
{
if (dev_is_pci(dev))
dmabounce_unregister_dev(dev);
return 0;
}
#endif
/*
* Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
*/
static int ixp4xx_platform_notify(struct device *dev)
{
dev->dma_mask = &dev->coherent_dma_mask;
#ifdef CONFIG_PCI
if (dev_is_pci(dev)) {
dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
return 0;
}
#endif
dev->coherent_dma_mask = DMA_BIT_MASK(32);
return 0;
}
int dma_set_coherent_mask(struct device *dev, u64 mask)
{
if (dev_is_pci(dev))
mask &= DMA_BIT_MASK(28); /* 64 MB */
if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
dev->coherent_dma_mask = mask;
return 0;
}
return -EIO; /* device wanted sub-64MB mask */
}
EXPORT_SYMBOL(dma_set_coherent_mask);
#ifdef CONFIG_IXP4XX_INDIRECT_PCI
/*
* In the case of using indirect PCI, we simply return the actual PCI
* address and our read/write implementation use that to drive the
* access registers. If something outside of PCI is ioremap'd, we
* fallback to the default.
*/
static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
unsigned int mtype, void *caller)
{
if (!is_pci_memory(addr))
return __arm_ioremap_caller(addr, size, mtype, caller);
return (void __iomem *)addr;
}
static void ixp4xx_iounmap(volatile void __iomem *addr)
{
if (!is_pci_memory((__force u32)addr))
__iounmap(addr);
}
#endif
void __init ixp4xx_init_early(void)
{
platform_notify = ixp4xx_platform_notify;
#ifdef CONFIG_PCI
platform_notify_remove = ixp4xx_platform_notify_remove;
#endif
#ifdef CONFIG_IXP4XX_INDIRECT_PCI
arch_ioremap_caller = ixp4xx_ioremap_caller;
arch_iounmap = ixp4xx_iounmap;
#endif
}
// SPDX-License-Identifier: GPL-2.0-only
/*
* arch/arch/mach-ixp4xx/gateway7001-pci.c
*
* PCI setup routines for Gateway 7001
*
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
*
* based on coyote-pci.c:
* Copyright (C) 2002 Jungo Software Technologies.
* Copyright (C) 2003 MontaVista Softwrae, Inc.
*
* Maintainer: Imre Kaloz <kaloz@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
#include "irqs.h"
void __init gateway7001_pci_preinit(void)
{
irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot,
u8 pin)
{
if (slot == 1)
return IRQ_IXP4XX_GPIO11;
else if (slot == 2)
return IRQ_IXP4XX_GPIO10;
else return -1;
}
struct hw_pci gateway7001_pci __initdata = {
.nr_controllers = 1,
.ops = &ixp4xx_ops,
.preinit = gateway7001_pci_preinit,
.setup = ixp4xx_setup,
.map_irq = gateway7001_map_irq,
};
int __init gateway7001_pci_init(void)
{
if (machine_is_gateway7001())
pci_common_init(&gateway7001_pci);
return 0;
}
subsys_initcall(gateway7001_pci_init);
// SPDX-License-Identifier: GPL-2.0
/*
* arch/arm/mach-ixp4xx/gateway7001-setup.c
*
* Board setup for the Gateway 7001 board
*
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
*
* based on coyote-setup.c:
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Imre Kaloz <Kaloz@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include "irqs.h"
static struct flash_platform_data gateway7001_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource gateway7001_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device gateway7001_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &gateway7001_flash_data,
},
.num_resources = 1,
.resource = &gateway7001_flash_resource,
};
static struct resource gateway7001_uart_resource = {
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
};
static struct plat_serial8250_port gateway7001_uart_data[] = {
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ },
};
static struct platform_device gateway7001_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = gateway7001_uart_data,
},
.num_resources = 1,
.resource = &gateway7001_uart_resource,
};
static struct platform_device *gateway7001_devices[] __initdata = {
&gateway7001_flash,
&gateway7001_uart
};
static void __init gateway7001_init(void)
{
ixp4xx_sys_init();
gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
}
#ifdef CONFIG_MACH_GATEWAY7001
MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
.map_io = ixp4xx_map_io,
.init_early = ixp4xx_init_early,
.init_irq = ixp4xx_init_irq,
.init_time = ixp4xx_timer_init,
.atag_offset = 0x100,
.init_machine = gateway7001_init,
#if defined(CONFIG_PCI)
.dma_zone_size = SZ_64M,
#endif
.restart = ixp4xx_restart,
MACHINE_END
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* Goramo MultiLink router platform code
* Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/hdlc.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/platform_data/wan_ixp4xx_hss.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/pci.h>
#include <asm/system_info.h>
#include "irqs.h"
#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
#define SLOT_MPCI 0x0D /* IDSEL = AD19 */
#define SLOT_NEC 0x0E /* IDSEL = AD18 */
/* GPIO lines */
#define GPIO_SCL 0
#define GPIO_SDA 1
#define GPIO_STR 2
#define GPIO_IRQ_NEC 3
#define GPIO_IRQ_ETHA 4
#define GPIO_IRQ_ETHB 5
#define GPIO_HSS0_DCD_N 6
#define GPIO_HSS1_DCD_N 7
#define GPIO_UART0_DCD 8
#define GPIO_UART1_DCD 9
#define GPIO_HSS0_CTS_N 10
#define GPIO_HSS1_CTS_N 11
#define GPIO_IRQ_MPCI 12
#define GPIO_HSS1_RTS_N 13
#define GPIO_HSS0_RTS_N 14
/* GPIO15 is not connected */
/* Control outputs from 74HC4094 */
#define CONTROL_HSS0_CLK_INT 0
#define CONTROL_HSS1_CLK_INT 1
#define CONTROL_HSS0_DTR_N 2
#define CONTROL_HSS1_DTR_N 3
#define CONTROL_EXT 4
#define CONTROL_AUTO_RESET 5
#define CONTROL_PCI_RESET_N 6
#define CONTROL_EEPROM_WC_N 7
/* offsets from start of flash ROM = 0x50000000 */
#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */
#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */
#define CFG_REV 0x4C /* u32 */
#define CFG_SDRAM_SIZE 0x50 /* u32 */
#define CFG_SDRAM_CONF 0x54 /* u32 */
#define CFG_SDRAM_MODE 0x58 /* u32 */
#define CFG_SDRAM_REFRESH 0x5C /* u32 */
#define CFG_HW_BITS 0x60 /* u32 */
#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
#define CFG_HW_HAS_PCI_SLOT 0x00000008
#define CFG_HW_HAS_ETH0 0x00000010
#define CFG_HW_HAS_ETH1 0x00000020
#define CFG_HW_HAS_HSS0 0x00000040
#define CFG_HW_HAS_HSS1 0x00000080
#define CFG_HW_HAS_UART0 0x00000100
#define CFG_HW_HAS_UART1 0x00000200
#define CFG_HW_HAS_EEPROM 0x00000400
#define FLASH_CMD_READ_ARRAY 0xFF
#define FLASH_CMD_READ_ID 0x90
#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */
static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;
static u8 control_value;
/*
* FIXME: this is reimplementing I2C bit-bangining. Move this
* over to using driver/i2c/busses/i2c-gpio.c like all other boards
* and register proper I2C device(s) on the bus for this. (See
* other IXP4xx boards for examples.)
*/
static void set_scl(u8 value)
{
gpio_set_value(GPIO_SCL, !!value);
udelay(3);
}
static void set_sda(u8 value)
{
gpio_set_value(GPIO_SDA, !!value);
udelay(3);
}
static void set_str(u8 value)
{
gpio_set_value(GPIO_STR, !!value);
udelay(3);
}
static inline void set_control(int line, int value)
{
if (value)
control_value |= (1 << line);
else
control_value &= ~(1 << line);
}
static void output_control(void)
{
int i;
gpio_direction_output(GPIO_SCL, 1);
gpio_direction_output(GPIO_SDA, 1);
for (i = 0; i < 8; i++) {
set_scl(0);
set_sda(control_value & (0x80 >> i)); /* MSB first */
set_scl(1); /* active edge */
}
set_str(1);
set_str(0);
set_scl(0);
set_sda(1); /* Be ready for START */
set_scl(1);
}
static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
static int hss_set_clock(int port, unsigned int clock_type)
{
int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
switch (clock_type) {
case CLOCK_DEFAULT:
case CLOCK_EXT:
set_control(ctrl_int, 0);
output_control();
return CLOCK_EXT;
case CLOCK_INT:
set_control(ctrl_int, 1);
output_control();
return CLOCK_INT;
default:
return -EINVAL;
}
}
static irqreturn_t hss_dcd_irq(int irq, void *pdev)
{
int port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
set_carrier_cb_tab[port](pdev, !i);
return IRQ_HANDLED;
}
static int hss_open(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier))
{
int i, irq;
if (!port)
irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
else
irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
set_carrier_cb(pdev, !i);
set_carrier_cb_tab[!!port] = set_carrier_cb;
if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
irq, i);
return i;
}
set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
output_control();
gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
return 0;
}
static void hss_close(int port, void *pdev)
{
free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
output_control();
gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
}
/* Flash memory */
static struct flash_platform_data flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device device_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = { .platform_data = &flash_data },
.num_resources = 1,
.resource = &flash_resource,
};
/* IXP425 2 UART ports */
static struct resource uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char __iomem *)IXP4XX_UART1_BASE_VIRT +
REG_OFFSET,
.irq = IRQ_IXP4XX_UART1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char __iomem *)IXP4XX_UART2_BASE_VIRT +
REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ },
};
static struct platform_device device_uarts = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = uart_data,
.num_resources = 2,
.resource = uart_resources,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource eth_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource eth_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info eth_plat[] = {
{
.phy = 0,
.rxq = 3,
.txreadyq = 32,
}, {
.phy = 1,
.rxq = 4,
.txreadyq = 33,
}
};
static struct platform_device device_eth_tab[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = eth_plat,
.num_resources = ARRAY_SIZE(eth_npeb_resources),
.resource = eth_npeb_resources,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = eth_plat + 1,
.num_resources = ARRAY_SIZE(eth_npec_resources),
.resource = eth_npec_resources,
}
};
/* IXP425 2 synchronous serial ports */
static struct hss_plat_info hss_plat[] = {
{
.set_clock = hss_set_clock,
.open = hss_open,
.close = hss_close,
.txreadyq = 34,
}, {
.set_clock = hss_set_clock,
.open = hss_open,
.close = hss_close,
.txreadyq = 35,
}
};
static struct platform_device device_hss_tab[] = {
{
.name = "ixp4xx_hss",
.id = 0,
.dev.platform_data = hss_plat,
}, {
.name = "ixp4xx_hss",
.id = 1,
.dev.platform_data = hss_plat + 1,
}
};
static struct platform_device *device_tab[7] __initdata = {
&device_flash, /* index 0 */
};
static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
{
#ifdef __ARMEB__
return __raw_readb(flash + addr);
#else
return __raw_readb(flash + (addr ^ 3));
#endif
}
static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
{
#ifdef __ARMEB__
return __raw_readw(flash + addr);
#else
return __raw_readw(flash + (addr ^ 2));
#endif
}
static void __init gmlr_init(void)
{
u8 __iomem *flash;
int i, devices = 1; /* flash */
ixp4xx_sys_init();
if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
printk(KERN_ERR "goramo-mlr: unable to access system"
" configuration data\n");
else {
system_rev = __raw_readl(flash + CFG_REV);
hw_bits = __raw_readl(flash + CFG_HW_BITS);
for (i = 0; i < ETH_ALEN; i++) {
eth_plat[0].hwaddr[i] =
flash_readb(flash, CFG_ETH0_ADDRESS + i);
eth_plat[1].hwaddr[i] =
flash_readb(flash, CFG_ETH1_ADDRESS + i);
}
__raw_writew(FLASH_CMD_READ_ID, flash);
system_serial_high = flash_readw(flash, FLASH_SER_OFF);
system_serial_high <<= 16;
system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
system_serial_low <<= 16;
system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
__raw_writew(FLASH_CMD_READ_ARRAY, flash);
iounmap(flash);
}
switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
case CFG_HW_HAS_UART0:
memset(&uart_data[1], 0, sizeof(uart_data[1]));
device_uarts.num_resources = 1;
break;
case CFG_HW_HAS_UART1:
device_uarts.dev.platform_data = &uart_data[1];
device_uarts.resource = &uart_resources[1];
device_uarts.num_resources = 1;
break;
}
if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
device_tab[devices++] = &device_uarts; /* max index 1 */
if (hw_bits & CFG_HW_HAS_ETH0)
device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
if (hw_bits & CFG_HW_HAS_ETH1)
device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
if (hw_bits & CFG_HW_HAS_HSS0)
device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
if (hw_bits & CFG_HW_HAS_HSS1)
device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
hss_plat[0].timer_freq = ixp4xx_timer_freq;
hss_plat[1].timer_freq = ixp4xx_timer_freq;
gpio_request(GPIO_SCL, "SCL/clock");
gpio_request(GPIO_SDA, "SDA/data");
gpio_request(GPIO_STR, "strobe");
gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
gpio_direction_output(GPIO_SCL, 1);
gpio_direction_output(GPIO_SDA, 1);
gpio_direction_output(GPIO_STR, 0);
gpio_direction_output(GPIO_HSS0_RTS_N, 1);
gpio_direction_output(GPIO_HSS1_RTS_N, 1);
gpio_direction_input(GPIO_HSS0_DCD_N);
gpio_direction_input(GPIO_HSS1_DCD_N);
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
set_control(CONTROL_HSS0_DTR_N, 1);
set_control(CONTROL_HSS1_DTR_N, 1);
set_control(CONTROL_EEPROM_WC_N, 1);
set_control(CONTROL_PCI_RESET_N, 1);
output_control();
msleep(1); /* Wait for PCI devices to initialize */
flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
platform_add_devices(device_tab, devices);
}
#ifdef CONFIG_PCI
static void __init gmlr_pci_preinit(void)
{
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static void __init gmlr_pci_postinit(void)
{
if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
(hw_bits & CFG_HW_USB_PORTS) < 5) {
/* need to adjust number of USB ports on NEC chip */
u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
value &= ~7;
value |= (hw_bits & CFG_HW_USB_PORTS);
ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
}
}
}
static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
switch(slot) {
case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
case SLOT_ETHB: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
case SLOT_NEC: return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
default: return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
}
}
static struct hw_pci gmlr_hw_pci __initdata = {
.nr_controllers = 1,
.ops = &ixp4xx_ops,
.preinit = gmlr_pci_preinit,
.postinit = gmlr_pci_postinit,
.setup = ixp4xx_setup,
.map_irq = gmlr_map_irq,
};
static int __init gmlr_pci_init(void)
{
if (machine_is_goramo_mlr() &&
(hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
pci_common_init(&gmlr_hw_pci);
return 0;
}
subsys_initcall(gmlr_pci_init);
#endif /* CONFIG_PCI */
MACHINE_START(GORAMO_MLR, "MultiLink")
/* Maintainer: Krzysztof Halasa */
.map_io = ixp4xx_map_io,
.init_early = ixp4xx_init_early,
.init_irq = ixp4xx_init_irq,
.init_time = ixp4xx_timer_init,
.atag_offset = 0x100,
.init_machine = gmlr_init,
#if defined(CONFIG_PCI)
.dma_zone_size = SZ_64M,
#endif
.restart = ixp4xx_restart,
MACHINE_END
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/mach-ixp4xx/include/mach/hardware.h
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*/
/*
* Hardware definitions for IXP4xx based systems
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#define __ASM_ARCH_HARDWARE_H__
#ifdef CONFIG_IXP4XX_INDIRECT_PCI
#define PCIBIOS_MAX_MEM 0x4FFFFFFF
#else
#define PCIBIOS_MAX_MEM 0x4BFFFFFF
#endif
/* Register locations and bits */
#include "ixp4xx-regs.h"
#ifndef __ASSEMBLER__
#include <linux/soc/ixp4xx/cpu.h>
#endif
/* Platform helper functions and definitions */
#include "platform.h"
#endif /* _ASM_ARCH_HARDWARE_H */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/mach-ixp4xx/include/mach/io.h
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002-2005 MontaVista Software, Inc.
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#include <linux/bitops.h>
#include <mach/hardware.h>
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
/*
* IXP4xx provides two methods of accessing PCI memory space:
*
* 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
* To access PCI via this space, we simply ioremap() the BAR
* into the kernel and we can use the standard read[bwl]/write[bwl]
* macros. This is the preffered method due to speed but it
* limits the system to just 64MB of PCI memory. This can be
* problematic if using video cards and other memory-heavy targets.
*
* 2) If > 64MB of memory space is required, the IXP4xx can use indirect
* registers to access the whole 4 GB of PCI memory space (as we do below
* for I/O transactions). This allows currently for up to 1 GB (0x10000000
* to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
* every PCI access requires three local register accesses plus a spinlock,
* but in some cases the performance hit is acceptable. In addition, you
* cannot mmap() PCI devices in this case.
*/
#ifdef CONFIG_IXP4XX_INDIRECT_PCI
/*
* In the case of using indirect PCI, we simply return the actual PCI
* address and our read/write implementation use that to drive the
* access registers. If something outside of PCI is ioremap'd, we
* fallback to the default.
*/
extern unsigned long pcibios_min_mem;
static inline int is_pci_memory(u32 addr)
{
return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
}
#define writeb(v, p) __indirect_writeb(v, p)
#define writew(v, p) __indirect_writew(v, p)
#define writel(v, p) __indirect_writel(v, p)
#define writeb_relaxed(v, p) __indirect_writeb(v, p)
#define writew_relaxed(v, p) __indirect_writew(v, p)
#define writel_relaxed(v, p) __indirect_writel(v, p)
#define writesb(p, v, l) __indirect_writesb(p, v, l)
#define writesw(p, v, l) __indirect_writesw(p, v, l)
#define writesl(p, v, l) __indirect_writesl(p, v, l)
#define readb(p) __indirect_readb(p)
#define readw(p) __indirect_readw(p)
#define readl(p) __indirect_readl(p)
#define readb_relaxed(p) __indirect_readb(p)
#define readw_relaxed(p) __indirect_readw(p)
#define readl_relaxed(p) __indirect_readl(p)
#define readsb(p, v, l) __indirect_readsb(p, v, l)
#define readsw(p, v, l) __indirect_readsw(p, v, l)
#define readsl(p, v, l) __indirect_readsl(p, v, l)
static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (!is_pci_memory(addr)) {
__raw_writeb(value, p);
return;
}
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
}
static inline void __indirect_writesb(volatile void __iomem *bus_addr,
const void *p, int count)
{
const u8 *vaddr = p;
while (count--)
writeb(*vaddr++, bus_addr);
}
static inline void __indirect_writew(u16 value, volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (!is_pci_memory(addr)) {
__raw_writew(value, p);
return;
}
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
}
static inline void __indirect_writesw(volatile void __iomem *bus_addr,
const void *p, int count)
{
const u16 *vaddr = p;
while (count--)
writew(*vaddr++, bus_addr);
}
static inline void __indirect_writel(u32 value, volatile void __iomem *p)
{
u32 addr = (__force u32)p;
if (!is_pci_memory(addr)) {
__raw_writel(value, p);
return;
}
ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
}
static inline void __indirect_writesl(volatile void __iomem *bus_addr,
const void *p, int count)
{
const u32 *vaddr = p;
while (count--)
writel(*vaddr++, bus_addr);
}
static inline u8 __indirect_readb(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (!is_pci_memory(addr))
return __raw_readb(p);
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
return 0xff;
return data >> (8*n);
}
static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
void *p, u32 count)
{
u8 *vaddr = p;
while (count--)
*vaddr++ = readb(bus_addr);
}
static inline u16 __indirect_readw(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (!is_pci_memory(addr))
return __raw_readw(p);
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
return 0xffff;
return data>>(8*n);
}
static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
void *p, u32 count)
{
u16 *vaddr = p;
while (count--)
*vaddr++ = readw(bus_addr);
}
static inline u32 __indirect_readl(const volatile void __iomem *p)
{
u32 addr = (__force u32)p;
u32 data;
if (!is_pci_memory(addr))
return __raw_readl(p);
if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
return 0xffffffff;
return data;
}
static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
void *p, u32 count)
{
u32 *vaddr = p;
while (count--)
*vaddr++ = readl(bus_addr);
}
/*
* We can use the built-in functions b/c they end up calling writeb/readb
*/
#define memset_io(c,v,l) _memset_io((c),(v),(l))
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l))
#define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l))
#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
#ifndef CONFIG_PCI
#define __io(v) __typesafe_io(v)
#else
/*
* IXP4xx does not have a transparent cpu -> PCI I/O translation
* window. Instead, it has a set of registers that must be tweaked
* with the proper byte lanes, command types, and address for the
* transaction. This means that we need to override the default
* I/O functions.
*/
#define outb outb
static inline void outb(u8 value, u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
}
#define outsb outsb
static inline void outsb(u32 io_addr, const void *p, u32 count)
{
const u8 *vaddr = p;
while (count--)
outb(*vaddr++, io_addr);
}
#define outw outw
static inline void outw(u16 value, u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
}
#define outsw outsw
static inline void outsw(u32 io_addr, const void *p, u32 count)
{
const u16 *vaddr = p;
while (count--)
outw(cpu_to_le16(*vaddr++), io_addr);
}
#define outl outl
static inline void outl(u32 value, u32 addr)
{
ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
}
#define outsl outsl
static inline void outsl(u32 io_addr, const void *p, u32 count)
{
const u32 *vaddr = p;
while (count--)
outl(cpu_to_le32(*vaddr++), io_addr);
}
#define inb inb
static inline u8 inb(u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
return 0xff;
return data >> (8*n);
}
#define insb insb
static inline void insb(u32 io_addr, void *p, u32 count)
{
u8 *vaddr = p;
while (count--)
*vaddr++ = inb(io_addr);
}
#define inw inw
static inline u16 inw(u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
return 0xffff;
return data>>(8*n);
}
#define insw insw
static inline void insw(u32 io_addr, void *p, u32 count)
{
u16 *vaddr = p;
while (count--)
*vaddr++ = le16_to_cpu(inw(io_addr));
}
#define inl inl
static inline u32 inl(u32 addr)
{
u32 data;
if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
return 0xffffffff;
return data;
}
#define insl insl
static inline void insl(u32 io_addr, void *p, u32 count)
{
u32 *vaddr = p;
while (count--)
*vaddr++ = le32_to_cpu(inl(io_addr));
}
#define PIO_OFFSET 0x10000UL
#define PIO_MASK 0x0ffffUL
#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
#define ioread8(p) ioread8(p)
static inline u8 ioread8(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)inb(port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return (unsigned int)__raw_readb(addr);
#else
return (unsigned int)__indirect_readb(addr);
#endif
}
#define ioread8_rep(p, v, c) ioread8_rep(p, v, c)
static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
insb(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsb(addr, vaddr, count);
#else
__indirect_readsb(addr, vaddr, count);
#endif
}
#define ioread16(p) ioread16(p)
static inline u16 ioread16(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)inw(port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le16_to_cpu((__force __le16)__raw_readw(addr));
#else
return (unsigned int)__indirect_readw(addr);
#endif
}
#define ioread16_rep(p, v, c) ioread16_rep(p, v, c)
static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
insw(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsw(addr, vaddr, count);
#else
__indirect_readsw(addr, vaddr, count);
#endif
}
#define ioread32(p) ioread32(p)
static inline u32 ioread32(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)inl(port & PIO_MASK);
else {
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le32_to_cpu((__force __le32)__raw_readl(addr));
#else
return (unsigned int)__indirect_readl(addr);
#endif
}
}
#define ioread32_rep(p, v, c) ioread32_rep(p, v, c)
static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
insl(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsl(addr, vaddr, count);
#else
__indirect_readsl(addr, vaddr, count);
#endif
}
#define iowrite8(v, p) iowrite8(v, p)
static inline void iowrite8(u8 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outb(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writeb(value, addr);
#else
__indirect_writeb(value, addr);
#endif
}
#define iowrite8_rep(p, v, c) iowrite8_rep(p, v, c)
static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outsb(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesb(addr, vaddr, count);
#else
__indirect_writesb(addr, vaddr, count);
#endif
}
#define iowrite16(v, p) iowrite16(v, p)
static inline void iowrite16(u16 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outw(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writew(cpu_to_le16(value), addr);
#else
__indirect_writew(value, addr);
#endif
}
#define iowrite16_rep(p, v, c) iowrite16_rep(p, v, c)
static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outsw(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesw(addr, vaddr, count);
#else
__indirect_writesw(addr, vaddr, count);
#endif
}
#define iowrite32(v, p) iowrite32(v, p)
static inline void iowrite32(u32 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outl(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writel((u32 __force)cpu_to_le32(value), addr);
#else
__indirect_writel(value, addr);
#endif
}
#define iowrite32_rep(p, v, c) iowrite32_rep(p, v, c)
static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
outsl(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesl(addr, vaddr, count);
#else
__indirect_writesl(addr, vaddr, count);
#endif
}
#define ioport_map(port, nr) ioport_map(port, nr)
static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
return ((void __iomem*)((port) + PIO_OFFSET));
}
#define ioport_unmap(addr) ioport_unmap(addr)
static inline void ioport_unmap(void __iomem *addr)
{
}
#endif /* CONFIG_PCI */
#endif /* __ASM_ARM_ARCH_IO_H */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
*
* Register definitions for IXP4xx chipset. This file contains
* register location and bit definitions only. Platform specific
* definitions and helper function declarations are in platform.h
* and machine-name.h.
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*/
#ifndef _ASM_ARM_IXP4XX_H_
#define _ASM_ARM_IXP4XX_H_
/*
* IXP4xx Linux Memory Map:
*
* Phy Size Virt Description
* =========================================================================
*
* 0x00000000 0x10000000(max) PAGE_OFFSET System RAM
*
* 0x48000000 0x04000000 ioremap'd PCI Memory Space
*
* 0x50000000 0x10000000 ioremap'd EXP BUS
*
* 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
*
* 0xC0000000 0x00001000 0xFEF13000 PCI CFG
*
* 0xC4000000 0x00001000 0xFEF14000 EXP CFG
*
* 0x60000000 0x00004000 0xFEF15000 QMgr
*/
/*
* Queue Manager
*/
#define IXP4XX_QMGR_BASE_PHYS 0x60000000
/*
* Peripheral space, including debug UART. Must be section-aligned so that
* it can be used with the low-level debug code.
*/
#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEC00000)
#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
/*
* PCI Config registers
*/
#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEC13000)
#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
/*
* Expansion BUS Configuration registers
*/
#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEC14000
#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
#define IXP4XX_EXP_CS0_OFFSET 0x00
#define IXP4XX_EXP_CS1_OFFSET 0x04
#define IXP4XX_EXP_CS2_OFFSET 0x08
#define IXP4XX_EXP_CS3_OFFSET 0x0C
#define IXP4XX_EXP_CS4_OFFSET 0x10
#define IXP4XX_EXP_CS5_OFFSET 0x14
#define IXP4XX_EXP_CS6_OFFSET 0x18
#define IXP4XX_EXP_CS7_OFFSET 0x1C
#define IXP4XX_EXP_CFG0_OFFSET 0x20
#define IXP4XX_EXP_CFG1_OFFSET 0x24
#define IXP4XX_EXP_CFG2_OFFSET 0x28
#define IXP4XX_EXP_CFG3_OFFSET 0x2C
/*
* Expansion Bus Controller registers.
*/
#define IXP4XX_EXP_REG(x) ((volatile u32 __iomem *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
#define IXP4XX_EXP_CS0 IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
#define IXP4XX_EXP_CS1 IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
#define IXP4XX_EXP_CS2 IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET)
#define IXP4XX_EXP_CS3 IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
#define IXP4XX_EXP_CS4 IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
#define IXP4XX_EXP_CS5 IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
#define IXP4XX_EXP_CS6 IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)
#define IXP4XX_EXP_CS7 IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
#define IXP4XX_EXP_CFG0 IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET)
#define IXP4XX_EXP_CFG1 IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET)
#define IXP4XX_EXP_CFG2 IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET)
#define IXP4XX_EXP_CFG3 IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
/*
* Peripheral Space Register Region Base Addresses
*/
#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
/* ixp46X only */
#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
/* The UART is explicitly put in the beginning of fixmap */
#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
/* ixp46X only */
#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
/*
* Constants to make it easy to access Timer Control/Status registers
*/
#define IXP4XX_OSTS_OFFSET 0x00 /* Continious TimeStamp */
#define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
#define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
#define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
#define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
#define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */
#define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */
#define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */
#define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */
/*
* Operating System Timer Register Definitions.
*/
#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
#define IXP4XX_OSTS IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
#define IXP4XX_OST1 IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
#define IXP4XX_OSRT1 IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
#define IXP4XX_OST2 IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
#define IXP4XX_OSRT2 IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
#define IXP4XX_OSWT IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
#define IXP4XX_OSWE IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
#define IXP4XX_OSWK IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
#define IXP4XX_OSST IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
/*
* Timer register values and bit definitions
*/
#define IXP4XX_OST_ENABLE 0x00000001
#define IXP4XX_OST_ONE_SHOT 0x00000002
/* Low order bits of reload value ignored */
#define IXP4XX_OST_RELOAD_MASK 0x00000003
#define IXP4XX_OST_DISABLED 0x00000000
#define IXP4XX_OSST_TIMER_1_PEND 0x00000001
#define IXP4XX_OSST_TIMER_2_PEND 0x00000002
#define IXP4XX_OSST_TIMER_TS_PEND 0x00000004
#define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008
#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
#define IXP4XX_WDT_KEY 0x0000482E
#define IXP4XX_WDT_RESET_ENABLE 0x00000001
#define IXP4XX_WDT_IRQ_ENABLE 0x00000002
#define IXP4XX_WDT_COUNT_ENABLE 0x00000004
/*
* Constants to make it easy to access PCI Control/Status registers
*/
#define PCI_NP_AD_OFFSET 0x00
#define PCI_NP_CBE_OFFSET 0x04
#define PCI_NP_WDATA_OFFSET 0x08
#define PCI_NP_RDATA_OFFSET 0x0c
#define PCI_CRP_AD_CBE_OFFSET 0x10
#define PCI_CRP_WDATA_OFFSET 0x14
#define PCI_CRP_RDATA_OFFSET 0x18
#define PCI_CSR_OFFSET 0x1c
#define PCI_ISR_OFFSET 0x20
#define PCI_INTEN_OFFSET 0x24
#define PCI_DMACTRL_OFFSET 0x28
#define PCI_AHBMEMBASE_OFFSET 0x2c
#define PCI_AHBIOBASE_OFFSET 0x30
#define PCI_PCIMEMBASE_OFFSET 0x34
#define PCI_AHBDOORBELL_OFFSET 0x38
#define PCI_PCIDOORBELL_OFFSET 0x3C
#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
/*
* PCI Control/Status Registers
*/
#define _IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
#define PCI_NP_AD _IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
#define PCI_NP_CBE _IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
#define PCI_NP_WDATA _IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
#define PCI_NP_RDATA _IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
#define PCI_CRP_AD_CBE _IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
#define PCI_CRP_WDATA _IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
#define PCI_CRP_RDATA _IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
#define PCI_CSR _IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
#define PCI_ISR _IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
#define PCI_INTEN _IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
#define PCI_DMACTRL _IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
#define PCI_AHBMEMBASE _IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
#define PCI_AHBIOBASE _IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
#define PCI_PCIMEMBASE _IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
#define PCI_AHBDOORBELL _IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
#define PCI_PCIDOORBELL _IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
#define PCI_ATPDMA0_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
#define PCI_ATPDMA0_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
#define PCI_ATPDMA0_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
#define PCI_ATPDMA1_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
#define PCI_ATPDMA1_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
#define PCI_ATPDMA1_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
/*
* PCI register values and bit definitions
*/
/* CSR bit definitions */
#define PCI_CSR_HOST 0x00000001
#define PCI_CSR_ARBEN 0x00000002
#define PCI_CSR_ADS 0x00000004
#define PCI_CSR_PDS 0x00000008
#define PCI_CSR_ABE 0x00000010
#define PCI_CSR_DBT 0x00000020
#define PCI_CSR_ASE 0x00000100
#define PCI_CSR_IC 0x00008000
/* ISR (Interrupt status) Register bit definitions */
#define PCI_ISR_PSE 0x00000001
#define PCI_ISR_PFE 0x00000002
#define PCI_ISR_PPE 0x00000004
#define PCI_ISR_AHBE 0x00000008
#define PCI_ISR_APDC 0x00000010
#define PCI_ISR_PADC 0x00000020
#define PCI_ISR_ADB 0x00000040
#define PCI_ISR_PDB 0x00000080
/* INTEN (Interrupt Enable) Register bit definitions */
#define PCI_INTEN_PSE 0x00000001
#define PCI_INTEN_PFE 0x00000002
#define PCI_INTEN_PPE 0x00000004
#define PCI_INTEN_AHBE 0x00000008
#define PCI_INTEN_APDC 0x00000010
#define PCI_INTEN_PADC 0x00000020
#define PCI_INTEN_ADB 0x00000040
#define PCI_INTEN_PDB 0x00000080
/*
* Shift value for byte enable on NP cmd/byte enable register
*/
#define IXP4XX_PCI_NP_CBE_BESL 4
/*
* PCI commands supported by NP access unit
*/
#define NP_CMD_IOREAD 0x2
#define NP_CMD_IOWRITE 0x3
#define NP_CMD_CONFIGREAD 0xa
#define NP_CMD_CONFIGWRITE 0xb
#define NP_CMD_MEMREAD 0x6
#define NP_CMD_MEMWRITE 0x7
/*
* Constants for CRP access into local config space
*/
#define CRP_AD_CBE_BESL 20
#define CRP_AD_CBE_WRITE 0x00010000
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/mach-ixp4xx/include/mach/platform.h
*
* Constants and functions that are useful to IXP4xx platform-specific code
* and device drivers.
*
* Copyright (C) 2004 MontaVista Software, Inc.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#ifndef __ASSEMBLY__
#include <linux/reboot.h>
#include <linux/platform_data/eth_ixp4xx.h>
#include <asm/types.h>
#ifndef __ARMEB__
#define REG_OFFSET 0
#else
#define REG_OFFSET 3
#endif
/*
* Expansion bus memory regions
*/
#define IXP4XX_EXP_BUS_BASE_PHYS (0x50000000)
/*
* The expansion bus on the IXP4xx can be configured for either 16 or
* 32MB windows and the CS offset for each region changes based on the
* current configuration. This means that we cannot simply hardcode
* each offset. ixp4xx_sys_init() looks at the expansion bus configuration
* as setup by the bootloader to determine our window size.
*/
extern unsigned long ixp4xx_exp_bus_size;
#define IXP4XX_EXP_BUS_BASE(region)\
(IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
#define IXP4XX_EXP_BUS_END(region)\
(IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
/* Those macros can be used to adjust timing and configure
* other features for each region.
*/
#define IXP4XX_EXP_BUS_RECOVERY_T(x) (((x) & 0x0f) << 16)
#define IXP4XX_EXP_BUS_HOLD_T(x) (((x) & 0x03) << 20)
#define IXP4XX_EXP_BUS_STROBE_T(x) (((x) & 0x0f) << 22)
#define IXP4XX_EXP_BUS_SETUP_T(x) (((x) & 0x03) << 26)
#define IXP4XX_EXP_BUS_ADDR_T(x) (((x) & 0x03) << 28)
#define IXP4XX_EXP_BUS_SIZE(x) (((x) & 0x0f) << 10)
#define IXP4XX_EXP_BUS_CYCLES(x) (((x) & 0x03) << 14)
#define IXP4XX_EXP_BUS_CS_EN (1L << 31)
#define IXP4XX_EXP_BUS_BYTE_RD16 (1L << 6)
#define IXP4XX_EXP_BUS_HRDY_POL (1L << 5)
#define IXP4XX_EXP_BUS_MUX_EN (1L << 4)
#define IXP4XX_EXP_BUS_SPLT_EN (1L << 3)
#define IXP4XX_EXP_BUS_WR_EN (1L << 1)
#define IXP4XX_EXP_BUS_BYTE_EN (1L << 0)
#define IXP4XX_EXP_BUS_CYCLES_INTEL 0x00
#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA 0x01
#define IXP4XX_EXP_BUS_CYCLES_HPI 0x02
#define IXP4XX_FLASH_WRITABLE (0x2)
#define IXP4XX_FLASH_DEFAULT (0xbcd23c40)
#define IXP4XX_FLASH_WRITE (0xbcd23c42)
/*
* Clock Speed Definitions.
*/
#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66MHzi APB BUS */
#define IXP4XX_UART_XTAL 14745600
/*
* Frequency of clock used for primary clocksource
*/
extern unsigned long ixp4xx_timer_freq;
/*
* Functions used by platform-level setup code
*/
extern void ixp4xx_map_io(void);
extern void ixp4xx_init_early(void);
extern void ixp4xx_init_irq(void);
extern void ixp4xx_sys_init(void);
extern void ixp4xx_timer_init(void);
extern void ixp4xx_restart(enum reboot_mode, const char *);
extern void ixp4xx_pci_preinit(void);
struct pci_sys_data;
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
extern struct pci_ops ixp4xx_ops;
#endif // __ASSEMBLY__
/*
* arch/arm/mach-ixp4xx/include/mach/udc.h
*
*/
#include <linux/platform_data/pxa2xx_udc.h>
extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
......@@ -9,10 +9,12 @@
#ifndef _ARCH_UNCOMPRESS_H_
#define _ARCH_UNCOMPRESS_H_
#include "ixp4xx-regs.h"
#include <asm/mach-types.h>
#include <linux/serial_reg.h>
#define IXP4XX_UART1_BASE_PHYS 0xc8000000
#define IXP4XX_UART2_BASE_PHYS 0xc8001000
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
volatile u32* uart_base;
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/mach-ixp4xx/include/mach/irqs.h
*
* IRQ definitions for IXP4XX based systems
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003 MontaVista Software, Inc.
*/
#ifndef _ARCH_IXP4XX_IRQS_H_
#define _ARCH_IXP4XX_IRQS_H_
#define IRQ_IXP4XX_BASE 16
#define IRQ_IXP4XX_NPEA (IRQ_IXP4XX_BASE + 0)
#define IRQ_IXP4XX_NPEB (IRQ_IXP4XX_BASE + 1)
#define IRQ_IXP4XX_NPEC (IRQ_IXP4XX_BASE + 2)
#define IRQ_IXP4XX_QM1 (IRQ_IXP4XX_BASE + 3)
#define IRQ_IXP4XX_QM2 (IRQ_IXP4XX_BASE + 4)
#define IRQ_IXP4XX_TIMER1 (IRQ_IXP4XX_BASE + 5)
#define IRQ_IXP4XX_GPIO0 (IRQ_IXP4XX_BASE + 6)
#define IRQ_IXP4XX_GPIO1 (IRQ_IXP4XX_BASE + 7)
#define IRQ_IXP4XX_PCI_INT (IRQ_IXP4XX_BASE + 8)
#define IRQ_IXP4XX_PCI_DMA1 (IRQ_IXP4XX_BASE + 9)
#define IRQ_IXP4XX_PCI_DMA2 (IRQ_IXP4XX_BASE + 10)
#define IRQ_IXP4XX_TIMER2 (IRQ_IXP4XX_BASE + 11)
#define IRQ_IXP4XX_USB (IRQ_IXP4XX_BASE + 12)
#define IRQ_IXP4XX_UART2 (IRQ_IXP4XX_BASE + 13)
#define IRQ_IXP4XX_TIMESTAMP (IRQ_IXP4XX_BASE + 14)
#define IRQ_IXP4XX_UART1 (IRQ_IXP4XX_BASE + 15)
#define IRQ_IXP4XX_WDOG (IRQ_IXP4XX_BASE + 16)
#define IRQ_IXP4XX_AHB_PMU (IRQ_IXP4XX_BASE + 17)
#define IRQ_IXP4XX_XSCALE_PMU (IRQ_IXP4XX_BASE + 18)
#define IRQ_IXP4XX_GPIO2 (IRQ_IXP4XX_BASE + 19)
#define IRQ_IXP4XX_GPIO3 (IRQ_IXP4XX_BASE + 20)
#define IRQ_IXP4XX_GPIO4 (IRQ_IXP4XX_BASE + 21)
#define IRQ_IXP4XX_GPIO5 (IRQ_IXP4XX_BASE + 22)
#define IRQ_IXP4XX_GPIO6 (IRQ_IXP4XX_BASE + 23)
#define IRQ_IXP4XX_GPIO7 (IRQ_IXP4XX_BASE + 24)
#define IRQ_IXP4XX_GPIO8 (IRQ_IXP4XX_BASE + 25)
#define IRQ_IXP4XX_GPIO9 (IRQ_IXP4XX_BASE + 26)
#define IRQ_IXP4XX_GPIO10 (IRQ_IXP4XX_BASE + 27)
#define IRQ_IXP4XX_GPIO11 (IRQ_IXP4XX_BASE + 28)
#define IRQ_IXP4XX_GPIO12 (IRQ_IXP4XX_BASE + 29)
#define IRQ_IXP4XX_SW_INT1 (IRQ_IXP4XX_BASE + 30)
#define IRQ_IXP4XX_SW_INT2 (IRQ_IXP4XX_BASE + 31)
#define IRQ_IXP4XX_USB_HOST (IRQ_IXP4XX_BASE + 32)
#define IRQ_IXP4XX_I2C (IRQ_IXP4XX_BASE + 33)
#define IRQ_IXP4XX_SSP (IRQ_IXP4XX_BASE + 34)
#define IRQ_IXP4XX_TSYNC (IRQ_IXP4XX_BASE + 35)
#define IRQ_IXP4XX_EAU_DONE (IRQ_IXP4XX_BASE + 36)
#define IRQ_IXP4XX_SHA_DONE (IRQ_IXP4XX_BASE + 37)
#define IRQ_IXP4XX_SWCP_PE (IRQ_IXP4XX_BASE + 58)
#define IRQ_IXP4XX_QM_PE (IRQ_IXP4XX_BASE + 60)
#define IRQ_IXP4XX_MCU_ECC (IRQ_IXP4XX_BASE + 61)
#define IRQ_IXP4XX_EXP_PE (IRQ_IXP4XX_BASE + 62)
#define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n)
#define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n)
#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
#endif
......@@ -72,6 +72,8 @@ static int sram_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
platform_set_drvdata(pdev, info);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
......@@ -107,8 +109,6 @@ static int sram_probe(struct platform_device *pdev)
list_add(&info->node, &sram_bank_list);
mutex_unlock(&sram_lock);
platform_set_drvdata(pdev, info);
dev_info(&pdev->dev, "initialized\n");
return 0;
......@@ -127,17 +127,19 @@ static int sram_remove(struct platform_device *pdev)
struct sram_bank_info *info;
info = platform_get_drvdata(pdev);
if (info == NULL)
return -ENODEV;
mutex_lock(&sram_lock);
list_del(&info->node);
mutex_unlock(&sram_lock);
if (info->sram_size) {
mutex_lock(&sram_lock);
list_del(&info->node);
mutex_unlock(&sram_lock);
gen_pool_destroy(info->gpool);
iounmap(info->sram_virt);
kfree(info->pool_name);
}
gen_pool_destroy(info->gpool);
iounmap(info->sram_virt);
kfree(info->pool_name);
kfree(info);
return 0;
}
......
menuconfig ARCH_MSTARV7
bool "MStar/Sigmastar Armv7 SoC Support"
depends on ARCH_MULTI_V7
select ARM_ERRATA_814220
select ARM_GIC
select ARM_HEAVY_MB
select HAVE_ARM_ARCH_TIMER
......
......@@ -67,7 +67,6 @@ void __init mv78xx0_init_irq(void)
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE,
mv78xx0_core_index() ? 0x18 : 0,
orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
......@@ -2,7 +2,6 @@
config ARCH_NSPIRE
bool "TI-NSPIRE based"
depends on ARCH_MULTI_V4_V5
depends on MMU
select CPU_ARM926T
select GENERIC_IRQ_CHIP
select ARM_AMBA
......
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_ORION5X
bool "Marvell Orion"
depends on MMU && ARCH_MULTI_V5
depends on ARCH_MULTI_V5
select CPU_FEROCEON
select GPIOLIB
select MVEBU_MBUS
......
......@@ -49,6 +49,6 @@ void __init orion5x_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-31.
*/
orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
......@@ -153,16 +153,6 @@ config GUMSTIX_AM300EPD
endchoice
config MACH_INTELMOTE2
bool "Intel Mote 2 Platform"
select IWMMXT
select PXA27x
config MACH_STARGATE2
bool "Intel Stargate 2 Platform"
select IWMMXT
select PXA27x
config MACH_XCEP
bool "Iskratel Electronics XCEP"
select MTD
......
......@@ -45,8 +45,6 @@ obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
obj-$(CONFIG_MACH_INTELMOTE2) += stargate2.o
obj-$(CONFIG_MACH_STARGATE2) += stargate2.o
obj-$(CONFIG_MACH_XCEP) += xcep.o
obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
......
......@@ -58,9 +58,8 @@ static inline void arch_decomp_setup(void)
uart_shift = 2;
uart_is_pxa = 1;
if (machine_is_littleton() || machine_is_intelmote2()
|| machine_is_csb726() || machine_is_stargate2()
|| machine_is_cm_x300() || machine_is_balloon3())
if (machine_is_littleton() || machine_is_csb726() ||
machine_is_cm_x300() || machine_is_balloon3())
uart_base = STUART_BASE;
if (machine_is_arcom_zeus()) {
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* linux/arch/arm/mach-pxa/stargate2.c
*
* Author: Ed C. Epp
* Created: Nov 05, 2002
* Copyright: Intel Corp.
*
* Modified 2009: Jonathan Cameron <jic23@cam.ac.uk>
*/
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/machine.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/plat-ram.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/smc91x.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/property.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
#include "pxa27x.h"
#include <linux/platform_data/mmc-pxamci.h>
#include "udc.h"
#include "pxa27x-udc.h"
#include <mach/smemc.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/mfd/da903x.h>
#include "devices.h"
#include "generic.h"
#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
/* Bluetooth */
#define SG2_BT_RESET 81
/* SD */
#define SG2_GPIO_nSD_DETECT 90
#define SG2_SD_POWER_ENABLE 89
static unsigned long sg2_im2_unified_pin_config[] __initdata = {
/* Device Identification for wakeup*/
GPIO102_GPIO,
/* DA9030 */
GPIO1_GPIO,
/* MMC */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
/* 802.15.4 radio - driver out of mainline */
GPIO22_GPIO, /* CC_RSTN */
GPIO114_GPIO, /* CC_FIFO */
GPIO116_GPIO, /* CC_CCA */
GPIO0_GPIO, /* CC_FIFOP */
GPIO16_GPIO, /* CCSFD */
GPIO115_GPIO, /* Power enable */
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* SSP 3 - 802.15.4 radio */
GPIO39_GPIO, /* Chip Select */
GPIO34_SSP3_SCLK,
GPIO35_SSP3_TXD,
GPIO41_SSP3_RXD,
/* SSP 2 to daughter boards */
GPIO11_SSP2_RXD,
GPIO38_SSP2_TXD,
GPIO36_SSP2_SCLK,
GPIO37_GPIO, /* chip select */
/* SSP 1 - to daughter boards */
GPIO24_GPIO, /* Chip Select */
GPIO23_SSP1_SCLK,
GPIO25_SSP1_TXD,
GPIO26_SSP1_RXD,
/* BTUART Basic Connector*/
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* STUART - IM2 via debug board not sure on SG2*/
GPIO46_STUART_RXD,
GPIO47_STUART_TXD,
/* Basic sensor board */
GPIO96_GPIO, /* accelerometer interrupt */
GPIO99_GPIO, /* ADC interrupt */
/* SHT15 */
GPIO100_GPIO,
GPIO98_GPIO,
/* Basic sensor board */
GPIO96_GPIO, /* accelerometer interrupt */
GPIO99_GPIO, /* ADC interrupt */
/* Connector pins specified as gpios */
GPIO94_GPIO, /* large basic connector pin 14 */
GPIO10_GPIO, /* large basic connector pin 23 */
};
static struct gpiod_lookup_table sht15_gpiod_table = {
.dev_id = "sht15",
.table = {
/* FIXME: should this have |GPIO_OPEN_DRAIN set? */
GPIO_LOOKUP("gpio-pxa", 100, "data", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", 98, "clk", GPIO_ACTIVE_HIGH),
},
};
static struct platform_device sht15 = {
.name = "sht15",
.id = -1,
};
static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
REGULATOR_SUPPLY("vcc", "sht15"),
};
enum stargate2_ldos{
vcc_vref,
vcc_cc2420,
/* a mote connector? */
vcc_mica,
/* the CSR bluecore chip */
vcc_bt,
/* The two voltages available to sensor boards */
vcc_sensor_1_8,
vcc_sensor_3,
/* directly connected to the pxa27x */
vcc_sram_ext,
vcc_pxa_pll,
vcc_pxa_usim, /* Reference voltage for certain gpios */
vcc_pxa_mem,
vcc_pxa_flash,
vcc_pxa_core, /*Dc-Dc buck not yet supported */
vcc_lcd,
vcc_bb,
vcc_bbio, /*not sure!*/
vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/
};
/* The values of the various regulator constraints are obviously dependent
* on exactly what is wired to each ldo. Unfortunately this information is
* not generally available. More information has been requested from Xbow.
*/
static struct regulator_init_data stargate2_ldo_init_data[] = {
[vcc_bbio] = {
.constraints = { /* board default 1.8V */
.name = "vcc_bbio",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_bb] = {
.constraints = { /* board default 2.8V */
.name = "vcc_bb",
.min_uV = 2700000,
.max_uV = 3000000,
},
},
[vcc_pxa_flash] = {
.constraints = {/* default is 1.8V */
.name = "vcc_pxa_flash",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_cc2420] = { /* also vcc_io */
.constraints = {
/* board default is 2.8V */
.name = "vcc_cc2420",
.min_uV = 2700000,
.max_uV = 3300000,
},
},
[vcc_vref] = { /* Reference for what? */
.constraints = { /* default 1.8V */
.name = "vcc_vref",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_sram_ext] = {
.constraints = { /* default 2.8V */
.name = "vcc_sram_ext",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_mica] = {
.constraints = { /* default 2.8V */
.name = "vcc_mica",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_bt] = {
.constraints = { /* default 2.8V */
.name = "vcc_bt",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_lcd] = {
.constraints = { /* default 2.8V */
.name = "vcc_lcd",
.min_uV = 2700000,
.max_uV = 3300000,
},
},
[vcc_io] = { /* Same or higher than everything
* bar vccbat and vccusb */
.constraints = { /* default 2.8V */
.name = "vcc_io",
.min_uV = 2692000,
.max_uV = 3300000,
},
},
[vcc_sensor_1_8] = {
.constraints = { /* default 1.8V */
.name = "vcc_sensor_1_8",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_sensor_3] = { /* curiously default 2.8V */
.constraints = {
.name = "vcc_sensor_3",
.min_uV = 2800000,
.max_uV = 3000000,
},
.num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con),
.consumer_supplies = stargate2_sensor_3_con,
},
[vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
.constraints = {
.name = "vcc_pxa_pll",
.min_uV = 1170000,
.max_uV = 1430000,
},
},
[vcc_pxa_usim] = {
.constraints = { /* default 1.8V */
.name = "vcc_pxa_usim",
.min_uV = 1710000,
.max_uV = 2160000,
},
},
[vcc_pxa_mem] = {
.constraints = { /* default 1.8V */
.name = "vcc_pxa_mem",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
};
static struct mtd_partition stargate2flash_partitions[] = {
{
.name = "Bootloader",
.size = 0x00040000,
.offset = 0,
.mask_flags = 0,
}, {
.name = "Kernel",
.size = 0x00200000,
.offset = 0x00040000,
.mask_flags = 0
}, {
.name = "Filesystem",
.size = 0x01DC0000,
.offset = 0x00240000,
.mask_flags = 0
},
};
static struct resource flash_resources = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
static struct flash_platform_data stargate2_flash_data = {
.map_name = "cfi_probe",
.parts = stargate2flash_partitions,
.nr_parts = ARRAY_SIZE(stargate2flash_partitions),
.name = "PXA27xOnChipROM",
.width = 2,
};
static struct platform_device stargate2_flash_device = {
.name = "pxa2xx-flash",
.id = 0,
.dev = {
.platform_data = &stargate2_flash_data,
},
.resource = &flash_resources,
.num_resources = 1,
};
static struct pxa2xx_spi_controller pxa_ssp_master_0_info = {
.num_chipselect = 1,
};
static struct pxa2xx_spi_controller pxa_ssp_master_1_info = {
.num_chipselect = 1,
};
static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
.num_chipselect = 1,
};
static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
.dev_id = "pxa2xx-spi.1",
.table = {
GPIO_LOOKUP_IDX("gpio-pxa", 24, "cs", 0, GPIO_ACTIVE_LOW),
{ },
},
};
static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
.dev_id = "pxa2xx-spi.3",
.table = {
GPIO_LOOKUP_IDX("gpio-pxa", 39, "cs", 0, GPIO_ACTIVE_LOW),
{ },
},
};
/* An upcoming kernel change will scrap SFRM usage so these
* drivers have been moved to use GPIOs */
static struct pxa2xx_spi_chip staccel_chip_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
};
static struct pxa2xx_spi_chip cc2420_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
};
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "lis3l02dq",
.max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */
.bus_num = 1,
.chip_select = 0,
.controller_data = &staccel_chip_info,
.irq = PXA_GPIO_TO_IRQ(96),
}, {
.modalias = "cc2420",
.max_speed_hz = 6500000,
.bus_num = 3,
.chip_select = 0,
.controller_data = &cc2420_info,
},
};
static void sg2_udc_command(int cmd)
{
switch (cmd) {
case PXA2XX_UDC_CMD_CONNECT:
UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE;
break;
case PXA2XX_UDC_CMD_DISCONNECT:
UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE);
break;
}
}
static struct i2c_pxa_platform_data i2c_pwr_pdata = {
.fast_mode = 1,
};
static struct i2c_pxa_platform_data i2c_pdata = {
.fast_mode = 1,
};
static void __init imote2_stargate2_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(sg2_im2_unified_pin_config));
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
pxa27x_set_i2c_power_info(&i2c_pwr_pdata);
pxa_set_i2c_info(&i2c_pdata);
}
#ifdef CONFIG_MACH_INTELMOTE2
/* As the the imote2 doesn't currently have a conventional SD slot
* there is no option to hotplug cards, making all this rather simple
*/
static int imote2_mci_get_ro(struct device *dev)
{
return 0;
}
/* Rather simple case as hotplugging not possible */
static struct pxamci_platform_data imote2_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */
.get_ro = imote2_mci_get_ro,
};
static struct gpio_led imote2_led_pins[] = {
{
.name = "imote2:red",
.gpio = 103,
.active_low = 1,
}, {
.name = "imote2:green",
.gpio = 104,
.active_low = 1,
}, {
.name = "imote2:blue",
.gpio = 105,
.active_low = 1,
},
};
static struct gpio_led_platform_data imote2_led_data = {
.num_leds = ARRAY_SIZE(imote2_led_pins),
.leds = imote2_led_pins,
};
static struct platform_device imote2_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &imote2_led_data,
},
};
static struct da903x_subdev_info imote2_da9030_subdevs[] = {
{
.name = "da903x-regulator",
.id = DA9030_ID_LDO2,
.platform_data = &stargate2_ldo_init_data[vcc_bbio],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO3,
.platform_data = &stargate2_ldo_init_data[vcc_bb],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO4,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO5,
.platform_data = &stargate2_ldo_init_data[vcc_cc2420],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO6,
.platform_data = &stargate2_ldo_init_data[vcc_vref],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO7,
.platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO8,
.platform_data = &stargate2_ldo_init_data[vcc_mica],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO9,
.platform_data = &stargate2_ldo_init_data[vcc_bt],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO10,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO11,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO12,
.platform_data = &stargate2_ldo_init_data[vcc_lcd],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO15,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO17,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
}, {
.name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
.id = DA9030_ID_LDO18,
.platform_data = &stargate2_ldo_init_data[vcc_io],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO19,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
},
};
static struct da903x_platform_data imote2_da9030_pdata = {
.num_subdevs = ARRAY_SIZE(imote2_da9030_subdevs),
.subdevs = imote2_da9030_subdevs,
};
static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = {
{
.type = "da9030",
.addr = 0x49,
.platform_data = &imote2_da9030_pdata,
.irq = PXA_GPIO_TO_IRQ(1),
},
};
static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
{ /* UCAM sensor board */
.type = "max1239",
.addr = 0x35,
}, { /* ITS400 Sensor board only */
.type = "max1363",
.addr = 0x34,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = PXA_GPIO_TO_IRQ(99),
}, { /* ITS400 Sensor board only */
.type = "tsl2561",
.addr = 0x49,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = PXA_GPIO_TO_IRQ(99),
}, { /* ITS400 Sensor board only */
.type = "tmp175",
.addr = 0x4A,
.irq = PXA_GPIO_TO_IRQ(96),
}, { /* IMB400 Multimedia board */
.type = "wm8940",
.addr = 0x1A,
},
};
static unsigned long imote2_pin_config[] __initdata = {
/* Button */
GPIO91_GPIO,
/* LEDS */
GPIO103_GPIO, /* red led */
GPIO104_GPIO, /* green led */
GPIO105_GPIO, /* blue led */
};
static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = {
.udc_command = sg2_udc_command,
};
static struct platform_device imote2_audio_device = {
.name = "imote2-audio",
.id = -1,
};
static struct platform_device *imote2_devices[] = {
&stargate2_flash_device,
&imote2_leds,
&sht15,
&imote2_audio_device,
};
static void __init imote2_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config));
imote2_stargate2_init();
gpiod_add_lookup_table(&sht15_gpiod_table);
platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
i2c_register_board_info(0, imote2_i2c_board_info,
ARRAY_SIZE(imote2_i2c_board_info));
i2c_register_board_info(1, imote2_pwr_i2c_board_info,
ARRAY_SIZE(imote2_pwr_i2c_board_info));
pxa_set_mci_info(&imote2_mci_platform_data);
pxa_set_udc_info(&imote2_udc_info);
}
#endif
#ifdef CONFIG_MACH_STARGATE2
static unsigned long stargate2_pin_config[] __initdata = {
GPIO15_nCS_1, /* SRAM */
/* SMC91x */
GPIO80_nCS_4,
GPIO40_GPIO, /*cable detect?*/
/* Button */
GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH,
/* Compact Flash */
GPIO79_PSKTSEL,
GPIO48_nPOE,
GPIO49_nPWE,
GPIO50_nPIOR,
GPIO51_nPIOW,
GPIO85_nPCE_1,
GPIO54_nPCE_2,
GPIO55_nPREG,
GPIO56_nPWAIT,
GPIO57_nIOIS16,
GPIO120_GPIO, /* Buff ctrl */
GPIO108_GPIO, /* Power ctrl */
GPIO82_GPIO, /* Reset */
GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */
/* MMC not shared with imote2 */
GPIO90_GPIO, /* nSD detect */
GPIO89_GPIO, /* SD_POWER_ENABLE */
/* Bluetooth */
GPIO81_GPIO, /* reset */
};
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = (PXA_CS4_PHYS + 0x300),
.end = (PXA_CS4_PHYS + 0xfffff),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = PXA_GPIO_TO_IRQ(40),
.end = PXA_GPIO_TO_IRQ(40),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
static struct smc91x_platdata stargate2_smc91x_info = {
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT
| SMC91X_NOWAIT | SMC91X_USE_DMA,
.pxa_u16_align4 = true,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &stargate2_smc91x_info,
},
};
/*
* The card detect interrupt isn't debounced so we delay it by 250ms
* to give the card a chance to fully insert / eject.
*/
static int stargate2_mci_init(struct device *dev,
irq_handler_t stargate2_detect_int,
void *data)
{
int err;
err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable");
if (err) {
printk(KERN_ERR "Can't get the gpio for SD power control");
goto return_err;
}
gpio_direction_output(SG2_SD_POWER_ENABLE, 0);
err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect");
if (err) {
printk(KERN_ERR "Can't get the sd detect gpio");
goto free_power_en;
}
gpio_direction_input(SG2_GPIO_nSD_DETECT);
err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT),
stargate2_detect_int,
IRQ_TYPE_EDGE_BOTH,
"MMC card detect",
data);
if (err) {
printk(KERN_ERR "can't request MMC card detect IRQ\n");
goto free_nsd_detect;
}
return 0;
free_nsd_detect:
gpio_free(SG2_GPIO_nSD_DETECT);
free_power_en:
gpio_free(SG2_SD_POWER_ENABLE);
return_err:
return err;
}
/**
* stargate2_mci_setpower() - set state of mmc power supply
*
* Very simple control. Either it is on or off and is controlled by
* a gpio pin */
static int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
{
gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
return 0;
}
static void stargate2_mci_exit(struct device *dev, void *data)
{
free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data);
gpio_free(SG2_SD_POWER_ENABLE);
gpio_free(SG2_GPIO_nSD_DETECT);
}
static struct pxamci_platform_data stargate2_mci_platform_data = {
.detect_delay_ms = 250,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.init = stargate2_mci_init,
.setpower = stargate2_mci_setpower,
.exit = stargate2_mci_exit,
};
/*
* SRAM - The Stargate 2 has 32MB of SRAM.
*
* Here it is made available as an MTD. This will then
* typically have a cifs filesystem created on it to provide
* fast temporary storage.
*/
static struct resource sram_resources = {
.start = PXA_CS1_PHYS,
.end = PXA_CS1_PHYS + SZ_32M-1,
.flags = IORESOURCE_MEM,
};
static struct platdata_mtd_ram stargate2_sram_pdata = {
.mapname = "Stargate2 SRAM",
.bankwidth = 2,
};
static struct platform_device stargate2_sram = {
.name = "mtd-ram",
.id = 0,
.resource = &sram_resources,
.num_resources = 1,
.dev = {
.platform_data = &stargate2_sram_pdata,
},
};
static struct pcf857x_platform_data platform_data_pcf857x = {
.gpio_base = 128,
.n_latch = 0,
.setup = NULL,
.teardown = NULL,
.context = NULL,
};
static const struct property_entry pca9500_eeprom_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 4),
{ }
};
static const struct software_node pca9500_eeprom_node = {
.properties = pca9500_eeprom_properties,
};
/**
* stargate2_reset_bluetooth() reset the bluecore to ensure consistent state
**/
static int stargate2_reset_bluetooth(void)
{
int err;
err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET");
if (err) {
printk(KERN_ERR "Could not get gpio for bluetooth reset\n");
return err;
}
gpio_direction_output(SG2_BT_RESET, 1);
mdelay(5);
/* now reset it - 5 msec minimum */
gpio_set_value(SG2_BT_RESET, 0);
mdelay(10);
gpio_set_value(SG2_BT_RESET, 1);
gpio_free(SG2_BT_RESET);
return 0;
}
static struct led_info stargate2_leds[] = {
{
.name = "sg2:red",
.flags = DA9030_LED_RATE_ON,
}, {
.name = "sg2:blue",
.flags = DA9030_LED_RATE_ON,
}, {
.name = "sg2:green",
.flags = DA9030_LED_RATE_ON,
},
};
static struct da903x_subdev_info stargate2_da9030_subdevs[] = {
{
.name = "da903x-led",
.id = DA9030_ID_LED_2,
.platform_data = &stargate2_leds[0],
}, {
.name = "da903x-led",
.id = DA9030_ID_LED_3,
.platform_data = &stargate2_leds[2],
}, {
.name = "da903x-led",
.id = DA9030_ID_LED_4,
.platform_data = &stargate2_leds[1],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO2,
.platform_data = &stargate2_ldo_init_data[vcc_bbio],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO3,
.platform_data = &stargate2_ldo_init_data[vcc_bb],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO4,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO5,
.platform_data = &stargate2_ldo_init_data[vcc_cc2420],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO6,
.platform_data = &stargate2_ldo_init_data[vcc_vref],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO7,
.platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO8,
.platform_data = &stargate2_ldo_init_data[vcc_mica],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO9,
.platform_data = &stargate2_ldo_init_data[vcc_bt],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO10,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO11,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO12,
.platform_data = &stargate2_ldo_init_data[vcc_lcd],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO15,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO17,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
}, {
.name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
.id = DA9030_ID_LDO18,
.platform_data = &stargate2_ldo_init_data[vcc_io],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO19,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
},
};
static struct da903x_platform_data stargate2_da9030_pdata = {
.num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs),
.subdevs = stargate2_da9030_subdevs,
};
static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
{
.type = "da9030",
.addr = 0x49,
.platform_data = &stargate2_da9030_pdata,
.irq = PXA_GPIO_TO_IRQ(1),
},
};
static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
/* Techically this a pca9500 - but it's compatible with the 8574
* for gpio expansion and the 24c02 for eeprom access.
*/
{
.type = "pcf8574",
.addr = 0x27,
.platform_data = &platform_data_pcf857x,
}, {
.type = "24c02",
.addr = 0x57,
.swnode = &pca9500_eeprom_node,
}, {
.type = "max1238",
.addr = 0x35,
}, { /* ITS400 Sensor board only */
.type = "max1363",
.addr = 0x34,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = PXA_GPIO_TO_IRQ(99),
}, { /* ITS400 Sensor board only */
.type = "tsl2561",
.addr = 0x49,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = PXA_GPIO_TO_IRQ(99),
}, { /* ITS400 Sensor board only */
.type = "tmp175",
.addr = 0x4A,
.irq = PXA_GPIO_TO_IRQ(96),
},
};
/* Board doesn't support cable detection - so always lie and say
* something is there.
*/
static int sg2_udc_detect(void)
{
return 1;
}
static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = {
.udc_is_connected = sg2_udc_detect,
.udc_command = sg2_udc_command,
};
static struct platform_device *stargate2_devices[] = {
&stargate2_flash_device,
&stargate2_sram,
&smc91x_device,
&sht15,
};
static void __init stargate2_init(void)
{
/* This is probably a board specific hack as this must be set
prior to connecting the MFP stuff up. */
__raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR);
pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
imote2_stargate2_init();
gpiod_add_lookup_table(&sht15_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
i2c_register_board_info(1, stargate2_pwr_i2c_board_info,
ARRAY_SIZE(stargate2_pwr_i2c_board_info));
pxa_set_mci_info(&stargate2_mci_platform_data);
pxa_set_udc_info(&stargate2_udc_info);
stargate2_reset_bluetooth();
}
#endif
#ifdef CONFIG_MACH_INTELMOTE2
MACHINE_START(INTELMOTE2, "IMOTE 2")
.map_io = pxa27x_map_io,
.nr_irqs = PXA_NR_IRQS,
.init_irq = pxa27x_init_irq,
.handle_irq = pxa27x_handle_irq,
.init_time = pxa_timer_init,
.init_machine = imote2_init,
.atag_offset = 0x100,
.restart = pxa_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_STARGATE2
MACHINE_START(STARGATE2, "Stargate 2")
.map_io = pxa27x_map_io,
.nr_irqs = STARGATE_NR_IRQS,
.init_irq = pxa27x_init_irq,
.handle_irq = pxa27x_handle_irq,
.init_time = pxa_timer_init,
.init_machine = stargate2_init,
.atag_offset = 0x100,
.restart = pxa_restart,
MACHINE_END
#endif
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_RENESAS
bool "Renesas ARM SoCs"
depends on ARCH_MULTI_V7 && MMU
depends on ARCH_MULTI_V7
select ARM_GIC
select GPIOLIB
select NO_IOPORT_MAP
......
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_U8500
bool "ST-Ericsson U8500 Series"
depends on ARCH_MULTI_V7 && MMU
depends on ARCH_MULTI_V7
select AB8500_CORE
select ABX500_CORE
select ARM_AMBA
......
......@@ -516,8 +516,7 @@ static void orion_gpio_mask_irq(struct irq_data *d)
irq_gc_unlock(gc);
}
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irqs[4])
......@@ -545,9 +544,6 @@ void __init orion_gpio_init(struct device_node *np,
ochip->chip.base = gpio_base;
ochip->chip.ngpio = ngpio;
ochip->chip.can_sleep = 0;
#ifdef CONFIG_OF
ochip->chip.of_node = np;
#endif
ochip->chip.dbg_show = orion_gpio_dbg_show;
spin_lock_init(&ochip->lock);
......@@ -605,7 +601,7 @@ void __init orion_gpio_init(struct device_node *np,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Setup irq domain on top of the generic chip. */
ochip->domain = irq_domain_add_legacy(np,
ochip->domain = irq_domain_add_legacy(NULL,
ochip->chip.ngpio,
ochip->secondary_irq_base,
ochip->secondary_irq_base,
......
......@@ -30,8 +30,7 @@ int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
void orion_gpio_set_valid(unsigned pin, int mode);
/* Initialize gpiolib. */
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irq[4]);
......
......@@ -33,7 +33,6 @@
/* Intermittent includes, delete this after v5.14-rc1 */
#include <linux/soc/ixp4xx/cpu.h>
#include <mach/ixp4xx-regs.h>
#define MAX_KEYLEN 32
......
......@@ -20,9 +20,9 @@ if NET_VENDOR_XSCALE
config IXP4XX_ETH
tristate "Intel IXP4xx Ethernet support"
depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR && OF
select PHYLIB
select OF_MDIO if OF
select OF_MDIO
select NET_PTP_CLASSIFY
help
Say Y here if you want to use built-in Ethernet ports
......
......@@ -30,7 +30,6 @@
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_data/eth_ixp4xx.h>
#include <linux/platform_device.h>
#include <linux/ptp_classify.h>
#include <linux/slab.h>
......@@ -38,6 +37,11 @@
#include <linux/soc/ixp4xx/npe.h>
#include <linux/soc/ixp4xx/qmgr.h>
#include <linux/soc/ixp4xx/cpu.h>
#include <linux/types.h>
#define IXP4XX_ETH_NPEA 0x00
#define IXP4XX_ETH_NPEB 0x10
#define IXP4XX_ETH_NPEC 0x20
#include "ixp46x_ts.h"
......@@ -147,6 +151,16 @@ typedef void buffer_t;
#define free_buffer_irq kfree
#endif
/* Information about built-in Ethernet MAC interfaces */
struct eth_plat_info {
u8 phy; /* MII PHY ID, 0 - 31 */
u8 rxq; /* configurable, currently 0 - 31 only */
u8 txreadyq;
u8 hwaddr[6];
u8 npe; /* NPE instance used by this interface */
bool has_mdio; /* If this instance has an MDIO bus */
};
struct eth_regs {
u32 tx_control[2], __res1[2]; /* 000 */
u32 rx_control[2], __res2[2]; /* 010 */
......@@ -1366,7 +1380,6 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
#ifdef CONFIG_OF
static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
{
struct device_node *np = dev->of_node;
......@@ -1417,12 +1430,6 @@ static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
return plat;
}
#else
static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
{
return NULL;
}
#endif
static int ixp4xx_eth_probe(struct platform_device *pdev)
{
......@@ -1434,49 +1441,9 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
struct port *port;
int err;
if (np) {
plat = ixp4xx_of_get_platdata(dev);
if (!plat)
return -ENODEV;
} else {
plat = dev_get_platdata(dev);
if (!plat)
return -ENODEV;
plat->npe = pdev->id;
switch (plat->npe) {
case IXP4XX_ETH_NPEA:
/* If the MDIO bus is not up yet, defer probe */
break;
case IXP4XX_ETH_NPEB:
/* On all except IXP43x, NPE-B is used for the MDIO bus.
* If there is no NPE-B in the feature set, bail out,
* else we have the MDIO bus here.
*/
if (!cpu_is_ixp43x()) {
if (!(ixp4xx_read_feature_bits() &
IXP4XX_FEATURE_NPEB_ETH0))
return -ENODEV;
/* Else register the MDIO bus on NPE-B */
plat->has_mdio = true;
}
break;
case IXP4XX_ETH_NPEC:
/* IXP43x lacks NPE-B and uses NPE-C for the MDIO bus
* access, if there is no NPE-C, no bus, nothing works,
* so bail out.
*/
if (cpu_is_ixp43x()) {
if (!(ixp4xx_read_feature_bits() &
IXP4XX_FEATURE_NPEC_ETH))
return -ENODEV;
/* Else register the MDIO bus on NPE-B */
plat->has_mdio = true;
}
break;
default:
return -ENODEV;
}
}
plat = ixp4xx_of_get_platdata(dev);
if (!plat)
return -ENODEV;
if (!(ndev = devm_alloc_etherdev(dev, sizeof(struct port))))
return -ENOMEM;
......@@ -1530,21 +1497,7 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
udelay(50);
if (np) {
phydev = of_phy_get_and_connect(ndev, np, ixp4xx_adjust_link);
} else {
phydev = mdiobus_get_phy(mdio_bus, plat->phy);
if (!phydev) {
err = -ENODEV;
dev_err(dev, "could not connect phydev (%d)\n", err);
goto err_free_mem;
}
err = phy_connect_direct(ndev, phydev, ixp4xx_adjust_link,
PHY_INTERFACE_MODE_MII);
if (err)
goto err_free_mem;
}
phydev = of_phy_get_and_connect(ndev, np, ixp4xx_adjust_link);
if (!phydev) {
err = -ENODEV;
dev_err(dev, "no phydev\n");
......
......@@ -16,7 +16,6 @@
#include <linux/ptp_clock_kernel.h>
#include <linux/platform_device.h>
#include <linux/soc/ixp4xx/cpu.h>
#include <mach/ixp4xx-regs.h>
#include "ixp46x_ts.h"
......
......@@ -293,7 +293,8 @@ config SLIC_DS26522
config IXP4XX_HSS
tristate "Intel IXP4xx HSS (synchronous serial port) support"
depends on HDLC && IXP4XX_NPE && IXP4XX_QMGR
depends on ARCH_IXP4XX
depends on ARCH_IXP4XX && OF
select MFD_SYSCON
help
Say Y here if you want to use built-in HSS ports
on IXP4xx processor.
......
......@@ -16,8 +16,10 @@
#include <linux/hdlc.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
......@@ -1389,9 +1391,28 @@ static int ixp4xx_hss_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct net_device *ndev;
struct device_node *np;
struct regmap *rmap;
struct port *port;
hdlc_device *hdlc;
int err;
u32 val;
/*
* Go into the syscon and check if we have the HSS and HDLC
* features available, else this will not work.
*/
rmap = syscon_regmap_lookup_by_compatible("syscon");
if (IS_ERR(rmap))
return dev_err_probe(dev, PTR_ERR(rmap),
"failed to look up syscon\n");
val = cpu_ixp4xx_features(rmap);
if ((val & (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
(IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) {
dev_err(dev, "HDLC and HSS feature unavailable in platform\n");
return -ENODEV;
}
np = dev->of_node;
......@@ -1516,25 +1537,9 @@ static struct platform_driver ixp4xx_hss_driver = {
.probe = ixp4xx_hss_probe,
.remove = ixp4xx_hss_remove,
};
static int __init hss_init_module(void)
{
if ((ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
(IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS))
return -ENODEV;
return platform_driver_register(&ixp4xx_hss_driver);
}
static void __exit hss_cleanup_module(void)
{
platform_driver_unregister(&ixp4xx_hss_driver);
}
module_platform_driver(ixp4xx_hss_driver);
MODULE_AUTHOR("Krzysztof Halasa");
MODULE_DESCRIPTION("Intel IXP4xx HSS driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:ixp4xx_hss");
module_init(hss_init_module);
module_exit(hss_cleanup_module);
......@@ -210,7 +210,7 @@ config PCMCIA_PXA2XX
depends on ARM && ARCH_PXA && PCMCIA
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|| ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|| ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
|| ARCOM_PCMCIA || ARCH_PXA_ESERIES \
|| MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
|| MACH_COLIBRI320 || MACH_H4700)
select PCMCIA_SOC_COMMON
......
......@@ -56,7 +56,6 @@ pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
pxa2xx-obj-$(CONFIG_MACH_PALMTC) += pxa2xx_palmtc.o
pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o
pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o
pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* linux/drivers/pcmcia/pxa2xx_stargate2.c
*
* Stargate 2 PCMCIA specific routines.
*
* Created: December 6, 2005
* Author: Ed C. Epp
* Copyright: Intel Corp 2005
* Jonathan Cameron <jic23@cam.ac.uk> 2009
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <pcmcia/ss.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include "soc_common.h"
#define SG2_S0_POWER_CTL 108
#define SG2_S0_GPIO_RESET 82
#define SG2_S0_GPIO_DETECT 53
#define SG2_S0_GPIO_READY 81
static struct gpio sg2_pcmcia_gpios[] = {
{ SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
{ SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
};
static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
return 0;
}
static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
state->bvd1 = 0; /* not available - battery detect on card */
state->bvd2 = 0; /* not available */
state->vs_3v = 1; /* not available - voltage detect for card */
state->vs_Xv = 0; /* not available */
}
static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
/* Enable card power */
switch (state->Vcc) {
case 0:
/* sets power ctl register high */
gpio_set_value(SG2_S0_POWER_CTL, 1);
break;
case 33:
case 50:
/* sets power control register low (clear) */
gpio_set_value(SG2_S0_POWER_CTL, 0);
msleep(100);
break;
default:
pr_err("%s(): bad Vcc %u\n",
__func__, state->Vcc);
return -1;
}
/* reset */
gpio_set_value(SG2_S0_GPIO_RESET, !!(state->flags & SS_RESET));
return 0;
}
static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
.owner = THIS_MODULE,
.hw_init = sg2_pcmcia_hw_init,
.socket_state = sg2_pcmcia_socket_state,
.configure_socket = sg2_pcmcia_configure_socket,
.nr = 1,
};
static struct platform_device *sg2_pcmcia_device;
static int __init sg2_pcmcia_init(void)
{
int ret;
if (!machine_is_stargate2())
return -ENODEV;
sg2_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!sg2_pcmcia_device)
return -ENOMEM;
ret = gpio_request_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
if (ret)
goto error_put_platform_device;
ret = platform_device_add_data(sg2_pcmcia_device,
&sg2_pcmcia_ops,
sizeof(sg2_pcmcia_ops));
if (ret)
goto error_free_gpios;
ret = platform_device_add(sg2_pcmcia_device);
if (ret)
goto error_free_gpios;
return 0;
error_free_gpios:
gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
error_put_platform_device:
platform_device_put(sg2_pcmcia_device);
return ret;
}
static void __exit sg2_pcmcia_exit(void)
{
platform_device_unregister(sg2_pcmcia_device);
gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
}
fs_initcall(sg2_pcmcia_init);
module_exit(sg2_pcmcia_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
......@@ -13,6 +13,7 @@ source "drivers/soc/imx/Kconfig"
source "drivers/soc/ixp4xx/Kconfig"
source "drivers/soc/litex/Kconfig"
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/microchip/Kconfig"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/renesas/Kconfig"
source "drivers/soc/rockchip/Kconfig"
......
......@@ -18,6 +18,7 @@ obj-y += ixp4xx/
obj-$(CONFIG_SOC_XWAY) += lantiq/
obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
obj-y += mediatek/
obj-y += microchip/
obj-y += amlogic/
obj-y += qcom/
obj-y += renesas/
......
......@@ -12,6 +12,7 @@ config IXP4XX_QMGR
config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support"
select FW_LOADER
select MFD_SYSCON
help
This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers.
......
......@@ -16,6 +16,7 @@
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
......@@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
static int npe_reset(struct npe *npe)
{
u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id);
u32 val, ctl, exec_count, ctx_reg2;
int i;
......@@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe)
__raw_writel(0, &npe->regs->action_points[3]);
__raw_writel(0, &npe->regs->watch_count);
val = ixp4xx_read_feature_bits();
/*
* We need to work on cached values here because the register
* will read inverted but needs to be written non-inverted.
*/
val = cpu_ixp4xx_features(npe->rmap);
/* reset the NPE */
ixp4xx_write_feature_bits(val &
~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit);
/* deassert reset */
ixp4xx_write_feature_bits(val |
(IXP4XX_FEATURE_RESET_NPEA << npe->id));
regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit);
for (i = 0; i < MAX_RETRIES; i++) {
if (ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_RESET_NPEA << npe->id))
val = cpu_ixp4xx_features(npe->rmap);
if (val & reset_bit)
break; /* NPE is back alive */
udelay(1);
}
......@@ -683,6 +688,14 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct resource *res;
struct regmap *rmap;
u32 val;
/* This system has only one syscon, so fetch it */
rmap = syscon_regmap_lookup_by_compatible("syscon");
if (IS_ERR(rmap))
return dev_err_probe(dev, PTR_ERR(rmap),
"failed to look up syscon\n");
for (i = 0; i < NPE_COUNT; i++) {
struct npe *npe = &npe_tab[i];
......@@ -691,8 +704,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
if (!res)
return -ENODEV;
if (!(ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_RESET_NPEA << i))) {
val = cpu_ixp4xx_features(rmap);
if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) {
dev_info(dev, "NPE%d at %pR not available\n",
i, res);
continue; /* NPE already disabled or not present */
......@@ -700,6 +714,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
npe->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(npe->regs))
return PTR_ERR(npe->regs);
npe->rmap = rmap;
if (npe_reset(npe)) {
dev_info(dev, "NPE%d at %pR does not reset\n",
......
config POLARFIRE_SOC_SYS_CTRL
tristate "POLARFIRE_SOC_SYS_CTRL"
depends on POLARFIRE_SOC_MAILBOX
help
This driver adds support for the PolarFire SoC (MPFS) system controller.
To compile this driver as a module, choose M here. the
module will be called mpfs_system_controller.
If unsure, say N.
obj-$(CONFIG_POLARFIRE_SOC_SYS_CTRL) += mpfs-sys-controller.o
// SPDX-License-Identifier: GPL-2.0
/*
* Microchip PolarFire SoC (MPFS) system controller driver
*
* Copyright (c) 2020-2021 Microchip Corporation. All rights reserved.
*
* Author: Conor Dooley <conor.dooley@microchip.com>
*
*/
#include <linux/slab.h>
#include <linux/kref.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
#include <linux/mailbox_client.h>
#include <linux/platform_device.h>
#include <soc/microchip/mpfs.h>
static DEFINE_MUTEX(transaction_lock);
struct mpfs_sys_controller {
struct mbox_client client;
struct mbox_chan *chan;
struct completion c;
struct kref consumers;
};
int mpfs_blocking_transaction(struct mpfs_sys_controller *sys_controller, struct mpfs_mss_msg *msg)
{
int ret, err;
err = mutex_lock_interruptible(&transaction_lock);
if (err)
return err;
reinit_completion(&sys_controller->c);
ret = mbox_send_message(sys_controller->chan, msg);
if (ret >= 0) {
if (wait_for_completion_timeout(&sys_controller->c, HZ)) {
ret = 0;
} else {
ret = -ETIMEDOUT;
dev_warn(sys_controller->client.dev,
"MPFS sys controller transaction timeout\n");
}
} else {
dev_err(sys_controller->client.dev,
"mpfs sys controller transaction returned %d\n", ret);
}
mutex_unlock(&transaction_lock);
return ret;
}
EXPORT_SYMBOL(mpfs_blocking_transaction);
static void rx_callback(struct mbox_client *client, void *msg)
{
struct mpfs_sys_controller *sys_controller =
container_of(client, struct mpfs_sys_controller, client);
complete(&sys_controller->c);
}
static void mpfs_sys_controller_delete(struct kref *kref)
{
struct mpfs_sys_controller *sys_controller = container_of(kref, struct mpfs_sys_controller,
consumers);
mbox_free_channel(sys_controller->chan);
kfree(sys_controller);
}
static void mpfs_sys_controller_put(void *data)
{
struct mpfs_sys_controller *sys_controller = data;
kref_put(&sys_controller->consumers, mpfs_sys_controller_delete);
}
static struct platform_device subdevs[] = {
{
.name = "mpfs-rng",
.id = -1,
},
{
.name = "mpfs-generic-service",
.id = -1,
}
};
static int mpfs_sys_controller_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mpfs_sys_controller *sys_controller;
int i;
sys_controller = devm_kzalloc(dev, sizeof(*sys_controller), GFP_KERNEL);
if (!sys_controller)
return -ENOMEM;
sys_controller->client.dev = dev;
sys_controller->client.rx_callback = rx_callback;
sys_controller->client.tx_block = 1U;
sys_controller->chan = mbox_request_channel(&sys_controller->client, 0);
if (IS_ERR(sys_controller->chan))
return dev_err_probe(dev, PTR_ERR(sys_controller->chan),
"Failed to get mbox channel\n");
init_completion(&sys_controller->c);
kref_init(&sys_controller->consumers);
platform_set_drvdata(pdev, sys_controller);
dev_info(&pdev->dev, "Registered MPFS system controller\n");
for (i = 0; i < ARRAY_SIZE(subdevs); i++) {
subdevs[i].dev.parent = dev;
if (platform_device_register(&subdevs[i]))
dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name);
}
return 0;
}
static int mpfs_sys_controller_remove(struct platform_device *pdev)
{
struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev);
mpfs_sys_controller_put(sys_controller);
return 0;
}
static const struct of_device_id mpfs_sys_controller_of_match[] = {
{.compatible = "microchip,mpfs-sys-controller", },
{},
};
MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match);
struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev)
{
const struct of_device_id *match;
struct mpfs_sys_controller *sys_controller;
int ret;
if (!dev->parent)
goto err_no_device;
match = of_match_node(mpfs_sys_controller_of_match, dev->parent->of_node);
of_node_put(dev->parent->of_node);
if (!match)
goto err_no_device;
sys_controller = dev_get_drvdata(dev->parent);
if (!sys_controller)
goto err_bad_device;
if (!kref_get_unless_zero(&sys_controller->consumers))
goto err_bad_device;
ret = devm_add_action_or_reset(dev, mpfs_sys_controller_put, sys_controller);
if (ret)
return ERR_PTR(ret);
return sys_controller;
err_no_device:
dev_dbg(dev, "Parent device was not an MPFS system controller\n");
return ERR_PTR(-ENODEV);
err_bad_device:
dev_dbg(dev, "MPFS system controller found but could not register as a sub device\n");
return ERR_PTR(-EPROBE_DEFER);
}
EXPORT_SYMBOL(mpfs_sys_controller_get);
static struct platform_driver mpfs_sys_controller_driver = {
.driver = {
.name = "mpfs-sys-controller",
.of_match_table = mpfs_sys_controller_of_match,
},
.probe = mpfs_sys_controller_probe,
.remove = mpfs_sys_controller_remove,
};
module_platform_driver(mpfs_sys_controller_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
MODULE_DESCRIPTION("MPFS system controller driver");
......@@ -78,6 +78,10 @@
#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */
#define AT91_CKGR_PLLAR 0x28 /* PLL A Register */
#define AT91_PMC_RATIO 0x2c /* Processor clock ratio register [SAMA7G5 only] */
#define AT91_PMC_RATIO_RATIO (0xf) /* CPU clock ratio. */
#define AT91_CKGR_PLLBR 0x2c /* PLL B Register */
#define AT91_PMC_DIV (0xff << 0) /* Divider */
#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_ETH_IXP4XX
#define __PLATFORM_DATA_ETH_IXP4XX
#include <linux/types.h>
#define IXP4XX_ETH_NPEA 0x00
#define IXP4XX_ETH_NPEB 0x10
#define IXP4XX_ETH_NPEC 0x20
/* Information about built-in Ethernet MAC interfaces */
struct eth_plat_info {
u8 phy; /* MII PHY ID, 0 - 31 */
u8 rxq; /* configurable, currently 0 - 31 only */
u8 txreadyq;
u8 hwaddr[6];
u8 npe; /* NPE instance used by this interface */
bool has_mdio; /* If this instance has an MDIO bus */
};
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_WAN_IXP4XX_HSS_H
#define __PLATFORM_DATA_WAN_IXP4XX_HSS_H
#include <linux/types.h>
/* Information about built-in HSS (synchronous serial) interfaces */
struct hss_plat_info {
int (*set_clock)(int port, unsigned int clock_type);
int (*open)(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier));
void (*close)(int port, void *pdev);
u8 txreadyq;
u32 timer_freq;
};
#endif
......@@ -9,6 +9,7 @@
#define __SOC_IXP4XX_CPU_H__
#include <linux/io.h>
#include <linux/regmap.h>
#ifdef CONFIG_ARM
#include <asm/cputype.h>
#endif
......@@ -23,6 +24,9 @@
#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
#define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
/* Feature register in the expansion bus controller */
#define IXP4XX_EXP_CNFG2 0x2c
/* "fuse" bits of IXP_EXP_CFG2 */
/* All IXP4xx CPUs */
#define IXP4XX_FEATURE_RCOMP (1 << 0)
......@@ -86,21 +90,31 @@
IXP43X_PROCESSOR_ID_VALUE)
#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
IXP46X_PROCESSOR_ID_VALUE)
static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
{
u32 val;
u32 ixp4xx_read_feature_bits(void);
void ixp4xx_write_feature_bits(u32 value);
regmap_read(rmap, IXP4XX_EXP_CNFG2, &val);
/* For some reason this register is inverted */
val = ~val;
if (cpu_is_ixp42x_rev_a0())
return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
IXP4XX_FEATURE_AES);
if (cpu_is_ixp42x())
return val & IXP42X_FEATURE_MASK;
if (cpu_is_ixp43x())
return val & IXP43X_FEATURE_MASK;
return val & IXP46X_FEATURE_MASK;
}
#else
#define cpu_is_ixp42x_rev_a0() 0
#define cpu_is_ixp42x() 0
#define cpu_is_ixp43x() 0
#define cpu_is_ixp46x() 0
static inline u32 ixp4xx_read_feature_bits(void)
static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
{
return 0;
}
static inline void ixp4xx_write_feature_bits(u32 value)
{
}
#endif
#endif /* _ASM_ARCH_CPU_H */
......@@ -3,6 +3,7 @@
#define __IXP4XX_NPE_H
#include <linux/kernel.h>
#include <linux/regmap.h>
extern const char *npe_names[];
......@@ -17,6 +18,7 @@ struct npe_regs {
struct npe {
struct npe_regs __iomem *regs;
struct regmap *rmap;
int id;
int valid;
};
......
......@@ -11,15 +11,13 @@
#ifndef __SAMA7_DDR_H__
#define __SAMA7_DDR_H__
#ifdef CONFIG_SOC_SAMA7
/* DDR3PHY */
#define DDR3PHY_PIR (0x04) /* DDR3PHY PHY Initialization Register */
#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */
#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */
#define DDR3PHY_PIR_ITMSRST (1 << 4) /* Interface Timing Module Soft Reset */
#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */
#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */
#define DDR3PHY_PIR_DLLSRST (1 << 1) /* DLL Soft Rest */
#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */
#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */
#define DDR3PHY_PGCR (0x08) /* DDR3PHY PHY General Configuration Register */
#define DDR3PHY_PGCR_CKDV1 (1 << 13) /* CK# Disable Value */
......@@ -55,7 +53,8 @@
#define UDDRC_STAT_OPMODE_MSK (0x7 << 0) /* Operating mode mask */
#define UDDRC_PWRCTL (0x30) /* UDDRC Low Power Control Register */
#define UDDRC_PWRCTRL_SELFREF_SW (1 << 5) /* Software self-refresh */
#define UDDRC_PWRCTL_SELFREF_EN (1 << 0) /* Automatic self-refresh */
#define UDDRC_PWRCTL_SELFREF_SW (1 << 5) /* Software self-refresh */
#define UDDRC_DFIMISC (0x1B0) /* UDDRC DFI Miscellaneous Control Register */
#define UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN (1 << 0) /* PHY initialization complete enable signal */
......@@ -67,7 +66,7 @@
#define UDDRC_SWSTAT_SW_DONE_ACK (1 << 0) /* Register programming done */
#define UDDRC_PSTAT (0x3FC) /* UDDRC Port Status Register */
#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */
#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */
#define UDDRC_PCTRL_0 (0x490) /* UDDRC Port 0 Control Register */
#define UDDRC_PCTRL_1 (0x540) /* UDDRC Port 1 Control Register */
......@@ -75,6 +74,4 @@
#define UDDRC_PCTRL_3 (0x6A0) /* UDDRC Port 3 Control Register */
#define UDDRC_PCTRL_4 (0x750) /* UDDRC Port 4 Control Register */
#endif /* CONFIG_SOC_SAMA7 */
#endif /* __SAMA7_DDR_H__ */
......@@ -34,9 +34,9 @@ struct mpfs_mss_response {
#if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL)
int mpfs_blocking_transaction(struct mpfs_sys_controller *mpfs_client, void *msg);
int mpfs_blocking_transaction(struct mpfs_sys_controller *mpfs_client, struct mpfs_mss_msg *msg);
struct mpfs_sys_controller *mpfs_sys_controller_get(struct device_node *mailbox_node);
struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev);
#endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */
......
......@@ -745,7 +745,6 @@ int dma_set_mask(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(dma_set_mask);
#ifndef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
int dma_set_coherent_mask(struct device *dev, u64 mask)
{
/*
......@@ -761,7 +760,6 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
return 0;
}
EXPORT_SYMBOL(dma_set_coherent_mask);
#endif
size_t dma_max_mapping_size(struct device *dev)
{
......
......@@ -220,15 +220,6 @@ config SND_PXA2XX_SOC_MIOA701
Say Y if you want to add support for SoC audio on the
MIO A701.
config SND_PXA2XX_SOC_IMOTE2
tristate "SoC Audio support for IMote 2"
depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8940
help
Say Y if you want to add support for SoC audio on the
IMote 2.
config SND_MMP_SOC_BROWNSTONE
tristate "SoC Audio support for Marvell Brownstone"
depends on SND_MMP_SOC_SSPA && MACH_BROWNSTONE && I2C
......
......@@ -29,7 +29,6 @@ snd-soc-hx4700-objs := hx4700.o
snd-soc-magician-objs := magician.o
snd-soc-mioa701-objs := mioa701_wm9713.o
snd-soc-z2-objs := z2.o
snd-soc-imote2-objs := imote2.o
snd-soc-brownstone-objs := brownstone.o
snd-soc-ttc-dkb-objs := ttc-dkb.o
......@@ -47,6 +46,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o
obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/module.h>
#include <sound/soc.h>
#include <asm/mach-types.h>
#include "../codecs/wm8940.h"
#include "pxa2xx-i2s.h"
static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
unsigned int clk = 0;
int ret;
switch (params_rate(params)) {
case 8000:
case 16000:
case 48000:
case 96000:
clk = 12288000;
break;
case 11025:
case 22050:
case 44100:
clk = 11289600;
break;
}
ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
/* set the I2S system clock as input (unused) */
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk,
SND_SOC_CLOCK_OUT);
return ret;
}
static const struct snd_soc_ops imote2_asoc_ops = {
.hw_params = imote2_asoc_hw_params,
};
SND_SOC_DAILINK_DEFS(wm8940,
DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8940-codec.0-0034",
"wm8940-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
static struct snd_soc_dai_link imote2_dai = {
.name = "WM8940",
.stream_name = "WM8940",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &imote2_asoc_ops,
SND_SOC_DAILINK_REG(wm8940),
};
static struct snd_soc_card imote2 = {
.name = "Imote2",
.owner = THIS_MODULE,
.dai_link = &imote2_dai,
.num_links = 1,
};
static int imote2_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &imote2;
int ret;
card->dev = &pdev->dev;
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret);
return ret;
}
static struct platform_driver imote2_driver = {
.driver = {
.name = "imote2-audio",
.pm = &snd_soc_pm_ops,
},
.probe = imote2_probe,
};
module_platform_driver(imote2_driver);
MODULE_AUTHOR("Jonathan Cameron");
MODULE_DESCRIPTION("ALSA SoC Imote 2");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:imote2-audio");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment