uboot/board/tqc/tqm85xx/nand.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008 Wolfgang Grandegger <wg@denx.de>
   3 *
   4 * (C) Copyright 2006
   5 * Thomas Waehner, TQ-System GmbH, thomas.waehner@tqs.de.
   6 *
   7 * See file CREDITS for list of people who contributed to this
   8 * project.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23 * MA 02111-1307 USA
  24 */
  25
  26#include <common.h>
  27#include <asm/processor.h>
  28#include <asm/immap_85xx.h>
  29#include <asm/processor.h>
  30#include <asm/mmu.h>
  31#include <asm/io.h>
  32#include <asm/errno.h>
  33#include <linux/mtd/mtd.h>
  34#include <linux/mtd/fsl_upm.h>
  35#include <ioports.h>
  36
  37#include <nand.h>
  38
  39DECLARE_GLOBAL_DATA_PTR;
  40
  41extern uint get_lbc_clock (void);
  42
  43/* index of UPM RAM array run pattern for NAND command cycle */
  44#define CONFIG_SYS_NAN_UPM_WRITE_CMD_OFS        0x08
  45
  46/* index of UPM RAM array run pattern for NAND address cycle */
  47#define CONFIG_SYS_NAND_UPM_WRITE_ADDR_OFS      0x10
  48
  49/* Structure for table with supported UPM timings */
  50struct upm_freq {
  51        ulong freq;
  52        const u32 *upm_patt;
  53        uchar gpl4_disable;
  54        uchar ehtr;
  55        uchar ead;
  56};
  57
  58/* NAND-FLASH UPM tables for TQM85XX according to TQM8548.pq.timing.101.doc */
  59
  60/* UPM pattern for bus clock = 25 MHz */
  61static const u32 upm_patt_25[] = {
  62        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
  63        /* 0x00 */ 0x0ff32000, 0x0fa32000, 0x3fb32005, 0xfffffc00,
  64        /* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  65
  66        /* UPM Read Burst RAM array entry -> NAND Write CMD */
  67        /* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
  68        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  69
  70        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
  71        /* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
  72        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  73
  74        /* UPM Write Single RAM array entry -> NAND Write Data */
  75        /* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
  76        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  77
  78        /* UPM Write Burst RAM array entry -> unused */
  79        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  80        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  81        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  82        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
  83
  84        /* UPM Refresh Timer RAM array entry -> unused */
  85        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  86        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  87        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
  88
  89        /* UPM Exception RAM array entry -> unsused */
  90        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
  91};
  92
  93/* UPM pattern for bus clock = 33.3 MHz */
  94static const u32 upm_patt_33[] = {
  95        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
  96        /* 0x00 */ 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
  97        /* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
  98
  99        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 100        /* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
 101        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 102
 103        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 104        /* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
 105        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 106
 107        /* UPM Write Single RAM array entry -> NAND Write Data */
 108        /* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
 109        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 110
 111        /* UPM Write Burst RAM array entry -> unused */
 112        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 113        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 114        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 115        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 116
 117        /* UPM Refresh Timer RAM array entry -> unused */
 118        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 119        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 120        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 121
 122        /* UPM Exception RAM array entry -> unsused */
 123        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 124};
 125
 126/* UPM pattern for bus clock = 41.7 MHz */
 127static const u32 upm_patt_42[] = {
 128        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 129        /* 0x00 */ 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
 130        /* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 131
 132        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 133        /* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
 134        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 135
 136        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 137        /* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
 138        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 139
 140        /* UPM Write Single RAM array entry -> NAND Write Data */
 141        /* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
 142        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 143
 144        /* UPM Write Burst RAM array entry -> unused */
 145        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 146        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 147        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 148        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 149
 150        /* UPM Refresh Timer RAM array entry -> unused */
 151        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 152        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 153        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 154
 155        /* UPM Exception RAM array entry -> unsused */
 156        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 157};
 158
 159/* UPM pattern for bus clock = 50 MHz */
 160static const u32 upm_patt_50[] = {
 161        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 162        /* 0x00 */ 0x0ff33000, 0x0fa33100, 0x0fa33005, 0xfffffc00,
 163        /* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 164
 165        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 166        /* 0x08 */ 0x00ff3d30, 0x00ff3c30, 0x0fff3c35, 0xfffffc00,
 167        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 168
 169        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 170        /* 0x10 */ 0x00f3fd30, 0x00f3fc30, 0x0ff3fc35, 0xfffffc00,
 171        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 172
 173        /* UPM Write Single RAM array entry -> NAND Write Data */
 174        /* 0x18 */ 0x00f33d00, 0x00f33c00, 0x0ff33c05, 0xfffffc00,
 175        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 176
 177        /* UPM Write Burst RAM array entry -> unused */
 178        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 179        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 180        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 181        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 182
 183        /* UPM Refresh Timer RAM array entry -> unused */
 184        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 185        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 186        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 187
 188        /* UPM Exception RAM array entry -> unsused */
 189        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 190};
 191
 192/* UPM pattern for bus clock = 66.7 MHz */
 193static const u32 upm_patt_67[] = {
 194        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 195        /* 0x00 */ 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
 196        /* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 197
 198        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 199        /* 0x08 */ 0x00ff3d30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
 200        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 201
 202        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 203        /* 0x10 */ 0x00f3fd30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
 204        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 205
 206        /* UPM Write Single RAM array entry -> NAND Write Data */
 207        /* 0x18 */ 0x00f33d00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
 208        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 209
 210        /* UPM Write Burst RAM array entry -> unused */
 211        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 212        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 213        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 214        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 215
 216        /* UPM Refresh Timer RAM array entry -> unused */
 217        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 218        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 219        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 220
 221        /* UPM Exception RAM array entry -> unsused */
 222        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 223};
 224
 225/* UPM pattern for bus clock = 83.3 MHz */
 226static const u32 upm_patt_83[] = {
 227        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 228        /* 0x00 */ 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
 229        /* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 230
 231        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 232        /* 0x08 */ 0x00ff3e30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
 233        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 234
 235        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 236        /* 0x10 */ 0x00f3fe30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
 237        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 238
 239        /* UPM Write Single RAM array entry -> NAND Write Data */
 240        /* 0x18 */ 0x00f33e00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
 241        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 242
 243        /* UPM Write Burst RAM array entry -> unused */
 244        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 245        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 246        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 247        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 248
 249        /* UPM Refresh Timer RAM array entry -> unused */
 250        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 251        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 252        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 253
 254        /* UPM Exception RAM array entry -> unsused */
 255        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 256};
 257
 258/* UPM pattern for bus clock = 100 MHz */
 259static const u32 upm_patt_100[] = {
 260        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 261        /* 0x00 */ 0x0ff33100, 0x0fe33000, 0x0fa33200, 0x0fa33000,
 262        /* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 263
 264        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 265        /* 0x08 */ 0x00ff3f30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
 266        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 267
 268        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 269        /* 0x10 */ 0x00f3ff30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
 270        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 271
 272        /* UPM Write Single RAM array entry -> NAND Write Data */
 273        /* 0x18 */ 0x00f33f00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
 274        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 275
 276        /* UPM Write Burst RAM array entry -> unused */
 277        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 278        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 279        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 280        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 281
 282        /* UPM Refresh Timer RAM array entry -> unused */
 283        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 284        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 285        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 286
 287        /* UPM Exception RAM array entry -> unsused */
 288        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 289};
 290
 291/* UPM pattern for bus clock = 133.3 MHz */
 292static const u32 upm_patt_133[] = {
 293        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 294        /* 0x00 */ 0x0ff33100, 0x0fe33000, 0x0fa33300, 0x0fa33000,
 295        /* 0x04 */ 0x0fa33000, 0x0fa33005, 0xfffffc00, 0xfffffc00,
 296
 297        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 298        /* 0x08 */ 0x00ff3f30, 0x00ff3d30, 0x0fff3d30, 0x0fff3c35,
 299        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 300
 301        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 302        /* 0x10 */ 0x00f3ff30, 0x00f3fd30, 0x0ff3fd30, 0x0ff3fc35,
 303        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 304
 305        /* UPM Write Single RAM array entry -> NAND Write Data */
 306        /* 0x18 */ 0x00f33f00, 0x00f33d00, 0x0ff33d00, 0x0ff33c05,
 307        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 308
 309        /* UPM Write Burst RAM array entry -> unused */
 310        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 311        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 312        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 313        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 314
 315        /* UPM Refresh Timer RAM array entry -> unused */
 316        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 317        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 318        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 319
 320        /* UPM Exception RAM array entry -> unsused */
 321        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 322};
 323
 324/* UPM pattern for bus clock = 166.7 MHz */
 325static const u32 upm_patt_167[] = {
 326        /* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
 327        /* 0x00 */ 0x0ff33200, 0x0fe33000, 0x0fa33300, 0x0fa33300,
 328        /* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 329
 330        /* UPM Read Burst RAM array entry -> NAND Write CMD */
 331        /* 0x08 */ 0x00ff3f30, 0x00ff3f30, 0x0fff3e30, 0xffff3c35,
 332        /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 333
 334        /* UPM Read Burst RAM array entry -> NAND Write ADDR */
 335        /* 0x10 */ 0x00f3ff30, 0x00f3ff30, 0x0ff3fe30, 0x0ff3fc35,
 336        /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 337
 338        /* UPM Write Single RAM array entry -> NAND Write Data */
 339        /* 0x18 */ 0x00f33f00, 0x00f33f00, 0x0ff33e00, 0x0ff33c05,
 340        /* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 341
 342        /* UPM Write Burst RAM array entry -> unused */
 343        /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 344        /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 345        /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 346        /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 347
 348        /* UPM Refresh Timer RAM array entry -> unused */
 349        /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 350        /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 351        /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 352
 353        /* UPM Exception RAM array entry -> unsused */
 354        /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 355};
 356
 357/* Supported UPM timings */
 358struct upm_freq upm_freq_table[] = {
 359        /* nominal freq. | ptr to table | GPL4 dis. | EHTR  | EAD */
 360        {25000000, upm_patt_25, 1, 0, 0},
 361        {33333333, upm_patt_33, 1, 0, 0},
 362        {41666666, upm_patt_42, 1, 0, 0},
 363        {50000000, upm_patt_50, 0, 0, 0},
 364        {66666666, upm_patt_67, 0, 0, 0},
 365        {83333333, upm_patt_83, 0, 0, 0},
 366        {100000000, upm_patt_100, 0, 1, 1},
 367        {133333333, upm_patt_133, 0, 1, 1},
 368        {166666666, upm_patt_167, 0, 1, 1},
 369};
 370
 371#define UPM_FREQS (sizeof(upm_freq_table) / sizeof(struct upm_freq))
 372
 373volatile const u32 *nand_upm_patt;
 374
 375/*
 376 * write into UPMB ram
 377 */
 378static void upmb_write (u_char addr, ulong val)
 379{
 380        volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
 381
 382        out_be32 (&lbc->mdr, val);
 383
 384        clrsetbits_be32(&lbc->mbmr, MxMR_MAD_MSK,
 385                        MxMR_OP_WARR | (addr & MxMR_MAD_MSK));
 386
 387        /* dummy access to perform write */
 388        out_8 ((void __iomem *)CONFIG_SYS_NAND_BASE, 0);
 389
 390        clrbits_be32(&lbc->mbmr, MxMR_OP_WARR);
 391}
 392
 393/*
 394 * Initialize UPM for NAND flash access.
 395 */
 396static void nand_upm_setup (volatile ccsr_lbc_t *lbc)
 397{
 398        uint i, j;
 399        uint or3 = CONFIG_SYS_OR3_PRELIM;
 400        uint clock = get_lbc_clock ();
 401
 402        out_be32 (&lbc->br3, 0);        /* disable bank and reset all bits */
 403        out_be32 (&lbc->br3, CONFIG_SYS_BR3_PRELIM);
 404
 405        /*
 406         * Search appropriate UPM table for bus clock.
 407         * If the bus clock exceeds a tolerated value, take the UPM timing for
 408         * the next higher supported frequency to ensure that access works
 409         * (even the access may be slower then).
 410         */
 411        for (i = 0; (i < UPM_FREQS) && (clock > upm_freq_table[i].freq); i++)
 412                ;
 413
 414        if (i >= UPM_FREQS)
 415        /* no valid entry found */
 416                /* take last entry with configuration for max. bus clock */
 417                i--;
 418
 419        if (upm_freq_table[i].ehtr) {
 420                /* EHTR must be set due to TQM8548 timing specification */
 421                or3 |= OR_UPM_EHTR;
 422        }
 423        if (upm_freq_table[i].ead)
 424                /* EAD must be set due to TQM8548 timing specification */
 425                or3 |= OR_UPM_EAD;
 426
 427        out_be32 (&lbc->or3, or3);
 428
 429        /* Assign address of table */
 430        nand_upm_patt = upm_freq_table[i].upm_patt;
 431
 432        for (j = 0; j < 64; j++) {
 433                upmb_write (j, *nand_upm_patt);
 434                nand_upm_patt++;
 435        }
 436
 437        /* Put UPM back to normal operation mode */
 438        if (upm_freq_table[i].gpl4_disable)
 439                /* GPL4 must be disabled according to timing specification */
 440                out_be32 (&lbc->mbmr, MxMR_OP_NORM | MxMR_GPL_x4DIS);
 441
 442        return;
 443}
 444
 445static struct fsl_upm_nand fun = {
 446        .width = 8,
 447        .upm_cmd_offset = 0x08,
 448        .upm_addr_offset = 0x10,
 449        .upm_mar_chip_offset = CONFIG_SYS_NAND_CS_DIST,
 450        .chip_offset = CONFIG_SYS_NAND_CS_DIST,
 451        .chip_delay = NAND_BIG_DELAY_US,
 452        .wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BUFFER,
 453};
 454
 455void board_nand_select_device (struct nand_chip *nand, int chip)
 456{
 457}
 458
 459int board_nand_init (struct nand_chip *nand)
 460{
 461        volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
 462
 463        if (!nand_upm_patt)
 464                nand_upm_setup (lbc);
 465
 466        fun.upm.io_addr = nand->IO_ADDR_R;
 467        fun.upm.mxmr = (void __iomem *)&lbc->mbmr;
 468        fun.upm.mdr = (void __iomem *)&lbc->mdr;
 469        fun.upm.mar = (void __iomem *)&lbc->mar;
 470
 471        return fsl_upm_nand_init (nand, &fun);
 472}
 473