| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 
|  | 2 | /* | 
|  | 3 | * arch/arm/mach-ep93xx/snappercl15.c | 
|  | 4 | * Bluewater Systems Snapper CL15 system module | 
|  | 5 | * | 
|  | 6 | * Copyright (C) 2009 Bluewater Systems Ltd | 
|  | 7 | * Author: Ryan Mallon | 
|  | 8 | * | 
|  | 9 | * NAND code adapted from driver by: | 
|  | 10 | *   Andre Renaud <andre@bluewatersys.com> | 
|  | 11 | *   James R. McKaskill | 
|  | 12 | */ | 
|  | 13 |  | 
|  | 14 | #include <linux/platform_device.h> | 
|  | 15 | #include <linux/kernel.h> | 
|  | 16 | #include <linux/init.h> | 
|  | 17 | #include <linux/io.h> | 
|  | 18 | #include <linux/i2c.h> | 
|  | 19 | #include <linux/fb.h> | 
|  | 20 |  | 
|  | 21 | #include <linux/mtd/platnand.h> | 
|  | 22 |  | 
|  | 23 | #include "hardware.h" | 
|  | 24 | #include <linux/platform_data/video-ep93xx.h> | 
|  | 25 | #include "gpio-ep93xx.h" | 
|  | 26 |  | 
|  | 27 | #include <asm/mach-types.h> | 
|  | 28 | #include <asm/mach/arch.h> | 
|  | 29 |  | 
|  | 30 | #include "soc.h" | 
|  | 31 |  | 
|  | 32 | #define SNAPPERCL15_NAND_BASE	(EP93XX_CS7_PHYS_BASE + SZ_16M) | 
|  | 33 |  | 
|  | 34 | #define SNAPPERCL15_NAND_WPN	(1 << 8)  /* Write protect (active low) */ | 
|  | 35 | #define SNAPPERCL15_NAND_ALE	(1 << 9)  /* Address latch */ | 
|  | 36 | #define SNAPPERCL15_NAND_CLE	(1 << 10) /* Command latch */ | 
|  | 37 | #define SNAPPERCL15_NAND_CEN	(1 << 11) /* Chip enable (active low) */ | 
|  | 38 | #define SNAPPERCL15_NAND_RDY	(1 << 14) /* Device ready */ | 
|  | 39 |  | 
|  | 40 | #define NAND_CTRL_ADDR(chip) 	(chip->legacy.IO_ADDR_W + 0x40) | 
|  | 41 |  | 
|  | 42 | static void snappercl15_nand_cmd_ctrl(struct nand_chip *chip, int cmd, | 
|  | 43 | unsigned int ctrl) | 
|  | 44 | { | 
|  | 45 | static u16 nand_state = SNAPPERCL15_NAND_WPN; | 
|  | 46 | u16 set; | 
|  | 47 |  | 
|  | 48 | if (ctrl & NAND_CTRL_CHANGE) { | 
|  | 49 | set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN; | 
|  | 50 |  | 
|  | 51 | if (ctrl & NAND_NCE) | 
|  | 52 | set &= ~SNAPPERCL15_NAND_CEN; | 
|  | 53 | if (ctrl & NAND_CLE) | 
|  | 54 | set |= SNAPPERCL15_NAND_CLE; | 
|  | 55 | if (ctrl & NAND_ALE) | 
|  | 56 | set |= SNAPPERCL15_NAND_ALE; | 
|  | 57 |  | 
|  | 58 | nand_state &= ~(SNAPPERCL15_NAND_CEN | | 
|  | 59 | SNAPPERCL15_NAND_CLE | | 
|  | 60 | SNAPPERCL15_NAND_ALE); | 
|  | 61 | nand_state |= set; | 
|  | 62 | __raw_writew(nand_state, NAND_CTRL_ADDR(chip)); | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 | if (cmd != NAND_CMD_NONE) | 
|  | 66 | __raw_writew((cmd & 0xff) | nand_state, | 
|  | 67 | chip->legacy.IO_ADDR_W); | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | static int snappercl15_nand_dev_ready(struct nand_chip *chip) | 
|  | 71 | { | 
|  | 72 | return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY); | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | static struct mtd_partition snappercl15_nand_parts[] = { | 
|  | 76 | { | 
|  | 77 | .name		= "Kernel", | 
|  | 78 | .offset		= 0, | 
|  | 79 | .size		= SZ_2M, | 
|  | 80 | }, | 
|  | 81 | { | 
|  | 82 | .name		= "Filesystem", | 
|  | 83 | .offset		= MTDPART_OFS_APPEND, | 
|  | 84 | .size		= MTDPART_SIZ_FULL, | 
|  | 85 | }, | 
|  | 86 | }; | 
|  | 87 |  | 
|  | 88 | static struct platform_nand_data snappercl15_nand_data = { | 
|  | 89 | .chip = { | 
|  | 90 | .nr_chips		= 1, | 
|  | 91 | .partitions		= snappercl15_nand_parts, | 
|  | 92 | .nr_partitions		= ARRAY_SIZE(snappercl15_nand_parts), | 
|  | 93 | .chip_delay		= 25, | 
|  | 94 | }, | 
|  | 95 | .ctrl = { | 
|  | 96 | .dev_ready		= snappercl15_nand_dev_ready, | 
|  | 97 | .cmd_ctrl		= snappercl15_nand_cmd_ctrl, | 
|  | 98 | }, | 
|  | 99 | }; | 
|  | 100 |  | 
|  | 101 | static struct resource snappercl15_nand_resource[] = { | 
|  | 102 | { | 
|  | 103 | .start		= SNAPPERCL15_NAND_BASE, | 
|  | 104 | .end		= SNAPPERCL15_NAND_BASE + SZ_4K - 1, | 
|  | 105 | .flags		= IORESOURCE_MEM, | 
|  | 106 | }, | 
|  | 107 | }; | 
|  | 108 |  | 
|  | 109 | static struct platform_device snappercl15_nand_device = { | 
|  | 110 | .name			= "gen_nand", | 
|  | 111 | .id			= -1, | 
|  | 112 | .dev.platform_data	= &snappercl15_nand_data, | 
|  | 113 | .resource		= snappercl15_nand_resource, | 
|  | 114 | .num_resources		= ARRAY_SIZE(snappercl15_nand_resource), | 
|  | 115 | }; | 
|  | 116 |  | 
|  | 117 | static struct ep93xx_eth_data __initdata snappercl15_eth_data = { | 
|  | 118 | .phy_id			= 1, | 
|  | 119 | }; | 
|  | 120 |  | 
|  | 121 | static struct i2c_board_info __initdata snappercl15_i2c_data[] = { | 
|  | 122 | { | 
|  | 123 | /* Audio codec */ | 
|  | 124 | I2C_BOARD_INFO("tlv320aic23", 0x1a), | 
|  | 125 | }, | 
|  | 126 | }; | 
|  | 127 |  | 
|  | 128 | static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = { | 
|  | 129 | }; | 
|  | 130 |  | 
|  | 131 | static struct platform_device snappercl15_audio_device = { | 
|  | 132 | .name		= "snappercl15-audio", | 
|  | 133 | .id		= -1, | 
|  | 134 | }; | 
|  | 135 |  | 
|  | 136 | static void __init snappercl15_register_audio(void) | 
|  | 137 | { | 
|  | 138 | ep93xx_register_i2s(); | 
|  | 139 | platform_device_register(&snappercl15_audio_device); | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | static void __init snappercl15_init_machine(void) | 
|  | 143 | { | 
|  | 144 | ep93xx_init_devices(); | 
|  | 145 | ep93xx_register_eth(&snappercl15_eth_data, 1); | 
|  | 146 | ep93xx_register_i2c(snappercl15_i2c_data, | 
|  | 147 | ARRAY_SIZE(snappercl15_i2c_data)); | 
|  | 148 | ep93xx_register_fb(&snappercl15_fb_info); | 
|  | 149 | snappercl15_register_audio(); | 
|  | 150 | platform_device_register(&snappercl15_nand_device); | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15") | 
|  | 154 | /* Maintainer: Ryan Mallon */ | 
|  | 155 | .atag_offset	= 0x100, | 
|  | 156 | .map_io		= ep93xx_map_io, | 
|  | 157 | .init_irq	= ep93xx_init_irq, | 
|  | 158 | .init_time	= ep93xx_timer_init, | 
|  | 159 | .init_machine	= snappercl15_init_machine, | 
|  | 160 | .init_late	= ep93xx_init_late, | 
|  | 161 | .restart	= ep93xx_restart, | 
|  | 162 | MACHINE_END |