^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/arm/mach-ep93xx/ts72xx.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Technologic Systems TS72xx SBC support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mtd/platnand.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spi/flash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spi/mmc_spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_data/spi-ep93xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "gpio-ep93xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/mach-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/mach/arch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "ts72xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * IO map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static struct map_desc ts72xx_io_desc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .virtual = (unsigned long)TS72XX_MODEL_VIRT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .length = TS72XX_MODEL_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .type = MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .virtual = (unsigned long)TS72XX_OPTIONS_VIRT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .length = TS72XX_OPTIONS_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .type = MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .virtual = (unsigned long)TS72XX_OPTIONS2_VIRT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .length = TS72XX_OPTIONS2_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .type = MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .virtual = (unsigned long)TS72XX_CPLDVER_VIRT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .pfn = __phys_to_pfn(TS72XX_CPLDVER_PHYS_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .length = TS72XX_CPLDVER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .type = MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void __init ts72xx_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ep93xx_map_io();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * NAND flash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static void ts72xx_nand_hwcontrol(struct nand_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int cmd, unsigned int ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (ctrl & NAND_CTRL_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) void __iomem *addr = chip->legacy.IO_ADDR_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned char bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bits = __raw_readb(addr) & ~0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __raw_writeb(bits, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (cmd != NAND_CMD_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __raw_writeb(cmd, chip->legacy.IO_ADDR_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int ts72xx_nand_device_ready(struct nand_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void __iomem *addr = chip->legacy.IO_ADDR_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return !!(__raw_readb(addr) & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define TS72XX_BOOTROM_PART_SIZE (SZ_16K)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct mtd_partition ts72xx_nand_parts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .name = "TS-BOOTROM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .size = TS72XX_BOOTROM_PART_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .mask_flags = MTD_WRITEABLE, /* force read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .name = "Linux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .offset = MTDPART_OFS_RETAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .size = TS72XX_REDBOOT_PART_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* leave so much for last partition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .name = "RedBoot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .offset = MTDPART_OFS_APPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .size = MTDPART_SIZ_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .mask_flags = MTD_WRITEABLE, /* force read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static struct platform_nand_data ts72xx_nand_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .nr_chips = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .chip_offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .chip_delay = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .cmd_ctrl = ts72xx_nand_hwcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .dev_ready = ts72xx_nand_device_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static struct resource ts72xx_nand_resource[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .start = 0, /* filled in later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .end = 0, /* filled in later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static struct platform_device ts72xx_nand_flash = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .name = "gen_nand",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .dev.platform_data = &ts72xx_nand_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .resource = ts72xx_nand_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .num_resources = ARRAY_SIZE(ts72xx_nand_resource),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) void __init ts72xx_register_flash(struct mtd_partition *parts, int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) resource_size_t start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * TS7200 has NOR flash all other TS72xx board have NAND flash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (board_is_ts7200()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ts72xx_nand_resource[0].start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ts72xx_nand_resource[0].end = start + SZ_16M - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ts72xx_nand_data.chip.partitions = parts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ts72xx_nand_data.chip.nr_partitions = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) platform_device_register(&ts72xx_nand_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * RTC M48T86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define TS72XX_RTC_INDEX_PHYS_BASE (EP93XX_CS1_PHYS_BASE + 0x00800000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define TS72XX_RTC_DATA_PHYS_BASE (EP93XX_CS1_PHYS_BASE + 0x01700000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static struct resource ts72xx_rtc_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) DEFINE_RES_MEM(TS72XX_RTC_INDEX_PHYS_BASE, 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) DEFINE_RES_MEM(TS72XX_RTC_DATA_PHYS_BASE, 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct platform_device ts72xx_rtc_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .name = "rtc-m48t86",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .resource = ts72xx_rtc_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .num_resources = ARRAY_SIZE(ts72xx_rtc_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Watchdog (in CPLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define TS72XX_WDT_CONTROL_PHYS_BASE (EP93XX_CS2_PHYS_BASE + 0x03800000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define TS72XX_WDT_FEED_PHYS_BASE (EP93XX_CS2_PHYS_BASE + 0x03c00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static struct resource ts72xx_wdt_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) DEFINE_RES_MEM(TS72XX_WDT_CONTROL_PHYS_BASE, 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) DEFINE_RES_MEM(TS72XX_WDT_FEED_PHYS_BASE, 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static struct platform_device ts72xx_wdt_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .name = "ts72xx-wdt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .resource = ts72xx_wdt_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * ETH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .phy_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * SPI SD/MMC host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define BK3_EN_SDCARD_PHYS_BASE 0x12400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define BK3_EN_SDCARD_PWR 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define BK3_DIS_SDCARD_PWR 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void bk3_mmc_spi_setpower(struct device *dev, unsigned int vdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) void __iomem *pwr_sd = ioremap(BK3_EN_SDCARD_PHYS_BASE, SZ_4K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!pwr_sd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pr_err("Failed to enable SD card power!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) pr_debug("%s: SD card pwr %s VDD:0x%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) !!vdd ? "ON" : "OFF", vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (!!vdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) __raw_writeb(BK3_EN_SDCARD_PWR, pwr_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) __raw_writeb(BK3_DIS_SDCARD_PWR, pwr_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) iounmap(pwr_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct mmc_spi_platform_data bk3_spi_mmc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .detect_delay = 500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .powerup_msecs = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .caps = MMC_CAP_NONREMOVABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .setpower = bk3_mmc_spi_setpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * SPI Bus - SD card access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static struct spi_board_info bk3_spi_board_info[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .modalias = "mmc_spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .platform_data = &bk3_spi_mmc_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .max_speed_hz = 7.4E6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .bus_num = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .chip_select = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .mode = SPI_MODE_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * This is a stub -> the FGPIO[3] pin is not connected on the schematic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * The all work is performed automatically by !SPI_FRAME (SFRM1) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * goes through CPLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static struct gpiod_lookup_table bk3_spi_cs_gpio_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .dev_id = "spi0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static struct ep93xx_spi_info bk3_spi_master __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .use_dma = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * TS72XX support code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Relative to EP93XX_CS1_PHYS_BASE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #define TS73XX_FPGA_LOADER_BASE 0x03c00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static struct resource ts73xx_fpga_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .start = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .end = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static struct platform_device ts73xx_fpga_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .name = "ts73xx-fpga-mgr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .resource = ts73xx_fpga_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .num_resources = ARRAY_SIZE(ts73xx_fpga_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * SPI Bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static struct spi_board_info ts72xx_spi_devices[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .modalias = "tmp122",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .max_speed_hz = 2 * 1000 * 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .bus_num = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .chip_select = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .dev_id = "spi0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* DIO_17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static struct ep93xx_spi_info ts72xx_spi_info __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Intentionally left blank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void __init ts72xx_init_machine(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ep93xx_init_devices();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ts72xx_register_flash(ts72xx_nand_parts, ARRAY_SIZE(ts72xx_nand_parts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) is_ts9420_installed() ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) EP93XX_CS7_PHYS_BASE : EP93XX_CS6_PHYS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) platform_device_register(&ts72xx_rtc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) platform_device_register(&ts72xx_wdt_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ep93xx_register_eth(&ts72xx_eth_data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (board_is_ts7300())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) platform_device_register(&ts73xx_fpga_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) gpiod_add_lookup_table(&ts72xx_spi_cs_gpio_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ARRAY_SIZE(ts72xx_spi_devices));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .atag_offset = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .map_io = ts72xx_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .init_irq = ep93xx_init_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .init_time = ep93xx_timer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .init_machine = ts72xx_init_machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .init_late = ep93xx_init_late,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .restart = ep93xx_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) MACHINE_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * EP93xx I2S audio peripheral handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static struct resource ep93xx_i2s_resource[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) DEFINE_RES_IRQ_NAMED(IRQ_EP93XX_SAI, "spilink i2s slave"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static struct platform_device ep93xx_i2s_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .name = "ep93xx-spilink-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .num_resources = ARRAY_SIZE(ep93xx_i2s_resource),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .resource = ep93xx_i2s_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * BK3 support code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) *************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static struct mtd_partition bk3_nand_parts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .name = "System",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .offset = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .size = 0x01e00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .name = "Data",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .offset = 0x01e00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .size = 0x05f20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .name = "RedBoot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .offset = 0x07d20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .size = 0x002e0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .mask_flags = MTD_WRITEABLE, /* force RO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static void __init bk3_init_machine(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ep93xx_init_devices();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ts72xx_register_flash(bk3_nand_parts, ARRAY_SIZE(bk3_nand_parts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) EP93XX_CS6_PHYS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ep93xx_register_eth(&ts72xx_eth_data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) gpiod_add_lookup_table(&bk3_spi_cs_gpio_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ep93xx_register_spi(&bk3_spi_master, bk3_spi_board_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ARRAY_SIZE(bk3_spi_board_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Configure ep93xx's I2S to use AC97 pins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_I2SONAC97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) platform_device_register(&ep93xx_i2s_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) MACHINE_START(BK3, "Liebherr controller BK3.1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Maintainer: Lukasz Majewski <lukma@denx.de> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .atag_offset = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .map_io = ts72xx_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .init_irq = ep93xx_init_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .init_time = ep93xx_timer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .init_machine = bk3_init_machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .init_late = ep93xx_init_late,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .restart = ep93xx_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) MACHINE_END