Commit afd7f3d0de7be71ee90478d4dde00dc1a8f9d204

Authored by wdenk
1 parent f18f47f4d4
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

Initial revision

Showing 4 changed files with 3073 additions and 0 deletions Side-by-side Diff

board/bmw/early_init.S
Changes suppressed. Click to show
  1 +#include <ppc_asm.tmpl>
  2 +#include <mpc824x.h>
  3 +#include <ppc_defs.h>
  4 +#include <asm/cache.h>
  5 +#include <asm/mmu.h>
  6 +
  7 +#define USE_V2_INIT 1 /* Jimmy Blair's initialization. */
  8 +
  9 +
  10 +/*
  11 + * Initialize the MMU using BAT entries and hardwired TLB
  12 + * This obviates the need for any code in cpu_init_f which
  13 + * configures the BAT registers.
  14 +*/
  15 +#define MEMORY_MGMT_MSR_BITS (MSR_DR | MSR_IR) /* Data and Inst Relocate */
  16 + .global iommu_setup
  17 + /* Initialize IO/MMU mappings via BAT method Ch. 7,
  18 + * PPC Programming Reference
  19 + */
  20 +iommu_setup:
  21 +
  22 +/* initialize the BAT registers (SPRs 528 - 543 */
  23 +#define mtibat0u(x) mtspr 528,(x) /* SPR 528 (IBAT0U) */
  24 +#define mtibat0l(x) mtspr 529,(x) /* SPR 529 (IBAT0L) */
  25 +#define mtibat1u(x) mtspr 530,(x) /* SPR 530 (IBAT1U) */
  26 +#define mtibat1l(x) mtspr 531,(x) /* SPR 531 (IBAT1L) */
  27 +#define mtibat2u(x) mtspr 532,(x) /* SPR 532 (IBAT2U) */
  28 +#define mtibat2l(x) mtspr 533,(x) /* SPR 533 (IBAT2L) */
  29 +#define mtibat3u(x) mtspr 534,(x) /* SPR 534 (IBAT3U) */
  30 +#define mtibat3l(x) mtspr 535,(x) /* SPR 535 (IBAT3L) */
  31 +#define mtdbat0u(x) mtspr 536,(x) /* SPR 536 (DBAT0U) */
  32 +#define mtdbat0l(x) mtspr 537,(x) /* SPR 537 (DBAT0L) */
  33 +#define mtdbat1u(x) mtspr 538,(x) /* SPR 538 (DBAT1U) */
  34 +#define mtdbat1l(x) mtspr 539,(x) /* SPR 539 (DBAT1L) */
  35 +#define mtdbat2u(x) mtspr 540,(x) /* SPR 540 (DBAT2U) */
  36 +#define mtdbat2l(x) mtspr 541,(x) /* SPR 541 (DBAT2L) */
  37 +#define mtdbat3u(x) mtspr 542,(x) /* SPR 542 (DBAT3U) */
  38 +#define mtdbat3l(x) mtspr 543,(x) /* SPR 543 (DBAT3L) */
  39 +
  40 +
  41 +/* PowerPC processors do not necessarily initialize the BAT
  42 + registers on power-up or reset. So they are in an unknown
  43 + state. Before programming the BATs for the first time, all
  44 + BAT registers MUST have their Vs and Vp bits cleared in the
  45 + upper BAT half in order to avoid possibly having 2 BATs
  46 + valid and mapping the same memory region.
  47 +
  48 + The reason for this is that, even with address translation
  49 + disabled, multiple BAT hits for an address are treated as
  50 + programming errors and can cause unpredictable results.
  51 +
  52 + It is up to the software to make sure it never has 2 IBAT
  53 + mappings or 2 DBAT mappings that are valid for the same
  54 + addresses. It is not necessary to perform this code
  55 + sequence every time the BATs are programmed, only when
  56 + there is a possibility that there may be overlapping BAT
  57 + entries.
  58 +
  59 + When programming the BATs in non-reset scenarios, even if
  60 + you are sure that your new mapping will not temporarily
  61 + create overlapping regions, it is still a wise idea to
  62 + invalidate a BAT entry by setting its upper BAT register to
  63 + all 0's before programming it. This will avoid having a
  64 + BAT marked valid that is in an unknown or transient state
  65 +*/
  66 +
  67 + addis r5,0,0x0000
  68 + mtibat0u(r5)
  69 + mtibat0l(r5)
  70 + mtibat1u(r5)
  71 + mtibat1l(r5)
  72 + mtibat2u(r5)
  73 + mtibat2l(r5)
  74 + mtibat3u(r5)
  75 + mtibat3l(r5)
  76 + mtdbat0u(r5)
  77 + mtdbat0l(r5)
  78 + mtdbat1u(r5)
  79 + mtdbat1l(r5)
  80 + mtdbat2u(r5)
  81 + mtdbat2l(r5)
  82 + mtdbat3u(r5)
  83 + mtdbat3l(r5)
  84 + isync
  85 +
  86 +/*
  87 + * Set up I/D BAT0
  88 + */
  89 + lis r4, CFG_DBAT0L@h
  90 + ori r4, r4, CFG_DBAT0L@l
  91 + lis r3, CFG_DBAT0U@h
  92 + ori r3, r3, CFG_DBAT0U@l
  93 +
  94 + mtdbat0l(r4)
  95 + isync
  96 + mtdbat0u(r3)
  97 + isync
  98 + sync
  99 +
  100 + lis r4, CFG_IBAT0L@h
  101 + ori r4, r4, CFG_IBAT0L@l
  102 + lis r3, CFG_IBAT0U@h
  103 + ori r3, r3, CFG_IBAT0U@l
  104 +
  105 + isync
  106 + mtibat0l(r4)
  107 + isync
  108 + mtibat0u(r3)
  109 + isync
  110 +
  111 +/*
  112 + * Set up I/D BAT1
  113 + */
  114 + lis r4, CFG_IBAT1L@h
  115 + ori r4, r4, CFG_IBAT1L@l
  116 + lis r3, CFG_IBAT1U@h
  117 + ori r3, r3, CFG_IBAT1U@l
  118 +
  119 + isync
  120 + mtibat1l(r4)
  121 + isync
  122 + mtibat1u(r3)
  123 + isync
  124 + mtdbat1l(r4)
  125 + isync
  126 + mtdbat1u(r3)
  127 + isync
  128 + sync
  129 +
  130 +/*
  131 + * Set up I/D BAT2
  132 + */
  133 + lis r4, CFG_IBAT2L@h
  134 + ori r4, r4, CFG_IBAT2L@l
  135 + lis r3, CFG_IBAT2U@h
  136 + ori r3, r3, CFG_IBAT2U@l
  137 +
  138 + isync
  139 + mtibat2l(r4)
  140 + isync
  141 + mtibat2u(r3)
  142 + isync
  143 + mtdbat2l(r4)
  144 + isync
  145 + mtdbat2u(r3)
  146 + isync
  147 + sync
  148 +
  149 +/*
  150 + * Setup I/D BAT3
  151 + */
  152 + lis r4, CFG_IBAT3L@h
  153 + ori r4, r4, CFG_IBAT3L@l
  154 + lis r3, CFG_IBAT3U@h
  155 + ori r3, r3, CFG_IBAT3U@l
  156 +
  157 + isync
  158 + mtibat3l(r4)
  159 + isync
  160 + mtibat3u(r3)
  161 + isync
  162 + mtdbat3l(r4)
  163 + isync
  164 + mtdbat3u(r3)
  165 + isync
  166 + sync
  167 +
  168 +
  169 +/*
  170 + * Invalidate all 64 TLB's
  171 + */
  172 + lis r3, 0
  173 + mtctr r3
  174 + lis r5, 4
  175 +
  176 +tlblp:
  177 + tlbie r3
  178 + sync
  179 + addi r3, r3, 0x1000
  180 + cmplw r3, r5
  181 + blt tlblp
  182 +
  183 + sync
  184 +
  185 +/*
  186 + * Enable Data Translation
  187 + */
  188 + lis r4, MEMORY_MGMT_MSR_BITS@h
  189 + ori r4, r4, MEMORY_MGMT_MSR_BITS@l
  190 + mfmsr r3
  191 + or r3, r4, r3
  192 + mtmsr r3
  193 + isync
  194 + sync
  195 +
  196 + blr
  197 +
  198 +
  199 +#ifdef USE_V2_INIT
  200 +/* #define USER_I_CACHE_ENABLE 1*/ /* Fast rom boots */
  201 +/* Macro for hiadjust and lo */
  202 +#define HIADJ(arg) arg@ha
  203 +#define HI(arg) arg@h
  204 +#define LO(arg) arg@l
  205 +
  206 +#undef LOADPTR
  207 +#define LOADPTR(reg,const32) \
  208 + addis reg,r0,HIADJ(const32); addi reg,reg,LO(const32)
  209 +
  210 +.globl early_init_f
  211 +
  212 +early_init_f:
  213 +/* MPC8245/BMW CPCI System Init
  214 + * Jimmy Blair, Broadcom Corp, 2002.
  215 + */
  216 + mflr r11
  217 + /* Zero-out registers */
  218 +
  219 + addis r0,r0,0
  220 + mtspr SPRG0,r0
  221 + mtspr SPRG1,r0
  222 + mtspr SPRG2,r0
  223 + mtspr SPRG3,r0
  224 +
  225 + /* Set MPU/MSR to a known state. Turn on FP */
  226 +
  227 + LOADPTR (r3, MSR_FP)
  228 + sync
  229 + mtmsr r3
  230 + isync
  231 +
  232 + /* Init the floating point control/status register */
  233 +
  234 + mtfsfi 7,0x0
  235 + mtfsfi 6,0x0
  236 + mtfsfi 5,0x0
  237 + mtfsfi 4,0x0
  238 + mtfsfi 3,0x0
  239 + mtfsfi 2,0x0
  240 + mtfsfi 1,0x0
  241 + mtfsfi 0,0x0
  242 + isync
  243 +
  244 + /* Set MPU/MSR to a known state. Turn off FP */
  245 +
  246 +#if 1 /* Turn off floating point (remove to keep FP on) */
  247 + andi. r3, r3, 0
  248 + sync
  249 + mtmsr r3
  250 + isync
  251 +#endif
  252 +
  253 + /* Init the Segment registers */
  254 +
  255 + andi. r3, r3, 0
  256 + isync
  257 + mtsr 0,r3
  258 + isync
  259 + mtsr 1,r3
  260 + isync
  261 + mtsr 2,r3
  262 + isync
  263 + mtsr 3,r3
  264 + isync
  265 + mtsr 4,r3
  266 + isync
  267 + mtsr 5,r3
  268 + isync
  269 + mtsr 6,r3
  270 + isync
  271 + mtsr 7,r3
  272 + isync
  273 + mtsr 8,r3
  274 + isync
  275 + mtsr 9,r3
  276 + isync
  277 + mtsr 10,r3
  278 + isync
  279 + mtsr 11,r3
  280 + isync
  281 + mtsr 12,r3
  282 + isync
  283 + mtsr 13,r3
  284 + isync
  285 + mtsr 14,r3
  286 + isync
  287 + mtsr 15,r3
  288 + isync
  289 +
  290 + /* Turn off data and instruction cache control bits */
  291 +
  292 + mfspr r3, HID0
  293 + isync
  294 + rlwinm r4, r3, 0, 18, 15 /* r4 has ICE and DCE bits cleared */
  295 + sync
  296 + isync
  297 + mtspr HID0, r4 /* HID0 = r4 */
  298 + isync
  299 +
  300 + /* Get cpu type */
  301 +
  302 + mfspr r28, PVR
  303 + rlwinm r28, r28, 16, 16, 31
  304 +
  305 + /* invalidate the MPU's data/instruction caches */
  306 +
  307 + lis r3, 0x0
  308 + cmpli 0, 0, r28, CPU_TYPE_603
  309 + beq cpuIs603
  310 + cmpli 0, 0, r28, CPU_TYPE_603E
  311 + beq cpuIs603
  312 + cmpli 0, 0, r28, CPU_TYPE_603P
  313 + beq cpuIs603
  314 + cmpli 0, 0, r28, CPU_TYPE_604R
  315 + bne cpuNot604R
  316 +
  317 +cpuIs604R:
  318 + lis r3, 0x0
  319 + mtspr HID0, r3 /* disable the caches */
  320 + isync
  321 + ori r4, r4, 0x0002 /* disable BTAC by setting bit 30 */
  322 +
  323 +cpuNot604R:
  324 + ori r3, r3, (HID0_ICFI |HID0_DCI)
  325 +
  326 +cpuIs603:
  327 + ori r3, r3, (HID0_ICE | HID0_DCE)
  328 + or r4, r4, r3 /* set bits */
  329 + sync
  330 + isync
  331 + mtspr HID0, r4 /* HID0 = r4 */
  332 + andc r4, r4, r3 /* clear bits */
  333 + isync
  334 + cmpli 0, 0, r28, CPU_TYPE_604
  335 + beq cpuIs604
  336 + cmpli 0, 0, r28, CPU_TYPE_604E
  337 + beq cpuIs604
  338 + cmpli 0, 0, r28, CPU_TYPE_604R
  339 + beq cpuIs604
  340 + mtspr HID0, r4
  341 + isync
  342 +
  343 +#ifdef USER_I_CACHE_ENABLE
  344 + b instCacheOn603
  345 +#else
  346 + b cacheEnableDone
  347 +#endif
  348 +
  349 +cpuIs604:
  350 + LOADPTR (r5, 0x1000) /* loop count, 0x1000 */
  351 + mtspr CTR, r5
  352 +loopDelay:
  353 + nop
  354 + bdnz loopDelay
  355 + isync
  356 + mtspr HID0, r4
  357 + isync
  358 +
  359 + /* turn the Instruction cache ON for faster FLASH ROM boots */
  360 +
  361 +#ifdef USER_I_CACHE_ENABLE
  362 +
  363 + ori r4, r4, (HID0_ICE | HID0_ICFI)
  364 + isync /* Synchronize for ICE enable */
  365 + b writeReg4
  366 +instCacheOn603:
  367 + ori r4, r4, (HID0_ICE | HID0_ICFI)
  368 + rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */
  369 +
  370 + /*
  371 + * The setting of the instruction cache enable (ICE) bit must be
  372 + * preceded by an isync instruction to prevent the cache from being
  373 + * enabled or disabled while an instruction access is in progress.
  374 + */
  375 + isync
  376 +writeReg4:
  377 + mtspr HID0, r4 /* Enable Instr Cache & Inval cache */
  378 + cmpli 0, 0, r28, CPU_TYPE_604
  379 + beq cacheEnableDone
  380 + cmpli 0, 0, r28, CPU_TYPE_604E
  381 + beq cacheEnableDone
  382 +
  383 + mtspr HID0, r3 /* using 2 consec instructions */
  384 + /* PPC603 recommendation */
  385 +#endif
  386 +cacheEnableDone:
  387 +
  388 + /* Detect map A or B */
  389 +
  390 + addis r5,r0, HI(CHRP_REG_ADDR)
  391 + addis r6,r0, HI(CHRP_REG_DATA)
  392 + LOADPTR (r7, KAHLUA_ID) /* Kahlua PCI controller ID */
  393 + LOADPTR (r8, BMC_BASE)
  394 +
  395 + stwbrx r8,0,(r5)
  396 + lwbrx r3,0,(r6) /* Store read value to r3 */
  397 + cmp 0,0,r3,r7
  398 + beq cr0, X4_KAHLUA_START
  399 +
  400 + /* It's not an 8240, is it an 8245? */
  401 +
  402 + LOADPTR (r7, KAHLUA2_ID) /* Kahlua PCI controller ID */
  403 + cmp 0,0,r3,r7
  404 + beq cr0, X4_KAHLUA_START
  405 +
  406 + /* Save the PCI controller type in r7 */
  407 + mr r7, r3
  408 +
  409 + LOADPTR (r5, PREP_REG_ADDR)
  410 + LOADPTR (r6, PREP_REG_DATA)
  411 +
  412 +X4_KAHLUA_START:
  413 + /* MPC8245 changes begin here */
  414 + LOADPTR (r3, MPC107_PCI_CMD) /* PCI command reg */
  415 + stwbrx r3,0,r5
  416 + li r4, 6 /* Command register value */
  417 + sthbrx r4, 0, r6
  418 +
  419 + LOADPTR (r3, MPC107_PCI_STAT) /* PCI status reg */
  420 + stwbrx r3,0,r5
  421 + li r4, -1 /* Write-to-clear all bits */
  422 + li r3, 2 /* PCI_STATUS is at +2 offset */
  423 + sthbrx r4, r3, r6
  424 +
  425 + /*-------PROC_INT1_ADR */
  426 +
  427 + LOADPTR (r3, PROC_INT1_ADR) /* Processor I/F Config 1 reg. */
  428 + stwbrx r3,0,r5
  429 + LOADPTR (r4, 0xff141b98)
  430 + stwbrx r4,0,r6
  431 +
  432 + /*-------PROC_INT2_ADR */
  433 +
  434 + LOADPTR (r3, PROC_INT2_ADR) /* Processor I/F Config 2 reg. */
  435 + stwbrx r3,0,r5
  436 + lis r4, 0x2000 /* Flush PCI config writes */
  437 + stwbrx r4,0,r6
  438 +
  439 + LOADPTR (r9, KAHLUA2_ID)
  440 + cmpl 0, 0, r7, r9
  441 + bne L1not8245
  442 +
  443 + /* MIOCR1 -- turn on bit for DLL delay */
  444 +
  445 + LOADPTR (r3, MIOCR1_ADR_X)
  446 + stwbrx r3,0,r5
  447 + li r4, 0x04
  448 + stb r4, MIOCR1_SHIFT(r6)
  449 +
  450 + /* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
  451 + /* SDRAM_CLK_DEL (0x77)*/
  452 +
  453 + LOADPTR (r3, MIOCR2_ADR_X)
  454 + stwbrx r3,0,r5
  455 + li r4, 0x10
  456 + stb r4, MIOCR2_SHIFT(r6)
  457 +
  458 + /* PMCR2 -- set PCI hold delay to <10>b for 33 MHz */
  459 +
  460 + LOADPTR (r3, PMCR2_ADR_X)
  461 + stwbrx r3,0,r5
  462 + li r4, 0x20
  463 + stb r4, PMCR2_SHIFT(r6)
  464 +
  465 + /* Initialize EUMBBAR early since 8245 has internal UART in EUMB */
  466 +
  467 + LOADPTR (r3, EUMBBAR)
  468 + stwbrx r3,0,r5
  469 + LOADPTR (r4, CFG_EUMB_ADDR)
  470 + stwbrx r4,0,r6
  471 +
  472 +L1not8245:
  473 +
  474 + /* Toggle the DLL reset bit in AMBOR */
  475 +
  476 + LOADPTR (r3, AMBOR)
  477 + stwbrx r3,0,r5
  478 + lbz r4, 0(r6)
  479 +
  480 + andi. r4, r4, 0xdf
  481 + stb r4, 0(r6) /* Clear DLL_RESET */
  482 + sync
  483 +
  484 + ori r4, r4, 0x20 /* Set DLL_RESET */
  485 + stb r4, 0(r6)
  486 + sync
  487 +
  488 + andi. r4, r4, 0xdf
  489 + stb r4, 0(r6) /* Clear DLL_RESET */
  490 +
  491 +
  492 + /* Enable RCS2, use supplied timings */
  493 + LOADPTR (r3, ERCR1)
  494 + stwbrx r3,0,r5
  495 + LOADPTR (r4, 0x80408000)
  496 + stwbrx r4,0,r6
  497 +
  498 + /* Disable RCS3 parameters */
  499 + LOADPTR (r3, ERCR2)
  500 + stwbrx r3,0,r5
  501 + LOADPTR (r4, 0x00000000)
  502 + stwbrx r4,0,r6
  503 +
  504 + /* RCS3 at 0x70000000, 64KBytes */
  505 + LOADPTR (r3, ERCR2)
  506 + stwbrx r3,0,r5
  507 + LOADPTR (r4, 0x00000004)
  508 + stwbrx r4,0,r6
  509 +
  510 + /*-------MCCR1 */
  511 +
  512 +#ifdef INCLUDE_ECC
  513 +#define MC_ECC 1
  514 +#else /* INCLUDE_ECC */
  515 +#define MC_ECC 0
  516 +#endif /* INCLUDE_ECC */
  517 +
  518 +#define MC1_ROMNAL 8 /* 0-15 */
  519 +#define MC1_ROMFAL 11 /* 0-31 */
  520 +#define MC1_DBUS_SIZE 0 /* 0-3, read only */
  521 +#define MC1_BURST 0 /* 0-1 */
  522 +#define MC1_MEMGO 0 /* 0-1 */
  523 +#define MC1_SREN 1 /* 0-1 */
  524 +#define MC1_RAM_TYPE 0 /* 0-1 */
  525 +#define MC1_PCKEN MC_ECC /* 0-1 */
  526 +#define MC1_BANKBITS 0x5555 /* 2 bits/bank 7-0 */
  527 +
  528 + LOADPTR (r3, MEM_CONT1_ADR) /* Set MCCR1 (F0) */
  529 + stwbrx r3,0,r5
  530 + LOADPTR(r4, \
  531 + MC1_ROMNAL << 28 | MC1_ROMFAL << 23 | \
  532 + MC1_DBUS_SIZE << 21 | MC1_BURST << 20 | \
  533 + MC1_MEMGO << 19 | MC1_SREN << 18 | \
  534 + MC1_RAM_TYPE << 17 | MC1_PCKEN << 16 )
  535 + li r3, MC1_BANKBITS
  536 + cmpl 0, 0, r7, r9 /* Check for Kahlua2 */
  537 + bne BankBitsAdd
  538 + cmpli 0, 0, r3, 0x5555
  539 + beq K2BankBitsHack /* On 8245, 5555 ==> 0 */
  540 +BankBitsAdd:
  541 + ori r4, r3, 0
  542 +K2BankBitsHack:
  543 + stwbrx r4, 0, r6
  544 +
  545 + /*------- MCCR2 */
  546 +
  547 +#define MC2_TS_WAIT_TIMER 0 /* 0-7 */
  548 +#define MC2_ASRISE 8 /* 0-15 */
  549 +#define MC2_ASFALL 4 /* 0-15 */
  550 +#define MC2_INLINE_PAR_NOT_ECC 0 /* 0-1 */
  551 +#define MC2_WRITE_PARITY_CHK_EN MC_ECC /* 0-1 */
  552 +#define MC2_INLRD_PARECC_CHK_EN MC_ECC /* 0-1 */
  553 +#define MC2_ECC_EN 0 /* 0-1 */
  554 +#define MC2_EDO 0 /* 0-1 */
  555 +/*
  556 +* N.B. This refresh interval looks good up to 85 MHz with Hynix SDRAM.
  557 +* May need to be decreased for 100 MHz
  558 +*/
  559 +#define MC2_REFINT 0x3a5 /* 0-0x3fff */
  560 +#define MC2_RSV_PG 0 /* 0-1 */
  561 +#define MC2_RMW_PAR MC_ECC /* 0-1 */
  562 +
  563 + LOADPTR (r3, MEM_CONT2_ADR) /* Set MCCR2 (F4) */
  564 + stwbrx r3,0,r5
  565 + LOADPTR(r4, \
  566 + MC2_TS_WAIT_TIMER << 29 | MC2_ASRISE << 25 | \
  567 + MC2_ASFALL << 21 | MC2_INLINE_PAR_NOT_ECC << 20 | \
  568 + MC2_WRITE_PARITY_CHK_EN << 19 | \
  569 + MC2_INLRD_PARECC_CHK_EN << 18 | \
  570 + MC2_ECC_EN << 17 | MC2_EDO << 16 | \
  571 + MC2_REFINT << 2 | MC2_RSV_PG << 1 | MC2_RMW_PAR)
  572 + cmpl 0, 0, r7, r9 /* Check for Kahlua2 */
  573 + bne notK2
  574 + /* clear Kahlua2 reserved bits */
  575 + LOADPTR (r3, 0xfffcffff)
  576 + and r4, r4, r3
  577 +notK2:
  578 + stwbrx r4,0,r6
  579 +
  580 + /*------- MCCR3 */
  581 +
  582 +#define MC_BSTOPRE 0x079 /* 0-0x7ff */
  583 +
  584 +#define MC3_BSTOPRE_U (MC_BSTOPRE >> 4 & 0xf)
  585 +#define MC3_REFREC 8 /* 0-15 */
  586 +#define MC3_RDLAT (4+MC_ECC) /* 0-15 */
  587 +#define MC3_CPX 0 /* 0-1 */
  588 +#define MC3_RAS6P 0 /* 0-15 */
  589 +#define MC3_CAS5 0 /* 0-7 */
  590 +#define MC3_CP4 0 /* 0-7 */
  591 +#define MC3_CAS3 0 /* 0-7 */
  592 +#define MC3_RCD2 0 /* 0-7 */
  593 +#define MC3_RP1 0 /* 0-7 */
  594 +
  595 + LOADPTR (r3, MEM_CONT3_ADR) /* Set MCCR3 (F8) */
  596 + stwbrx r3,0,r5
  597 + LOADPTR(r4, \
  598 + MC3_BSTOPRE_U << 28 | MC3_REFREC << 24 | \
  599 + MC3_RDLAT << 20 | MC3_CPX << 19 | \
  600 + MC3_RAS6P << 15 | MC3_CAS5 << 12 | MC3_CP4 << 9 | \
  601 + MC3_CAS3 << 6 | MC3_RCD2 << 3 | MC3_RP1)
  602 + cmpl 0, 0, r7, r9 /* Check for Kahlua2 */
  603 + bne notK2b
  604 + /* clear Kahlua2 reserved bits */
  605 + LOADPTR (r3, 0xff000000)
  606 + and r4, r4, r3
  607 +notK2b:
  608 + stwbrx r4,0,r6
  609 +
  610 + /*------- MCCR4 */
  611 +
  612 +#define MC4_PRETOACT 3 /* 0-15 */
  613 +#define MC4_ACTOPRE 5 /* 0-15 */
  614 +#define MC4_WMODE 0 /* 0-1 */
  615 +#define MC4_INLINE MC_ECC /* 0-1 */
  616 +#define MC4_REGISTERED (1-MC_ECC) /* 0-1 */
  617 +#define MC4_BSTOPRE_UU (MC_BSTOPRE >> 8 & 3)
  618 +#define MC4_REGDIMM 0 /* 0-1 */
  619 +#define MC4_SDMODE_CAS 2 /* 0-7 */
  620 +#define MC4_DBUS_RCS1 1 /* 0-1, 8-bit */
  621 +#define MC4_SDMODE_WRAP 0 /* 0-1 */
  622 +#define MC4_SDMODE_BURST 2 /* 0-7 */
  623 +#define MC4_ACTORW 3 /* 0-15 */
  624 +#define MC4_BSTOPRE_L (MC_BSTOPRE & 0xf)
  625 +
  626 + LOADPTR (r3, MEM_CONT4_ADR) /* Set MCCR4 (FC) */
  627 + stwbrx r3,0,r5
  628 + LOADPTR(r4, \
  629 + MC4_PRETOACT << 28 | MC4_ACTOPRE << 24 | \
  630 + MC4_WMODE << 23 | MC4_INLINE << 22 | \
  631 + MC4_REGISTERED << 20 | MC4_BSTOPRE_UU << 18 | \
  632 + MC4_DBUS_RCS1 << 17 | \
  633 + MC4_REGDIMM << 15 | MC4_SDMODE_CAS << 12 | \
  634 + MC4_SDMODE_WRAP << 11 | MC4_SDMODE_BURST << 8 | \
  635 + MC4_ACTORW << 4 | MC4_BSTOPRE_L)
  636 + cmpl 0, 0, r7, r9 /* Check for Kahlua 2 */
  637 + bne notK2c
  638 + /* Turn on Kahlua2 extended ROM space */
  639 + LOADPTR (r3, 0x00200000)
  640 + or r4, r4, r3
  641 +notK2c:
  642 + stwbrx r4,0,r6
  643 +
  644 +#ifdef INCLUDE_ECC
  645 + /*------- MEM_ERREN1 */
  646 +
  647 + LOADPTR (r3, MEM_ERREN1_ADR) /* Set MEM_ERREN1 (c0) */
  648 + stwbrx r3,0,r5
  649 + lwbrx r4,0,r6
  650 + ori r4,r4,4 /* Set MEM_PERR_EN */
  651 + stwbrx r4,0,r6
  652 +#endif /* INCLUDE_ECC */
  653 +
  654 + /*------- MSAR/MEAR */
  655 +
  656 + LOADPTR (r3, MEM_START1_ADR) /* Set MSAR1 (80) */
  657 + stwbrx r3,0,r5
  658 + LOADPTR (r4, 0xc0804000)
  659 + stwbrx r4,0,r6
  660 +
  661 + LOADPTR (r3, MEM_START2_ADR) /* Set MSAR2 (84) */
  662 + stwbrx r3,0,r5
  663 + LOADPTR (r4, 0xc0804000)
  664 + stwbrx r4,0,r6
  665 +
  666 + LOADPTR (r3, XMEM_START1_ADR) /* Set MESAR1 (88) */
  667 + stwbrx r3,0,r5
  668 + LOADPTR (r4, 0x00000000)
  669 + stwbrx r4,0,r6
  670 +
  671 + LOADPTR (r3, XMEM_START2_ADR) /* Set MESAR2 (8c) */
  672 + stwbrx r3,0,r5
  673 + LOADPTR (r4, 0x01010101)
  674 + stwbrx r4,0,r6
  675 +
  676 + LOADPTR (r3, MEM_END1_ADR) /* Set MEAR1 (90) */
  677 + stwbrx r3,0,r5
  678 + LOADPTR (r4, 0xffbf7f3f)
  679 + stwbrx r4,0,r6
  680 +
  681 + LOADPTR (r3, MEM_END2_ADR) /* Set MEAR2 (94) */
  682 + stwbrx r3,0,r5
  683 + LOADPTR (r4, 0xffbf7f3f)
  684 + stwbrx r4,0,r6
  685 +
  686 + LOADPTR (r3, XMEM_END1_ADR) /* MEEAR1 (98) */
  687 + stwbrx r3,0,r5
  688 + LOADPTR (r4, 0x00000000)
  689 + stwbrx r4,0,r6
  690 +
  691 + LOADPTR (r3, XMEM_END2_ADR) /* MEEAR2 (9c) */
  692 + stwbrx r3,0,r5
  693 + LOADPTR (r4, 0x01010101)
  694 + stwbrx r4,0,r6
  695 +
  696 + /*-------ODCR */
  697 +
  698 + LOADPTR (r3, ODCR_ADR_X) /* Set ODCR */
  699 + stwbrx r3,0,r5
  700 +
  701 + li r4, 0x7f
  702 + stb r4, ODCR_SHIFT(r6) /* ODCR is at +3 offset */
  703 +
  704 + /*-------MBEN */
  705 +
  706 + LOADPTR (r3, MEM_EN_ADR) /* Set MBEN (a0) */
  707 + stwbrx r3,0,r5
  708 + li r4, 0x01 /* Enable bank 0 */
  709 + stb r4, 0(r6) /* MBEN is at +0 offset */
  710 +
  711 +#if 0 /* Jimmy: I think page made is broken */
  712 + /*-------PGMAX */
  713 +
  714 + LOADPTR (r3, MPM_ADR_X)
  715 + stwbrx r3,0,r5
  716 + li r4, 0x32
  717 + stb r4, MPM_SHIFT(r6) /* PAGE_MODE is at +3 offset */
  718 +#endif
  719 +
  720 + /* Wait before initializing other registers */
  721 +
  722 + lis r4,0x0001
  723 + mtctr r4
  724 +
  725 +KahluaX4wait200us:
  726 + bdnz KahluaX4wait200us
  727 +
  728 + /* Set MEMGO bit */
  729 +
  730 + LOADPTR (r3, MEM_CONT1_ADR) /* MCCR1 (F0) |= PGMAX */
  731 + stwbrx r3,0,r5
  732 + lwbrx r4,0,r6 /* old MCCR1 */
  733 + oris r4,r4,0x0008 /* MEMGO=1 */
  734 + stwbrx r4, 0, r6
  735 +
  736 + /* Wait again */
  737 +
  738 + addis r4,r0,0x0002
  739 + ori r4,r4,0xffff
  740 +
  741 + mtctr r4
  742 +
  743 +KahluaX4wait8ref:
  744 + bdnz KahluaX4wait8ref
  745 +
  746 + sync
  747 + eieio
  748 + mtlr r11
  749 + blr
  750 +
  751 +#else /* USE_V2_INIT */
  752 +
  753 +
  754 +
  755 +/* U-Boot works, but memory will not run reliably for all address ranges.
  756 + * Early U-Boot Working init, but 2.4.19 kernel will crash since memory is not
  757 + * initialized correctly. Could work if debugged.
  758 + */
  759 +/* PCI Support routines */
  760 +
  761 + .globl __pci_config_read_32
  762 +__pci_config_read_32:
  763 + lis r4, 0xfec0
  764 + stwbrx r3, r0, r4
  765 + sync
  766 + lis r4, 0xfee0
  767 + lwbrx r3, 0, r4
  768 + blr
  769 + .globl __pci_config_read_16
  770 +__pci_config_read_16:
  771 + lis r4, 0xfec0
  772 + andi. r5, r3, 2
  773 + stwbrx r3, r0, r4
  774 + sync
  775 + oris r4, r5, 0xfee0
  776 + lhbrx r3, r0, r4
  777 + blr
  778 + .globl __pci_config_read_8
  779 +__pci_config_read_8:
  780 + lis r4, 0xfec0
  781 + andi. r5, r3, 3
  782 + stwbrx r3, r0, r4
  783 + sync
  784 + oris r4, r5, 0xfee0
  785 + lbz r3, 0(4)
  786 + blr
  787 + .globl __pci_config_write_32
  788 +__pci_config_write_32:
  789 + lis r5, 0xfec0
  790 + stwbrx r3, r0, r5
  791 + sync
  792 + lis r5, 0xfee0
  793 + stwbrx r4, r0, r5
  794 + sync
  795 + blr
  796 + .globl __pci_config_write_16
  797 +__pci_config_write_16:
  798 + lis r5, 0xfec0
  799 + andi. r6, r3, 2
  800 + stwbrx r3, r0, 5
  801 + sync
  802 + oris r5, r6, 0xfee0
  803 + sthbrx r4, r0, r5
  804 + sync
  805 + blr
  806 + .globl __pci_config_write_8
  807 +__pci_config_write_8:
  808 + lis r5, 0xfec0
  809 + andi. r6, r3, 3
  810 + stwbrx r3, r0, r5
  811 + sync
  812 + oris r5, r6, 0xfee0
  813 + stb r4, 0(r5)
  814 + sync
  815 + blr
  816 + .globl in_8
  817 +in_8:
  818 + oris r3, r3, 0xfe00
  819 + lbz r3,0(r3)
  820 + blr
  821 + .globl in_16
  822 +in_16:
  823 + oris r3, r3, 0xfe00
  824 + lhbrx r3, 0, r3
  825 + blr
  826 + .globl in_16_ne
  827 +in_16_ne:
  828 + oris r3, r3, 0xfe00
  829 + lhzx r3, 0, r3
  830 + blr
  831 + .globl in_32
  832 +in_32:
  833 + oris r3, r3, 0xfe00
  834 + lwbrx r3, 0, r3
  835 + blr
  836 + .globl out_8
  837 +out_8:
  838 + oris r3, r3, 0xfe00
  839 + stb r4, 0(r3)
  840 + eieio
  841 + blr
  842 + .globl out_16
  843 +out_16:
  844 + oris r3, r3, 0xfe00
  845 + sthbrx r4, 0, r3
  846 + eieio
  847 + blr
  848 + .globl out_16_ne
  849 +out_16_ne:
  850 + oris r3, r3, 0xfe00
  851 + sth r4, 0(r3)
  852 + eieio
  853 + blr
  854 + .globl out_32
  855 +out_32:
  856 + oris r3, r3, 0xfe00
  857 + stwbrx r4, 0, r3
  858 + eieio
  859 + blr
  860 + .globl read_8
  861 +read_8:
  862 + lbz r3,0(r3)
  863 + blr
  864 + .globl read_16
  865 +read_16:
  866 + lhbrx r3, 0, r3
  867 + blr
  868 + .globl read_32
  869 +read_32:
  870 + lwbrx r3, 0, r3
  871 + blr
  872 + .globl read_32_ne
  873 +read_32_ne:
  874 + lwz r3, 0(r3)
  875 + blr
  876 + .globl write_8
  877 +write_8:
  878 + stb r4, 0(r3)
  879 + eieio
  880 + blr
  881 + .globl write_16
  882 +write_16:
  883 + sthbrx r4, 0, r3
  884 + eieio
  885 + blr
  886 + .globl write_32
  887 +write_32:
  888 + stwbrx r4, 0, r3
  889 + eieio
  890 + blr
  891 + .globl write_32_ne
  892 +write_32_ne:
  893 + stw r4, 0(r3)
  894 + eieio
  895 + blr
  896 +
  897 +
  898 +.globl early_init_f
  899 +
  900 +early_init_f:
  901 + mflr r11
  902 + lis r10, 0x8000
  903 +
  904 + /* PCI Latency Timer */
  905 + li r4, 0x0d
  906 + ori r3, r10, PLTR@l
  907 + bl __pci_config_write_8
  908 +
  909 + /* Cache Line Size */
  910 + li r4, 0x08
  911 + ori r3, r10, PCLSR@l
  912 + bl __pci_config_write_8
  913 +
  914 + /* PCI Cmd */
  915 + li r4, 6
  916 + ori r3, r10, PCICR@l
  917 + bl __pci_config_write_16
  918 +
  919 +#if 1
  920 + /* PCI Stat */
  921 + ori r3, r10, PCISR@l
  922 + bl __pci_config_read_16
  923 + ori r4, r4, 0xffff
  924 + ori r3, r10, PCISR@l
  925 + bl __pci_config_write_16
  926 +#endif
  927 +
  928 + /* PICR1 */
  929 + lis r4, 0xff14
  930 + ori r4, r4, 0x1b98
  931 + ori r3, r10, PICR1@l
  932 + bl __pci_config_write_32
  933 +
  934 +
  935 + /* PICR2 */
  936 + lis r4, 0x0404
  937 + ori r4, r4, 0x0004
  938 + ori r3, r10, PICR2@l
  939 + bl __pci_config_write_32
  940 +
  941 + /* MIOCR1 */
  942 + li r4, 0x04
  943 + ori r3, r10, MIOCR1@l
  944 + bl __pci_config_write_8
  945 +
  946 + /* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
  947 + /* SDRAM_CLK_DEL (0x77)*/
  948 + li r4, 0x10
  949 + ori r3, r10, MIOCR2@l
  950 + bl __pci_config_write_8
  951 +
  952 + /* EUMBBAR */
  953 + lis r4, 0xfc00
  954 + ori r3, r10, EUMBBAR@l
  955 + bl __pci_config_write_32
  956 +
  957 + /* AMBOR */
  958 +
  959 + /* Even if Address Map B is not being used (though it should),
  960 + * the memory DLL needs to be cleared/set/cleared before using memory.
  961 + */
  962 +
  963 + ori r3, r10, AMBOR@l
  964 + bl __pci_config_read_8 /* get Current bits */
  965 +
  966 + andi. r4, r4, 0xffdf
  967 + ori r3, r10, AMBOR@l
  968 + bl __pci_config_write_16 /* Clear DLL_RESET */
  969 +
  970 + ori r4, r4, 0x0020
  971 + ori r3, r10, AMBOR@l
  972 + bl __pci_config_write_16 /* Set DLL_RESET */
  973 +
  974 + andi. r4, r4, 0xffdf
  975 + ori r3, r10, AMBOR@l
  976 + bl __pci_config_write_16 /* Clear DLL_RESET */
  977 +
  978 + /* ERCR1 */
  979 + lis r4, 0x8040 /* Enable RCS2, use supplied timings */
  980 + ori r4, r4, 0x8000
  981 + ori r3, r10, ERCR1@l
  982 + bl __pci_config_write_32
  983 +
  984 + /* ERCR2 */
  985 + lis r4, 0x0000 /* Disable RCS3 parms */
  986 + ori r4, r4, 0x0000
  987 + ori r3, r10, ERCR2@l
  988 + bl __pci_config_write_32
  989 +
  990 + /* ERCR3 */
  991 + lis r4, 0x0000 /* RCS3 at 0x70000000, 64K bytes */
  992 + ori r4, r4, 0x0004
  993 + ori r3, r10, ERCR2@l
  994 + bl __pci_config_write_32
  995 +
  996 + /* Preserve memgo bit */
  997 + /* MCCR1 */
  998 +
  999 +/* lis r4, 0x75a8 / Safe Local ROM = 11+3 clocks */
  1000 + lis r4, 0x75a0 /* Safe Local ROM = 11+3 clocks */
  1001 +/* lis r4, 0x73a0 / Fast Local ROM = 7+3 clocks */
  1002 +/* oris r4, r4, 0x0010 / Burst ROM/Flash enable */
  1003 +/* oris r4, r4, 0x0004 / Self-refresh enable */
  1004 +
  1005 +/* ori r4,r4,0xFFFF / 16Mbit 2bank SDRAM */
  1006 +/* ori r4,r4,0xAAAA / 256Mbit 4bank SDRAM (8245 only) */
  1007 +/* ori r4,r4,0x5555 / 64Mbit 2bank SDRAM */
  1008 + ori r4,r4,0x0000 /* 64Mbit 4bank SDRAM */
  1009 +
  1010 + ori r3, r10, MCCR1@l
  1011 + bl __pci_config_write_32
  1012 +
  1013 + /* MCCR2 */
  1014 +
  1015 + lis r4,0x0000
  1016 +/* oris r4,r4,0x4000 / TS_WAIT_TIMER = 3 clocks */
  1017 + oris r4,r4,0x1000 /* ASRISE = 8 clocks */
  1018 + oris r4,r4,0x0080 /* ASFALL = 8 clocks */
  1019 +/* oris r4,r4,0x0010 / SDRAM Parity (else ECC) */
  1020 +/* oris r4,r4,0x0008 / Write parity check */
  1021 +/* oris r4,r4,0x0004 / SDRAM inline reads */
  1022 +
  1023 +
  1024 +/* Select a refresh rate; it needs to match the bus speed; if too */
  1025 +/* slow, data may be lost; if too fast, performance is lost. We */
  1026 +/* use the fastest value so we run at all speeds. */
  1027 +/* Refresh = (15600ns/busclk) - (213 (see UM)). */
  1028 +
  1029 +/* ori r4,r4,0x1d2c / 133 MHz mem bus = 1867 */
  1030 +/* ori r4,r4,0x150c / 100 MHz mem bus = 1347 */
  1031 +/* ori r4,r4,0x10fc / 83 MHz mem bus = 1087 */
  1032 +/* ori r4,r4,0x0cc4 / 66 MHz mem bus = 817 */
  1033 + ori r4,r4,0x04cc /* 33 MHz mem bus (SAFE) = 307 */
  1034 +/* ori r4,r4,0x0002 / Reserve a page */
  1035 +/* ori r4,r4,0x0001 / RWM parity */
  1036 +
  1037 + ori r3, r10, MCCR2@l
  1038 + bl __pci_config_write_32
  1039 +
  1040 +
  1041 + /* MCCR3 */
  1042 + lis r4,0x0000 /* BSTOPRE_M = 7 (see A/N) */
  1043 + oris r4,r4,0x0500 /* REFREC = 8 clocks */
  1044 + ori r3, r10, MCCR3@l
  1045 + bl __pci_config_write_32
  1046 +
  1047 + /* MCCR4 */ /* Turn on registered buffer mode */
  1048 + lis r4, 0x2000 /* PRETOACT = 3 clocks */
  1049 + oris r4,r4,0x0400 /* ACTOPRE = 5 clocks */
  1050 +/* oris r4,r4,0x0080 / Enable 8-beat burst (32-bit bus) */
  1051 +/* oris r4,r4,0x0040 / Enable Inline ECC/Parity */
  1052 + oris r4,r4,0x0020 /* EXTROM enabled */
  1053 + oris r4,r4,0x0010 /* Registered buffers */
  1054 +/* oris r4,r4,0x0000 / BSTOPRE_U = 0 (see A/N) */
  1055 + oris r4,r4,0x0002 /* DBUS_SIZ[2] (8 bit on RCS1) */
  1056 +
  1057 +/* ori r4,r4,0x8000 / Registered DIMMs */
  1058 + ori r4,r4,0x2000 /*CAS Latency (CL=3) (see RDLAT) */
  1059 +/* ori r4,r4,0x2000 / CAS Latency (CL=2) (see RDLAT) */
  1060 +/* ori r4,r4,0x0300 / Sequential wrap/8-beat burst */
  1061 + ori r4,r4,0x0200 /* Sequential wrap/4-beat burst */
  1062 + ori r4,r4,0x0030 /* ACTORW = 3 clocks */
  1063 + ori r4,r4,0x0009 /* BSTOPRE_L = 9 (see A/N) */
  1064 +
  1065 + ori r3, r10, MCCR4@l
  1066 + bl __pci_config_write_32
  1067 +
  1068 + /* MSAR1 */
  1069 + lis r4, 0xc0804000@h
  1070 + ori r4, r4, 0xc0804000@l
  1071 + ori r3, r10, MSAR1@l
  1072 + bl __pci_config_write_32
  1073 +
  1074 + /* MSAR2 */
  1075 + lis r4, 0xc0804000@h
  1076 + ori r4, r4, 0xc0804000@l
  1077 + ori r3, r10, MSAR2@l
  1078 + bl __pci_config_write_32
  1079 +
  1080 + /* MESAR1 */
  1081 + lis r4, 0x00000000@h
  1082 + ori r4, r4, 0x00000000@l
  1083 + ori r3, r10, EMSAR1@l
  1084 + bl __pci_config_write_32
  1085 +
  1086 + /* MESAR2 */
  1087 + lis r4, 0x01010101@h
  1088 + ori r4, r4, 0x01010101@l
  1089 + ori r3, r10, EMSAR2@l
  1090 + bl __pci_config_write_32
  1091 +
  1092 + /* MEAR1 */
  1093 + lis r4, 0xffbf7f3f@h
  1094 + ori r4, r4, 0xffbf7f3f@l
  1095 + ori r3, r10, MEAR1@l
  1096 + bl __pci_config_write_32
  1097 +
  1098 + /* MEAR2 */
  1099 + lis r4, 0xffbf7f3f@h
  1100 + ori r4, r4, 0xffbf7f3f@l
  1101 + ori r3, r10, MEAR2@l
  1102 + bl __pci_config_write_32
  1103 +
  1104 + /* MEEAR1 */
  1105 + lis r4, 0x00000000@h
  1106 + ori r4, r4, 0x00000000@l
  1107 + ori r3, r10, EMEAR1@l
  1108 + bl __pci_config_write_32
  1109 +
  1110 + /* MEEAR2 */
  1111 + lis r4, 0x01010101@h
  1112 + ori r4, r4, 0x01010101@l
  1113 + ori r3, r10, EMEAR2@l
  1114 + bl __pci_config_write_32
  1115 +
  1116 + /* ODCR */
  1117 + li r4, 0x7f
  1118 + ori r3, r10, ODCR@l
  1119 + bl __pci_config_write_8
  1120 +
  1121 + /* MBER */
  1122 + li r4, 0x01
  1123 + ori r3, r10, MBER@l
  1124 + bl __pci_config_write_8
  1125 +
  1126 + /* Page CTR aka PGMAX */
  1127 + li r4, 0x32
  1128 + ori r3, r10, 0x70
  1129 + bl __pci_config_write_8
  1130 +
  1131 +#if 0
  1132 + /* CLK Drive */
  1133 + ori r4, r10, 0xfc01 /* Top bit will be ignored */
  1134 + ori r3, r10, 0x74
  1135 + bl __pci_config_write_16
  1136 +#endif
  1137 +
  1138 + /* delay */
  1139 + lis r7, 1
  1140 + mtctr r7
  1141 +label1: bdnz label1
  1142 +
  1143 + /* Set memgo bit */
  1144 + /* MCCR1 */
  1145 + ori r3, r10, MCCR1@l
  1146 + bl __pci_config_read_32
  1147 + lis r7, 0x0008
  1148 + or r4, r3, r7
  1149 + ori r3, r10, MCCR1@l
  1150 + bl __pci_config_write_32
  1151 +
  1152 + /* delay again */
  1153 + lis r7, 1
  1154 + mtctr r7
  1155 +label2: bdnz label2
  1156 +#if 0
  1157 +/* DEBUG: Infinite loop, write then read */
  1158 +loop:
  1159 + lis r7, 0xffff
  1160 + mtctr r7
  1161 + li r3, 0x5004
  1162 + lis r4, 0xa0a0
  1163 + ori r4, r4, 0x5050
  1164 + bl write_32_ne
  1165 + li r3, 0x5004
  1166 + bl read_32_ne
  1167 + bdnz loop
  1168 +#endif
  1169 + mtlr r11
  1170 + blr
  1171 +#endif
board/gw8260/flash.c
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Marius Groeger <mgroeger@sysgo.de>
  4 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  5 + *
  6 + * (C) Copyright 2000, 2001
  7 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  8 + *
  9 + * (C) Copyright 2001
  10 + * Advent Networks, Inc. <http://www.adventnetworks.com>
  11 + * Oliver Brown <oliverb@alumni.utexas.net>
  12 + *
  13 + *--------------------------------------------------------------------
  14 + * See file CREDITS for list of people who contributed to this
  15 + * project.
  16 + *
  17 + * This program is free software; you can redistribute it and/or
  18 + * modify it under the terms of the GNU General Public License as
  19 + * published by the Free Software Foundation; either version 2 of
  20 + * the License, or (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30 + * MA 02111-1307 USA
  31 + */
  32 +
  33 +/*********************************************************************/
  34 +/* DESCRIPTION:
  35 + * This file contains the flash routines for the GW8260 board.
  36 + *
  37 + *
  38 + *
  39 + * MODULE DEPENDENCY:
  40 + * None
  41 + *
  42 + *
  43 + * RESTRICTIONS/LIMITATIONS:
  44 + *
  45 + * Only supports the following flash devices:
  46 + * AMD 29F080B
  47 + * AMD 29F016D
  48 + *
  49 + * Copyright (c) 2001, Advent Networks, Inc.
  50 + *
  51 + */
  52 +/*********************************************************************/
  53 +
  54 +#include <common.h>
  55 +#include <mpc8260.h>
  56 +
  57 +flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
  58 +
  59 +static ulong flash_get_size (vu_long *addr, flash_info_t *info);
  60 +static int write_word (flash_info_t *info, ulong dest, ulong data);
  61 +
  62 +/*********************************************************************/
  63 +/* functions */
  64 +/*********************************************************************/
  65 +
  66 +/*********************************************************************/
  67 +/* NAME: flash_init() - initializes flash banks */
  68 +/* */
  69 +/* DESCRIPTION: */
  70 +/* This function initializes the flash bank(s). */
  71 +/* */
  72 +/* RETURNS: */
  73 +/* The size in bytes of the flash */
  74 +/* */
  75 +/* RESTRICTIONS/LIMITATIONS: */
  76 +/* */
  77 +/* */
  78 +/*********************************************************************/
  79 +unsigned long flash_init (void)
  80 +{
  81 + unsigned long size;
  82 + int i;
  83 +
  84 + /* Init: no FLASHes known */
  85 + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  86 + flash_info[i].flash_id = FLASH_UNKNOWN;
  87 + }
  88 +
  89 + /* for now, only support the 4 MB Flash SIMM */
  90 + size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]);
  91 +
  92 + /*
  93 + * protect monitor and environment sectors
  94 + */
  95 +
  96 +#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
  97 + flash_protect(FLAG_PROTECT_SET,
  98 + CFG_MONITOR_BASE,
  99 + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
  100 + &flash_info[0]);
  101 +#endif
  102 +
  103 +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
  104 +# ifndef CFG_ENV_SIZE
  105 +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
  106 +# endif
  107 + flash_protect(FLAG_PROTECT_SET,
  108 + CFG_ENV_ADDR,
  109 + CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
  110 + &flash_info[0]);
  111 +#endif
  112 +
  113 + return (CFG_FLASH0_SIZE * 1024 * 1024); /*size*/
  114 +}
  115 +
  116 +/*********************************************************************/
  117 +/* NAME: flash_print_info() - prints flash imformation */
  118 +/* */
  119 +/* DESCRIPTION: */
  120 +/* This function prints the flash information. */
  121 +/* */
  122 +/* INPUTS: */
  123 +/* flash_info_t *info - flash information structure */
  124 +/* */
  125 +/* OUTPUTS: */
  126 +/* Displays flash information to console */
  127 +/* */
  128 +/* RETURNS: */
  129 +/* None */
  130 +/* */
  131 +/* RESTRICTIONS/LIMITATIONS: */
  132 +/* */
  133 +/* */
  134 +/*********************************************************************/
  135 +void flash_print_info (flash_info_t *info)
  136 +{
  137 + int i;
  138 +
  139 + if (info->flash_id == FLASH_UNKNOWN) {
  140 + printf ("missing or unknown FLASH type\n");
  141 + return;
  142 + }
  143 +
  144 + switch ((info->flash_id >> 16) & 0xff) {
  145 + case 0x1:
  146 + printf ("AMD ");
  147 + break;
  148 + default:
  149 + printf ("Unknown Vendor ");
  150 + break;
  151 + }
  152 +
  153 + switch (info->flash_id & FLASH_TYPEMASK) {
  154 + case AMD_ID_F040B:
  155 + printf ("AM29F040B (4 Mbit)\n");
  156 + break;
  157 + case AMD_ID_F080B:
  158 + printf ("AM29F080B (8 Mbit)\n");
  159 + break;
  160 + case AMD_ID_F016D:
  161 + printf ("AM29F016D (16 Mbit)\n");
  162 + break;
  163 + default:
  164 + printf ("Unknown Chip Type\n");
  165 + break;
  166 + }
  167 +
  168 + printf (" Size: %ld MB in %d Sectors\n",
  169 + info->size >> 20, info->sector_count);
  170 +
  171 + printf (" Sector Start Addresses:");
  172 + for (i=0; i<info->sector_count; ++i) {
  173 + if ((i % 5) == 0)
  174 + printf ("\n ");
  175 + printf (" %08lX%s",
  176 + info->start[i],
  177 + info->protect[i] ? " (RO)" : " "
  178 + );
  179 + }
  180 + printf ("\n");
  181 + return;
  182 +}
  183 +
  184 +/*********************************************************************/
  185 +/* The following code cannot be run from FLASH! */
  186 +/*********************************************************************/
  187 +
  188 +/*********************************************************************/
  189 +/* NAME: flash_get_size() - detects the flash size */
  190 +/* */
  191 +/* DESCRIPTION: */
  192 +/* 1) Reads vendor ID and devices ID from the flash devices. */
  193 +/* 2) Initializes flash info struct. */
  194 +/* 3) Return the flash size */
  195 +/* */
  196 +/* INPUTS: */
  197 +/* vu_long *addr - pointer to start of flash */
  198 +/* flash_info_t *info - flash information structure */
  199 +/* */
  200 +/* OUTPUTS: */
  201 +/* None */
  202 +/* */
  203 +/* RETURNS: */
  204 +/* Size of the flash in bytes, or 0 if device id is unknown. */
  205 +/* */
  206 +/* RESTRICTIONS/LIMITATIONS: */
  207 +/* Only supports the following devices: */
  208 +/* AM29F080D */
  209 +/* AM29F016D */
  210 +/* */
  211 +/*********************************************************************/
  212 +static ulong flash_get_size (vu_long *addr, flash_info_t *info)
  213 +{
  214 + short i;
  215 + vu_long vendor, devid;
  216 + ulong base = (ulong)addr;
  217 +
  218 + /*printf("addr = %08lx\n", (unsigned long)addr); */
  219 +
  220 + /* Reset and Write auto select command: read Manufacturer ID */
  221 + addr[0x0000] = 0xf0f0f0f0;
  222 + addr[0x0555] = 0xAAAAAAAA;
  223 + addr[0x02AA] = 0x55555555;
  224 + addr[0x0555] = 0x90909090;
  225 + udelay (1000);
  226 +
  227 + vendor = addr[0];
  228 + /*printf("vendor = %08lx\n", vendor); */
  229 + if (vendor != 0x01010101) {
  230 + info->size = 0;
  231 + goto out;
  232 + }
  233 +
  234 + devid = addr[1];
  235 + /*printf("devid = %08lx\n", devid); */
  236 +
  237 + if ((devid & 0xff) == AMD_ID_F080B) {
  238 + info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F080B;
  239 + /* we have 16 sectors with 64KB each x 4 */
  240 + info->sector_count = 16;
  241 + info->size = 4 * info->sector_count * 64*1024;
  242 + } else if ((devid & 0xff) == AMD_ID_F016D){
  243 + info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F016D;
  244 + /* we have 32 sectors with 64KB each x 4 */
  245 + info->sector_count = 32;
  246 + info->size = 4 * info->sector_count * 64*1024;
  247 + } else {
  248 + info->size = 0;
  249 + goto out;
  250 + }
  251 + /*printf("sector count = %08x\n", info->sector_count); */
  252 + /* check for protected sectors */
  253 + for (i = 0; i < info->sector_count; i++) {
  254 + /* sector base address */
  255 + info->start[i] = base + i * (info->size / info->sector_count);
  256 + /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  257 + /* D0 = 1 if protected */
  258 + addr = (volatile unsigned long *)(info->start[i]);
  259 + info->protect[i] = addr[2] & 1;
  260 + }
  261 +
  262 + /* reset command */
  263 + addr = (vu_long *)info->start[0];
  264 +
  265 + out:
  266 + addr[0] = 0xf0f0f0f0;
  267 +
  268 + /*printf("size = %08x\n", info->size); */
  269 + return info->size;
  270 +}
  271 +
  272 +/*********************************************************************/
  273 +/* NAME: flash_erase() - erases flash by sector */
  274 +/* */
  275 +/* DESCRIPTION: */
  276 +/* This function erases flash sectors starting for s_first to */
  277 +/* s_last. */
  278 +/* */
  279 +/* INPUTS: */
  280 +/* flash_info_t *info - flash information structure */
  281 +/* int s_first - first sector to erase */
  282 +/* int s_last - last sector to erase */
  283 +/* */
  284 +/* OUTPUTS: */
  285 +/* None */
  286 +/* */
  287 +/* RETURNS: */
  288 +/* Returns 0 for success, 1 for failure. */
  289 +/* */
  290 +/* RESTRICTIONS/LIMITATIONS: */
  291 +/* */
  292 +/*********************************************************************/
  293 +int flash_erase (flash_info_t *info, int s_first, int s_last)
  294 +{
  295 + vu_long *addr = (vu_long*)(info->start[0]);
  296 + int flag, prot, sect, l_sect;
  297 + ulong start, now, last;
  298 +
  299 + if ((s_first < 0) || (s_first > s_last)) {
  300 + if (info->flash_id == FLASH_UNKNOWN) {
  301 + printf ("- missing\n");
  302 + } else {
  303 + printf ("- no sectors to erase\n");
  304 + }
  305 + return 1;
  306 + }
  307 +
  308 + prot = 0;
  309 + for (sect = s_first; sect <= s_last; sect++) {
  310 + if (info->protect[sect]) {
  311 + prot++;
  312 + }
  313 + }
  314 +
  315 + if (prot) {
  316 + printf ("- Warning: %d protected sectors will not be erased!\n",
  317 + prot);
  318 + } else {
  319 + printf ("\n");
  320 + }
  321 +
  322 + l_sect = -1;
  323 +
  324 + /* Disable interrupts which might cause a timeout here */
  325 + flag = disable_interrupts();
  326 +
  327 + addr[0x0555] = 0xAAAAAAAA;
  328 + addr[0x02AA] = 0x55555555;
  329 + addr[0x0555] = 0x80808080;
  330 + addr[0x0555] = 0xAAAAAAAA;
  331 + addr[0x02AA] = 0x55555555;
  332 + udelay (100);
  333 +
  334 + /* Start erase on unprotected sectors */
  335 + for (sect = s_first; sect <= s_last; sect++) {
  336 + if (info->protect[sect] == 0) { /* not protected */
  337 + addr = (vu_long*)(info->start[sect]);
  338 + addr[0] = 0x30303030;
  339 + l_sect = sect;
  340 + }
  341 + }
  342 +
  343 + /* re-enable interrupts if necessary */
  344 + if (flag)
  345 + enable_interrupts();
  346 +
  347 + /* wait at least 80us - let's wait 1 ms */
  348 + udelay (1000);
  349 +
  350 + /*
  351 + * We wait for the last triggered sector
  352 + */
  353 + if (l_sect < 0)
  354 + goto DONE;
  355 +
  356 + start = get_timer (0);
  357 + last = start;
  358 + addr = (vu_long*)(info->start[l_sect]);
  359 + while ((addr[0] & 0x80808080) != 0x80808080) {
  360 + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  361 + printf ("Timeout\n");
  362 + return 1;
  363 + }
  364 + /* show that we're waiting */
  365 + if ((now - last) > 1000) { /* every second */
  366 + serial_putc ('.');
  367 + last = now;
  368 + }
  369 + }
  370 +
  371 + DONE:
  372 + /* reset to read mode */
  373 + addr = (volatile unsigned long *)info->start[0];
  374 + addr[0] = 0xF0F0F0F0; /* reset bank */
  375 +
  376 + printf (" done\n");
  377 + return 0;
  378 +}
  379 +
  380 +/*********************************************************************/
  381 +/* NAME: write_buff() - writes a buffer to flash */
  382 +/* */
  383 +/* DESCRIPTION: */
  384 +/* This function copies a buffer, *src, to flash. */
  385 +/* */
  386 +/* INPUTS: */
  387 +/* flash_info_t *info - flash information structure */
  388 +/* uchar *src - pointer to buffer to write to flash */
  389 +/* ulong addr - address to start write at */
  390 +/* ulong cnt - number of bytes to write to flash */
  391 +/* */
  392 +/* OUTPUTS: */
  393 +/* None */
  394 +/* */
  395 +/* RETURNS: */
  396 +/* 0 - OK */
  397 +/* 1 - write timeout */
  398 +/* 2 - Flash not erased */
  399 +/* */
  400 +/* RESTRICTIONS/LIMITATIONS: */
  401 +/* */
  402 +/*********************************************************************/
  403 +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  404 +{
  405 + ulong cp, wp, data;
  406 + int i, l, rc;
  407 +
  408 + wp = (addr & ~3); /* get lower word aligned address */
  409 +
  410 + /*
  411 + * handle unaligned start bytes
  412 + */
  413 + if ((l = addr - wp) != 0) {
  414 + data = 0;
  415 + for (i = 0, cp = wp; i < l; ++i, ++cp) {
  416 + data = (data << 8) | (*(uchar *)cp);
  417 + }
  418 + for (; (i < 4) && (cnt > 0); ++i) {
  419 + data = (data << 8) | *src++;
  420 + --cnt;
  421 + ++cp;
  422 + }
  423 + for (; (cnt == 0) && (i < 4); ++i, ++cp) {
  424 + data = (data << 8) | (*(uchar *)cp);
  425 + }
  426 +
  427 + if ((rc = write_word(info, wp, data)) != 0) {
  428 + return (rc);
  429 + }
  430 + wp += 4;
  431 + }
  432 +
  433 + /*
  434 + * handle word aligned part
  435 + */
  436 + while (cnt >= 4) {
  437 + data = 0;
  438 + for (i = 0; i < 4; ++i) {
  439 + data = (data << 8) | *src++;
  440 + }
  441 + if ((rc = write_word(info, wp, data)) != 0) {
  442 + return (rc);
  443 + }
  444 + wp += 4;
  445 + cnt -= 4;
  446 + }
  447 +
  448 + if (cnt == 0) {
  449 + return (0);
  450 + }
  451 +
  452 + /*
  453 + * handle unaligned tail bytes
  454 + */
  455 + data = 0;
  456 + for (i = 0, cp = wp; (i < 4) && (cnt > 0); ++i, ++cp) {
  457 + data = (data << 8) | *src++;
  458 + --cnt;
  459 + }
  460 + for (; (i < 4); ++i, ++cp) {
  461 + data = (data << 8) | (*(uchar *)cp);
  462 + }
  463 +
  464 + return (write_word(info, wp, data));
  465 +}
  466 +
  467 +/*********************************************************************/
  468 +/* NAME: write_word() - writes a word to flash */
  469 +/* */
  470 +/* DESCRIPTION: */
  471 +/* This writes a single word to flash. */
  472 +/* */
  473 +/* INPUTS: */
  474 +/* flash_info_t *info - flash information structure */
  475 +/* ulong dest - address to write */
  476 +/* ulong data - data to write */
  477 +/* */
  478 +/* OUTPUTS: */
  479 +/* None */
  480 +/* */
  481 +/* RETURNS: */
  482 +/* 0 - OK */
  483 +/* 1 - write timeout */
  484 +/* 2 - Flash not erased */
  485 +/* */
  486 +/* RESTRICTIONS/LIMITATIONS: */
  487 +/* */
  488 +/*********************************************************************/
  489 +static int write_word (flash_info_t *info, ulong dest, ulong data)
  490 +{
  491 + vu_long *addr = (vu_long*)(info->start[0]);
  492 + ulong start;
  493 + int flag;
  494 +
  495 + /* Check if Flash is (sufficiently) erased */
  496 + if ((*((vu_long *)dest) & data) != data) {
  497 + return (2);
  498 + }
  499 + /* Disable interrupts which might cause a timeout here */
  500 + flag = disable_interrupts();
  501 +
  502 + addr[0x0555] = 0xAAAAAAAA;
  503 + addr[0x02AA] = 0x55555555;
  504 + addr[0x0555] = 0xA0A0A0A0;
  505 +
  506 + *((vu_long *)dest) = data;
  507 +
  508 + /* re-enable interrupts if necessary */
  509 + if (flag)
  510 + enable_interrupts();
  511 +
  512 + /* data polling for D7 */
  513 + start = get_timer (0);
  514 + while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
  515 + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  516 + return (1);
  517 + }
  518 + }
  519 + return (0);
  520 +}
  521 +/*********************************************************************/
  522 +/* End of flash.c */
  523 +/*********************************************************************/
board/gw8260/gw8260.c
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4 + * Marius Groeger <mgroeger@sysgo.de>
  5 + *
  6 + * (C) Copyright 2001
  7 + * Advent Networks, Inc. <http://www.adventnetworks.com>
  8 + * Jay Monkman <jtm@smoothsmoothie.com>
  9 + *
  10 + * (C) Copyright 2001
  11 + * Advent Networks, Inc. <http://www.adventnetworks.com>
  12 + * Oliver Brown <oliverb@alumni.utexas.net>
  13 + *
  14 + * See file CREDITS for list of people who contributed to this
  15 + * project.
  16 + *
  17 + * This program is free software; you can redistribute it and/or
  18 + * modify it under the terms of the GNU General Public License as
  19 + * published by the Free Software Foundation; either version 2 of
  20 + * the License, or (at your option) any later version.
  21 + *
  22 + * This program is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with this program; if not, write to the Free Software
  29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30 + * MA 02111-1307 USA
  31 + */
  32 +
  33 +/*********************************************************************/
  34 +/* DESCRIPTION:
  35 + * This file contains the board routines for the GW8260 board.
  36 + *
  37 + * MODULE DEPENDENCY:
  38 + * None
  39 + *
  40 + * RESTRICTIONS/LIMITATIONS:
  41 + * None
  42 + *
  43 + * Copyright (c) 2001, Advent Networks, Inc.
  44 + */
  45 +/*********************************************************************/
  46 +
  47 +#include <common.h>
  48 +#include <ioports.h>
  49 +#include <mpc8260.h>
  50 +
  51 +/*
  52 + * I/O Port configuration table
  53 + *
  54 + */
  55 +const iop_conf_t iop_conf_tab[4][32] = {
  56 +
  57 + /* Port A configuration */
  58 + { /* conf ppar psor pdir podr pdat */
  59 + /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* TP14 */
  60 + /* PA30 */ { 1, 1, 1, 1, 0, 0 }, /* US_RTS */
  61 + /* PA29 */ { 1, 0, 0, 1, 0, 1 }, /* LSSI_DATA */
  62 + /* PA28 */ { 1, 0, 0, 1, 0, 1 }, /* LSSI_CLK */
  63 + /* PA27 */ { 1, 0, 0, 1, 0, 0 }, /* TP12 */
  64 + /* PA26 */ { 1, 0, 0, 0, 0, 0 }, /* IO_STATUS */
  65 + /* PA25 */ { 1, 0, 0, 0, 0, 0 }, /* IO_CLOCK */
  66 + /* PA24 */ { 1, 0, 0, 0, 0, 0 }, /* IO_CONFIG */
  67 + /* PA23 */ { 1, 0, 0, 0, 0, 0 }, /* IO_DONE */
  68 + /* PA22 */ { 1, 0, 0, 0, 0, 0 }, /* IO_DATA */
  69 + /* PA21 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD3 */
  70 + /* PA20 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD2 */
  71 + /* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD1 */
  72 + /* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD0 */
  73 + /* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD0 */
  74 + /* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD1 */
  75 + /* PA15 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD2 */
  76 + /* PA14 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD3 */
  77 + /* PA13 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE7 */
  78 + /* PA12 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE6 */
  79 + /* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE5 */
  80 + /* PA10 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE4 */
  81 + /* PA9 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE3 */
  82 + /* PA8 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE2 */
  83 + /* PA7 */ { 1, 0, 0, 0, 0, 0 }, /* LSSI_IN */
  84 + /* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE0 */
  85 + /* PA5 */ { 1, 0, 0, 1, 0, 0 }, /* DEMOD_RESET_ */
  86 + /* PA4 */ { 1, 0, 0, 1, 0, 0 }, /* MOD_RESET_ */
  87 + /* PA3 */ { 1, 0, 0, 1, 0, 0 }, /* IO_RESET */
  88 + /* PA2 */ { 1, 0, 0, 1, 0, 0 }, /* TX_ENABLE */
  89 + /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* RX_LOCK */
  90 + /* PA0 */ { 1, 0, 0, 1, 0, 1 } /* MPC_RESET_ */
  91 + },
  92 +
  93 + /* Port B configuration */
  94 + { /* conf ppar psor pdir podr pdat */
  95 + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TX_ER */
  96 + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_DV */
  97 + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FETH0_TX_EN */
  98 + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_ER */
  99 + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_COL */
  100 + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_CRS */
  101 + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD3 */
  102 + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD2 */
  103 + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD1 */
  104 + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD0 */
  105 + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD0 */
  106 + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD1 */
  107 + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD2 */
  108 + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD3 */
  109 + /* PB17 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_DV */
  110 + /* PB16 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_ER */
  111 + /* PB15 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TX_ER */
  112 + /* PB14 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TX_EN */
  113 + /* PB13 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_COL */
  114 + /* PB12 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_CRS */
  115 + /* PB11 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD3 */
  116 + /* PB10 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD2 */
  117 + /* PB9 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD1 */
  118 + /* PB8 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD0 */
  119 + /* PB7 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD0 */
  120 + /* PB6 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD1 */
  121 + /* PB5 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD2 */
  122 + /* PB4 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD3 */
  123 + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  124 + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  125 + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  126 + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
  127 + },
  128 +
  129 + /* Port C */
  130 + { /* conf ppar psor pdir podr pdat */
  131 + /* PC31 */ { 1, 0, 0, 1, 0, 1 }, /* FAST_RESET_ */
  132 + /* PC30 */ { 1, 0, 0, 1, 0, 1 }, /* FAST_PAUSE_ */
  133 + /* PC29 */ { 1, 0, 0, 1, 0, 0 }, /* FAST_SLEW1 */
  134 + /* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* FAST_SLEW0 */
  135 + /* PC27 */ { 1, 0, 0, 1, 0, 0 }, /* TP13 */
  136 + /* PC26 */ { 1, 0, 0, 0, 0, 0 }, /* RXDECDFLG */
  137 + /* PC25 */ { 1, 0, 0, 0, 0, 0 }, /* RXACQFAIL */
  138 + /* PC24 */ { 1, 0, 0, 0, 0, 0 }, /* RXACQFLG */
  139 + /* PC23 */ { 1, 0, 0, 1, 0, 0 }, /* WD_TCL */
  140 + /* PC22 */ { 1, 0, 0, 1, 0, 0 }, /* WD_EN */
  141 + /* PC21 */ { 1, 0, 0, 1, 0, 0 }, /* US_TXCLK */
  142 + /* PC20 */ { 1, 0, 0, 0, 0, 0 }, /* DS_RXCLK */
  143 + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_CLK */
  144 + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_TX_CLK */
  145 + /* PC17 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_CLK */
  146 + /* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_TX_CLK */
  147 + /* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* TX_SHUTDOWN_ */
  148 + /* PC14 */ { 1, 0, 0, 0, 0, 0 }, /* RS_232_DTR_ */
  149 + /* PC13 */ { 1, 0, 0, 0, 0, 0 }, /* TXERR */
  150 + /* PC12 */ { 1, 0, 0, 1, 0, 1 }, /* FETH1_MDDIS */
  151 + /* PC11 */ { 1, 0, 0, 1, 0, 1 }, /* FETH0_MDDIS */
  152 + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* MDC */
  153 + /* PC9 */ { 1, 0, 0, 1, 1, 1 }, /* MDIO */
  154 + /* PC8 */ { 1, 0, 0, 1, 1, 1 }, /* SER_NUM */
  155 + /* PC7 */ { 1, 1, 0, 0, 0, 0 }, /* US_CTS */
  156 + /* PC6 */ { 1, 1, 0, 0, 0, 0 }, /* DS_CD_ */
  157 + /* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* FETH1_PWRDWN */
  158 + /* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* FETH0_PWRDWN */
  159 + /* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED3 */
  160 + /* PC2 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED2 */
  161 + /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED1 */
  162 + /* PC0 */ { 1, 0, 0, 1, 0, 1 }, /* MPULED0 */
  163 + },
  164 +
  165 + /* Port D */
  166 + { /* conf ppar psor pdir podr pdat */
  167 + /* PD31 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  168 + /* PD30 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  169 + /* PD29 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  170 + /* PD28 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  171 + /* PD27 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  172 + /* PD26 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  173 + /* PD25 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  174 + /* PD24 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  175 + /* PD23 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  176 + /* PD22 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  177 + /* PD21 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  178 + /* PD20 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  179 + /* PD19 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
  180 + /* PD18 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
  181 + /* PD17 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
  182 + /* PD16 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
  183 + /* PD15 */ { 1, 1, 1, 0, 1, 1 }, /* SDRAM_SDA */
  184 + /* PD14 */ { 1, 1, 1, 0, 1, 1 }, /* SDRAM_SCL */
  185 + /* PD13 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED7 */
  186 + /* PD12 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED6 */
  187 + /* PD11 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED5 */
  188 + /* PD10 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED4 */
  189 + /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* RS232_TXD */
  190 + /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* RD232_RXD */
  191 + /* PD7 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  192 + /* PD6 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  193 + /* PD5 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  194 + /* PD4 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
  195 + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  196 + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  197 + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
  198 + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
  199 + }
  200 +};
  201 +
  202 +/*********************************************************************/
  203 +/* NAME: checkboard() - Displays the board type and serial number */
  204 +/* */
  205 +/* OUTPUTS: */
  206 +/* Displays the board type and serial number */
  207 +/* */
  208 +/* RETURNS: */
  209 +/* Always returns 1 */
  210 +/* */
  211 +/* RESTRICTIONS/LIMITATIONS: */
  212 +/* */
  213 +/* */
  214 +/*********************************************************************/
  215 +int checkboard(void)
  216 +{
  217 + char *str;
  218 + puts ("Board: Advent Networks gw8260\n");
  219 +
  220 + str = getenv("serial#");
  221 + if (str != NULL) {
  222 + printf("SN: %s\n", str);
  223 + }
  224 + return 0;
  225 +}
  226 +
  227 +
  228 +#if defined (CFG_DRAM_TEST)
  229 +/*********************************************************************/
  230 +/* NAME: move64() - moves a double word (64-bit) */
  231 +/* */
  232 +/* DESCRIPTION: */
  233 +/* this function performs a double word move from the data at */
  234 +/* the source pointer to the location at the destination pointer. */
  235 +/* */
  236 +/* INPUTS: */
  237 +/* unsigned long long *src - pointer to data to move */
  238 +/* */
  239 +/* OUTPUTS: */
  240 +/* unsigned long long *dest - pointer to locate to move data */
  241 +/* */
  242 +/* RETURNS: */
  243 +/* None */
  244 +/* */
  245 +/* RESTRICTIONS/LIMITATIONS: */
  246 +/* May cloober fr0. */
  247 +/* */
  248 +/*********************************************************************/
  249 +static void move64(unsigned long long *src, unsigned long long *dest)
  250 +{
  251 + asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
  252 + "stfd 0, 0(4)" /* *dest = fpr0 */
  253 + : : : "fr0" ); /* Clobbers fr0 */
  254 + return;
  255 +}
  256 +
  257 +
  258 +#if defined (CFG_DRAM_TEST_DATA)
  259 +
  260 +unsigned long long pattern[]= {
  261 + 0xaaaaaaaaaaaaaaaa,
  262 + 0xcccccccccccccccc,
  263 + 0xf0f0f0f0f0f0f0f0,
  264 + 0xff00ff00ff00ff00,
  265 + 0xffff0000ffff0000,
  266 + 0xffffffff00000000,
  267 + 0x00000000ffffffff,
  268 + 0x0000ffff0000ffff,
  269 + 0x00ff00ff00ff00ff,
  270 + 0x0f0f0f0f0f0f0f0f,
  271 + 0x3333333333333333,
  272 + 0x5555555555555555};
  273 +
  274 +/*********************************************************************/
  275 +/* NAME: mem_test_data() - test data lines for shorts and opens */
  276 +/* */
  277 +/* DESCRIPTION: */
  278 +/* Tests data lines for shorts and opens by forcing adjacent data */
  279 +/* to opposite states. Because the data lines could be routed in */
  280 +/* an arbitrary manner the must ensure test patterns ensure that */
  281 +/* every case is tested. By using the following series of binary */
  282 +/* patterns every combination of adjacent bits is test regardless */
  283 +/* of routing. */
  284 +/* */
  285 +/* ...101010101010101010101010 */
  286 +/* ...110011001100110011001100 */
  287 +/* ...111100001111000011110000 */
  288 +/* ...111111110000000011111111 */
  289 +/* */
  290 +/* Carrying this out, gives us six hex patterns as follows: */
  291 +/* */
  292 +/* 0xaaaaaaaaaaaaaaaa */
  293 +/* 0xcccccccccccccccc */
  294 +/* 0xf0f0f0f0f0f0f0f0 */
  295 +/* 0xff00ff00ff00ff00 */
  296 +/* 0xffff0000ffff0000 */
  297 +/* 0xffffffff00000000 */
  298 +/* */
  299 +/* The number test patterns will always be given by: */
  300 +/* */
  301 +/* log(base 2)(number data bits) = log2 (64) = 6 */
  302 +/* */
  303 +/* To test for short and opens to other signals on our boards. we */
  304 +/* simply */
  305 +/* test with the 1's complemnt of the paterns as well. */
  306 +/* */
  307 +/* OUTPUTS: */
  308 +/* Displays failing test pattern */
  309 +/* */
  310 +/* RETURNS: */
  311 +/* 0 - Passed test */
  312 +/* 1 - Failed test */
  313 +/* */
  314 +/* RESTRICTIONS/LIMITATIONS: */
  315 +/* Assumes only one one SDRAM bank */
  316 +/* */
  317 +/*********************************************************************/
  318 +int mem_test_data(void)
  319 +{
  320 + unsigned long long * pmem =
  321 + (unsigned long long *)CFG_SDRAM_BASE ;
  322 + unsigned long long temp64;
  323 + int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);
  324 + int i;
  325 + unsigned int hi, lo;
  326 +
  327 + for ( i = 0; i < num_patterns; i++) {
  328 + move64(&(pattern[i]), pmem);
  329 + move64(pmem, &temp64);
  330 +
  331 + /* hi = (temp64>>32) & 0xffffffff; */
  332 + /* lo = temp64 & 0xffffffff; */
  333 + /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
  334 +
  335 + hi = (pattern[i]>>32) & 0xffffffff;
  336 + lo = pattern[i] & 0xffffffff;
  337 + /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
  338 +
  339 + if (temp64 != pattern[i]){
  340 + printf ("\n Data Test Failed, pattern 0x%08x%08x", hi, lo);
  341 + return 1;
  342 + }
  343 + }
  344 +
  345 + return 0;
  346 +}
  347 +#endif /* CFG_DRAM_TEST_DATA */
  348 +
  349 +#if defined (CFG_DRAM_TEST_ADDRESS)
  350 +/*********************************************************************/
  351 +/* NAME: mem_test_address() - test address lines */
  352 +/* */
  353 +/* DESCRIPTION: */
  354 +/* This function performs a test to verify that each word im */
  355 +/* memory is uniquly addressable. The test sequence is as follows: */
  356 +/* */
  357 +/* 1) write the address of each word to each word. */
  358 +/* 2) verify that each location equals its address */
  359 +/* */
  360 +/* OUTPUTS: */
  361 +/* Displays failing test pattern and address */
  362 +/* */
  363 +/* RETURNS: */
  364 +/* 0 - Passed test */
  365 +/* 1 - Failed test */
  366 +/* */
  367 +/* RESTRICTIONS/LIMITATIONS: */
  368 +/* */
  369 +/* */
  370 +/*********************************************************************/
  371 +int mem_test_address(void)
  372 +{
  373 + volatile unsigned int * pmem = (volatile unsigned int *)CFG_SDRAM_BASE ;
  374 + const unsigned int size = (CFG_SDRAM_SIZE * 1024 * 1024)/4;
  375 + unsigned int i;
  376 +
  377 + /* write address to each location */
  378 + for ( i = 0; i < size; i++) {
  379 + pmem[i] = i;
  380 + }
  381 +
  382 + /* verify each loaction */
  383 + for ( i = 0; i < size; i++) {
  384 + if (pmem[i] != i) {
  385 + printf("\n Address Test Failed at 0x%x", i);
  386 + return 1;
  387 + }
  388 + }
  389 + return 0;
  390 +}
  391 +#endif /* CFG_DRAM_TEST_ADDRESS */
  392 +
  393 +#if defined (CFG_DRAM_TEST_WALK)
  394 +/*********************************************************************/
  395 +/* NAME: mem_march() - memory march */
  396 +/* */
  397 +/* DESCRIPTION: */
  398 +/* Marches up through memory. At each location verifies rmask if */
  399 +/* read = 1. At each location write wmask if write = 1. Displays */
  400 +/* failing address and pattern. */
  401 +/* */
  402 +/* INPUTS: */
  403 +/* volatile unsigned long long * base - start address of test */
  404 +/* unsigned int size - number of dwords(64-bit) to test */
  405 +/* unsigned long long rmask - read verify mask */
  406 +/* unsigned long long wmask - wrtie verify mask */
  407 +/* short read - verifies rmask if read = 1 */
  408 +/* short write - writes wmask if write = 1 */
  409 +/* */
  410 +/* OUTPUTS: */
  411 +/* Displays failing test pattern and address */
  412 +/* */
  413 +/* RETURNS: */
  414 +/* 0 - Passed test */
  415 +/* 1 - Failed test */
  416 +/* */
  417 +/* RESTRICTIONS/LIMITATIONS: */
  418 +/* */
  419 +/* */
  420 +/*********************************************************************/
  421 +int mem_march(volatile unsigned long long * base,
  422 + unsigned int size,
  423 + unsigned long long rmask,
  424 + unsigned long long wmask,
  425 + short read,
  426 + short write)
  427 +{
  428 + unsigned int i;
  429 + unsigned long long temp;
  430 + unsigned int hitemp, lotemp, himask, lomask;
  431 +
  432 + for (i = 0 ; i < size ; i++) {
  433 + if (read != 0) {
  434 + /* temp = base[i]; */
  435 + move64 ((unsigned long long *)&(base[i]), &temp);
  436 + if (rmask != temp) {
  437 + hitemp = (temp>>32) & 0xffffffff;
  438 + lotemp = temp & 0xffffffff;
  439 + himask = (rmask>>32) & 0xffffffff;
  440 + lomask = rmask & 0xffffffff;
  441 +
  442 + printf("\n Walking one's test failed: address = 0x%08x,"
  443 + "\n\texpected 0x%08x%08x, found 0x%08x%08x",
  444 + i<<3, himask, lomask, hitemp, lotemp);
  445 + return 1;
  446 + }
  447 + }
  448 + if ( write != 0 ) {
  449 + /* base[i] = wmask; */
  450 + move64 (&wmask, (unsigned long long *)&(base[i]));
  451 + }
  452 + }
  453 + return 0;
  454 +}
  455 +#endif /* CFG_DRAM_TEST_WALK */
  456 +
  457 +/*********************************************************************/
  458 +/* NAME: mem_test_walk() - a simple walking ones test */
  459 +/* */
  460 +/* DESCRIPTION: */
  461 +/* Performs a walking ones through entire physical memory. The */
  462 +/* test uses as series of memory marches, mem_march(), to verify */
  463 +/* and write the test patterns to memory. The test sequence is as */
  464 +/* follows: */
  465 +/* 1) march writing 0000...0001 */
  466 +/* 2) march verifying 0000...0001 , writing 0000...0010 */
  467 +/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
  468 +/* the write mask equals 1000...0000 */
  469 +/* 4) march verifying 1000...0000 */
  470 +/* The test fails if any of the memory marches return a failure. */
  471 +/* */
  472 +/* OUTPUTS: */
  473 +/* Displays which pass on the memory test is executing */
  474 +/* */
  475 +/* RETURNS: */
  476 +/* 0 - Passed test */
  477 +/* 1 - Failed test */
  478 +/* */
  479 +/* RESTRICTIONS/LIMITATIONS: */
  480 +/* */
  481 +/* */
  482 +/*********************************************************************/
  483 +int mem_test_walk(void)
  484 +{
  485 + unsigned long long mask;
  486 + volatile unsigned long long * pmem =
  487 + (volatile unsigned long long *)CFG_SDRAM_BASE ;
  488 + const unsigned long size = (CFG_SDRAM_SIZE * 1024 * 1024)/8;
  489 +
  490 + unsigned int i;
  491 + mask = 0x01;
  492 +
  493 + printf("Initial Pass");
  494 + mem_march(pmem,size,0x0,0x1,0,1);
  495 +
  496 + printf("\b\b\b\b\b\b\b\b\b\b\b\b");
  497 + printf(" ");
  498 + printf("\b\b\b\b\b\b\b\b\b\b\b\b");
  499 +
  500 + for (i = 0 ; i < 63 ; i++) {
  501 + printf("Pass %2d", i+2);
  502 + if ( mem_march(pmem,size, mask,mask << 1, 1, 1) != 0 ){
  503 + /*printf("mask: 0x%x, pass: %d, ", mask, i);*/
  504 + return 1;
  505 + }
  506 + mask = mask<<1;
  507 + printf("\b\b\b\b\b\b\b");
  508 + }
  509 +
  510 + printf("Last Pass");
  511 + if (mem_march(pmem, size, 0, mask, 0, 1) != 0) {
  512 + /* printf("mask: 0x%x", mask); */
  513 + return 1;
  514 + }
  515 + printf("\b\b\b\b\b\b\b\b\b");
  516 + printf(" ");
  517 + printf("\b\b\b\b\b\b\b\b\b");
  518 +
  519 + return 0;
  520 +}
  521 +
  522 +/*********************************************************************/
  523 +/* NAME: testdram() - calls any enabled memory tests */
  524 +/* */
  525 +/* DESCRIPTION: */
  526 +/* Runs memory tests if the environment test variables are set to */
  527 +/* 'y'. */
  528 +/* */
  529 +/* INPUTS: */
  530 +/* testdramdata - If set to 'y', data test is run. */
  531 +/* testdramaddress - If set to 'y', address test is run. */
  532 +/* testdramwalk - If set to 'y', walking ones test is run */
  533 +/* */
  534 +/* OUTPUTS: */
  535 +/* None */
  536 +/* */
  537 +/* RETURNS: */
  538 +/* 0 - Passed test */
  539 +/* 1 - Failed test */
  540 +/* */
  541 +/* RESTRICTIONS/LIMITATIONS: */
  542 +/* */
  543 +/* */
  544 +/*********************************************************************/
  545 +int testdram(void)
  546 +{
  547 + char *s;
  548 + int rundata, runaddress, runwalk;
  549 +
  550 + s = getenv ("testdramdata");
  551 + rundata = (s && (*s == 'y')) ? 1 : 0;
  552 + s = getenv ("testdramaddress");
  553 + runaddress = (s && (*s == 'y')) ? 1 : 0;
  554 + s = getenv ("testdramwalk");
  555 + runwalk = (s && (*s == 'y')) ? 1 : 0;
  556 +
  557 + if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
  558 + printf("Testing RAM ... ");
  559 + }
  560 +#ifdef CFG_DRAM_TEST_DATA
  561 + if (rundata == 1) {
  562 + if (mem_test_data() == 1){
  563 + return 1;
  564 + }
  565 + }
  566 +#endif
  567 +#ifdef CFG_DRAM_TEST_ADDRESS
  568 + if (runaddress == 1) {
  569 + if (mem_test_address() == 1){
  570 + return 1;
  571 + }
  572 + }
  573 +#endif
  574 +#ifdef CFG_DRAM_TEST_WALK
  575 + if (runwalk == 1) {
  576 + if (mem_test_walk() == 1){
  577 + return 1;
  578 + }
  579 + }
  580 +#endif
  581 + if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
  582 + printf("passed");
  583 + }
  584 + return 0;
  585 +
  586 +}
  587 +#endif /* CFG_DRAM_TEST */
  588 +
  589 +/*********************************************************************/
  590 +/* NAME: initdram() - initializes SDRAM controller */
  591 +/* */
  592 +/* DESCRIPTION: */
  593 +/* Initializes the MPC8260's SDRAM controller. */
  594 +/* */
  595 +/* INPUTS: */
  596 +/* CFG_IMMR - MPC8260 Internal memory map */
  597 +/* CFG_SDRAM_BASE - Physical start address of SDRAM */
  598 +/* CFG_PSDMR - SDRAM mode register */
  599 +/* CFG_MPTPR - Memory refresh timer prescaler register */
  600 +/* CFG_SDRAM0_SIZE - SDRAM size */
  601 +/* */
  602 +/* RETURNS: */
  603 +/* SDRAM size in bytes */
  604 +/* */
  605 +/* RESTRICTIONS/LIMITATIONS: */
  606 +/* */
  607 +/* */
  608 +/*********************************************************************/
  609 +long int initdram(int board_type)
  610 +{
  611 + volatile immap_t *immap = (immap_t *)CFG_IMMR;
  612 + volatile memctl8260_t *memctl = &immap->im_memctl;
  613 + volatile uchar c = 0, *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8);
  614 + ulong psdmr = CFG_PSDMR;
  615 + int i;
  616 +
  617 + /*
  618 + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
  619 + *
  620 + * "At system reset, initialization software must set up the
  621 + * programmable parameters in the memory controller banks registers
  622 + * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
  623 + * system software should execute the following initialization sequence
  624 + * for each SDRAM device.
  625 + *
  626 + * 1. Issue a PRECHARGE-ALL-BANKS command
  627 + * 2. Issue eight CBR REFRESH commands
  628 + * 3. Issue a MODE-SET command to initialize the mode register
  629 + *
  630 + * The initial commands are executed by setting P/LSDMR[OP] and
  631 + * accessing the SDRAM with a single-byte transaction."
  632 + *
  633 + * The appropriate BRx/ORx registers have already been set when we
  634 + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
  635 + */
  636 +
  637 + memctl->memc_psrt = CFG_PSRT;
  638 + memctl->memc_mptpr = CFG_MPTPR;
  639 +
  640 + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
  641 + *ramaddr = c;
  642 +
  643 + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
  644 + for (i = 0; i < 8; i++){
  645 + *ramaddr = c;
  646 + }
  647 + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
  648 + *ramaddr = c;
  649 +
  650 + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
  651 + *ramaddr = c;
  652 +
  653 + /* return total ram size */
  654 + return (CFG_SDRAM0_SIZE * 1024 * 1024);
  655 +}
  656 +
  657 +/*********************************************************************/
  658 +/* End of gw8260.c */
  659 +/*********************************************************************/
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * Changes for MATRIX Vision MVsensor (C) Copyright 2001
  6 + * MATRIX Vision GmbH / hg, info@matrix-vision.de
  7 + *
  8 + * See file CREDITS for list of people who contributed to this
  9 + * project.
  10 + *
  11 + * This program is free software; you can redistribute it and/or
  12 + * modify it under the terms of the GNU General Public License as
  13 + * published by the Free Software Foundation; either version 2 of
  14 + * the License, or (at your option) any later version.
  15 + *
  16 + * This program is distributed in the hope that it will be useful,
  17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 + * GNU General Public License for more details.
  20 + *
  21 + * You should have received a copy of the GNU General Public License
  22 + * along with this program; if not, write to the Free Software
  23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 + * MA 02111-1307 USA
  25 + */
  26 +
  27 +#include <common.h>
  28 +#include <mpc8xx.h>
  29 +
  30 +#undef MVDEBUG
  31 +#ifdef MVDEBUG
  32 +#define mvdebug debug
  33 +#else
  34 +#define mvdebug(p) do {} while (0)
  35 +#endif
  36 +
  37 +
  38 +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  39 +
  40 +
  41 +#ifdef CONFIG_MVS_16BIT_FLASH
  42 + #define FLASH_DATA_MASK 0xffff
  43 + #define FLASH_SHIFT 0
  44 +#else
  45 + #define FLASH_DATA_MASK 0xffffffff
  46 + #define FLASH_SHIFT 1
  47 +#endif
  48 +
  49 +
  50 +/*-----------------------------------------------------------------------
  51 + * Functions
  52 + */
  53 +static ulong flash_get_size (vu_long *address, flash_info_t *info);
  54 +static int write_word (flash_info_t *info, ulong dest, ulong data);
  55 +static void flash_get_offsets (ulong base, flash_info_t *info);
  56 +
  57 +/*-----------------------------------------------------------------------
  58 + */
  59 +
  60 +unsigned long flash_init (void)
  61 +{
  62 + volatile immap_t *immap = (immap_t *)CFG_IMMR;
  63 + volatile memctl8xx_t *memctl = &immap->im_memctl;
  64 + unsigned long size_b0, size_b1;
  65 + int i;
  66 +
  67 + /* Init: no FLASHes known */
  68 + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  69 + flash_info[i].flash_id = FLASH_UNKNOWN;
  70 + }
  71 +
  72 + /* Static FLASH Bank configuration here - FIXME XXX */
  73 +
  74 + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
  75 +
  76 + if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  77 + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  78 + size_b0, size_b0<<20);
  79 + }
  80 +
  81 +#if defined (FLASH_BASE1_PRELIM)
  82 + size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
  83 +
  84 + if (size_b1 > size_b0) {
  85 + printf ("## ERROR: "
  86 + "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  87 + size_b1, size_b1<<20,
  88 + size_b0, size_b0<<20
  89 + );
  90 + flash_info[0].flash_id = FLASH_UNKNOWN;
  91 + flash_info[1].flash_id = FLASH_UNKNOWN;
  92 + flash_info[0].sector_count = -1;
  93 + flash_info[1].sector_count = -1;
  94 + flash_info[0].size = 0;
  95 + flash_info[1].size = 0;
  96 + return (0);
  97 + }
  98 +#else
  99 + size_b1 = 0;
  100 +#endif
  101 +
  102 + /* Remap FLASH according to real size */
  103 + memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
  104 +#ifdef CONFIG_MVS_16BIT_FLASH
  105 + memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V;
  106 +#else
  107 + memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_32 | BR_MS_GPCM | BR_V;
  108 +#endif
  109 +
  110 + /* Re-do sizing to get full correct info */
  111 + size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
  112 +
  113 + flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
  114 +
  115 + /* monitor protection ON by default */
  116 + flash_protect(FLAG_PROTECT_SET,
  117 + CFG_FLASH_BASE,
  118 + CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
  119 + &flash_info[0]);
  120 +
  121 + if (size_b1) {
  122 + memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
  123 +#ifdef CONFIG_MVS_16BIT_FLASH
  124 + memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
  125 + BR_PS_16 | BR_MS_GPCM | BR_V;
  126 +#else
  127 + memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
  128 + BR_PS_32 | BR_MS_GPCM | BR_V;
  129 +#endif
  130 + /* Re-do sizing to get full correct info */
  131 + size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
  132 + &flash_info[1]);
  133 +
  134 + flash_get_offsets (CFG_FLASH_BASE + size_b0, &flash_info[1]);
  135 +
  136 + /* monitor protection ON by default */
  137 + flash_protect(FLAG_PROTECT_SET,
  138 + CFG_FLASH_BASE,
  139 + CFG_FLASH_BASE+CFG_MONITOR_LEN-1,
  140 + &flash_info[1]);
  141 + } else {
  142 + memctl->memc_br1 = 0; /* invalidate bank */
  143 +
  144 + flash_info[1].flash_id = FLASH_UNKNOWN;
  145 + flash_info[1].sector_count = -1;
  146 + }
  147 +
  148 + flash_info[0].size = size_b0;
  149 + flash_info[1].size = size_b1;
  150 +
  151 + return (size_b0 + size_b1);
  152 +}
  153 +
  154 +/*-----------------------------------------------------------------------
  155 + */
  156 +static void flash_get_offsets (ulong base, flash_info_t *info)
  157 +{
  158 + int i;
  159 +
  160 + /* set up sector start address table */
  161 + if (info->flash_id & FLASH_BTYPE)
  162 + { /* bottom boot sector types - these are the useful ones! */
  163 + /* set sector offsets for bottom boot block type */
  164 + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B)
  165 + { /* AMDLV320B has 8 x 8k bottom boot sectors */
  166 + for (i = 0; i < 8; i++) /* +8k */
  167 + info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
  168 + for (; i < info->sector_count; i++) /* +64k */
  169 + info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00070000 << FLASH_SHIFT);
  170 + }
  171 + else
  172 + { /* other types have 4 bottom boot sectors (16,8,8,32) */
  173 + i = 0;
  174 + info->start[i++] = base + 0x00000000; /* - */
  175 + info->start[i++] = base + (0x00004000 << FLASH_SHIFT); /* +16k */
  176 + info->start[i++] = base + (0x00006000 << FLASH_SHIFT); /* +8k */
  177 + info->start[i++] = base + (0x00008000 << FLASH_SHIFT); /* +8k */
  178 + info->start[i++] = base + (0x00010000 << FLASH_SHIFT); /* +32k */
  179 + for (; i < info->sector_count; i++) /* +64k */
  180 + info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00030000 << FLASH_SHIFT);
  181 + }
  182 + }
  183 + else
  184 + { /* top boot sector types - not so useful */
  185 + /* set sector offsets for top boot block type */
  186 + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T)
  187 + { /* AMDLV320T has 8 x 8k top boot sectors */
  188 + for (i = 0; i < info->sector_count - 8; i++) /* +64k */
  189 + info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
  190 + for (; i < info->sector_count; i++) /* +8k */
  191 + info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
  192 + }
  193 + else
  194 + { /* other types have 4 top boot sectors (32,8,8,16) */
  195 + for (i = 0; i < info->sector_count - 4; i++) /* +64k */
  196 + info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
  197 +
  198 + info->start[i++] = base + info->size - (0x00010000 << FLASH_SHIFT); /* -32k */
  199 + info->start[i++] = base + info->size - (0x00008000 << FLASH_SHIFT); /* -8k */
  200 + info->start[i++] = base + info->size - (0x00006000 << FLASH_SHIFT); /* -8k */
  201 + info->start[i] = base + info->size - (0x00004000 << FLASH_SHIFT); /* -16k */
  202 + }
  203 + }
  204 +}
  205 +
  206 +/*-----------------------------------------------------------------------
  207 + */
  208 +void flash_print_info (flash_info_t *info)
  209 +{
  210 + int i;
  211 +
  212 + if (info->flash_id == FLASH_UNKNOWN) {
  213 + printf ("missing or unknown FLASH type\n");
  214 + return;
  215 + }
  216 +
  217 + switch (info->flash_id & FLASH_VENDMASK) {
  218 + case FLASH_MAN_AMD: printf ("AMD "); break;
  219 + case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
  220 + case FLASH_MAN_STM: printf ("ST "); break;
  221 + default: printf ("Unknown Vendor "); break;
  222 + }
  223 +
  224 + switch (info->flash_id & FLASH_TYPEMASK) {
  225 + case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
  226 + break;
  227 + case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
  228 + break;
  229 + case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
  230 + break;
  231 + case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
  232 + break;
  233 + case FLASH_STMW320DB: printf ("M29W320B (32 Mbit, bottom boot sect)\n");
  234 + break;
  235 + case FLASH_STMW320DT: printf ("M29W320T (32 Mbit, top boot sector)\n");
  236 + break;
  237 + default: printf ("Unknown Chip Type\n");
  238 + break;
  239 + }
  240 +
  241 + printf (" Size: %ld MB in %d Sectors\n",
  242 + info->size >> 20, info->sector_count);
  243 +
  244 + printf (" Sector Start Addresses:");
  245 + for (i=0; i<info->sector_count; ++i) {
  246 + if ((i % 5) == 0)
  247 + printf ("\n ");
  248 + printf (" %08lX%s",
  249 + info->start[i],
  250 + info->protect[i] ? " (RO)" : " "
  251 + );
  252 + }
  253 + printf ("\n");
  254 +}
  255 +
  256 +/*-----------------------------------------------------------------------
  257 + */
  258 +
  259 +
  260 +/*-----------------------------------------------------------------------
  261 + */
  262 +
  263 +/*
  264 + * The following code cannot be run from FLASH!
  265 + */
  266 +
  267 +#define AMD_ID_LV160T_MVS (AMD_ID_LV160T & FLASH_DATA_MASK)
  268 +#define AMD_ID_LV160B_MVS (AMD_ID_LV160B & FLASH_DATA_MASK)
  269 +#define AMD_ID_LV320T_MVS (AMD_ID_LV320T & FLASH_DATA_MASK)
  270 +#define AMD_ID_LV320B_MVS (AMD_ID_LV320B & FLASH_DATA_MASK)
  271 +#define STM_ID_W320DT_MVS (STM_ID_29W320DT & FLASH_DATA_MASK)
  272 +#define STM_ID_W320DB_MVS (STM_ID_29W320DB & FLASH_DATA_MASK)
  273 +#define AMD_MANUFACT_MVS (AMD_MANUFACT & FLASH_DATA_MASK)
  274 +#define FUJ_MANUFACT_MVS (FUJ_MANUFACT & FLASH_DATA_MASK)
  275 +#define STM_MANUFACT_MVS (STM_MANUFACT & FLASH_DATA_MASK)
  276 +
  277 +#define AUTOSELECT_ADDR1 0x0555
  278 +#define AUTOSELECT_ADDR2 0x02AA
  279 +#define AUTOSELECT_ADDR3 AUTOSELECT_ADDR1
  280 +
  281 +#define AUTOSELECT_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
  282 +#define AUTOSELECT_DATA2 (0x00550055 & FLASH_DATA_MASK)
  283 +#define AUTOSELECT_DATA3 (0x00900090 & FLASH_DATA_MASK)
  284 +
  285 +#define RESET_BANK_DATA (0x00F000F0 & FLASH_DATA_MASK)
  286 +
  287 +static ulong flash_get_size (vu_long *address, flash_info_t *info)
  288 +{
  289 + short i;
  290 +#ifdef CONFIG_MVS_16BIT_FLASH
  291 + ushort value;
  292 + vu_short *addr = (vu_short *)address;
  293 +#else
  294 + ulong value;
  295 + vu_long *addr = (vu_long *)address;
  296 +#endif
  297 + ulong base = (ulong)address;
  298 +
  299 + /* Write auto select command: read Manufacturer ID */
  300 + addr[AUTOSELECT_ADDR1] = AUTOSELECT_DATA1;
  301 + addr[AUTOSELECT_ADDR2] = AUTOSELECT_DATA2;
  302 + addr[AUTOSELECT_ADDR3] = AUTOSELECT_DATA3;
  303 +
  304 + value = addr[0]; /* manufacturer ID */
  305 + switch (value) {
  306 + case AMD_MANUFACT_MVS:
  307 + info->flash_id = FLASH_MAN_AMD;
  308 + break;
  309 + case FUJ_MANUFACT_MVS:
  310 + info->flash_id = FLASH_MAN_FUJ;
  311 + break;
  312 + case STM_MANUFACT_MVS:
  313 + info->flash_id = FLASH_MAN_STM;
  314 + break;
  315 + default:
  316 + info->flash_id = FLASH_UNKNOWN;
  317 + info->sector_count = 0;
  318 + info->size = 0;
  319 + return (0); /* no or unknown flash */
  320 + }
  321 +
  322 + value = addr[1]; /* device ID */
  323 + switch (value) {
  324 + case AMD_ID_LV160T_MVS:
  325 + info->flash_id += FLASH_AM160T;
  326 + info->sector_count = 37;
  327 + info->size = (0x00200000 << FLASH_SHIFT);
  328 + break; /* => 2 or 4 MB */
  329 +
  330 + case AMD_ID_LV160B_MVS:
  331 + info->flash_id += FLASH_AM160B;
  332 + info->sector_count = 37;
  333 + info->size = (0x00200000 << FLASH_SHIFT);
  334 + break; /* => 2 or 4 MB */
  335 +
  336 + case AMD_ID_LV320T_MVS:
  337 + info->flash_id += FLASH_AM320T;
  338 + info->sector_count = 71;
  339 + info->size = (0x00400000 << FLASH_SHIFT);
  340 + break; /* => 4 or 8 MB */
  341 +
  342 + case AMD_ID_LV320B_MVS:
  343 + info->flash_id += FLASH_AM320B;
  344 + info->sector_count = 71;
  345 + info->size = (0x00400000 << FLASH_SHIFT);
  346 + break; /* => 4 or 8MB */
  347 +
  348 + case STM_ID_W320DT_MVS:
  349 + info->flash_id += FLASH_STMW320DT;
  350 + info->sector_count = 67;
  351 + info->size = (0x00400000 << FLASH_SHIFT);
  352 + break; /* => 4 or 8 MB */
  353 +
  354 + case STM_ID_W320DB_MVS:
  355 + info->flash_id += FLASH_STMW320DB;
  356 + info->sector_count = 67;
  357 + info->size = (0x00400000 << FLASH_SHIFT);
  358 + break; /* => 4 or 8MB */
  359 +
  360 + default:
  361 + info->flash_id = FLASH_UNKNOWN;
  362 + return (0); /* => no or unknown flash */
  363 +
  364 + }
  365 +
  366 + /* set up sector start address table */
  367 + flash_get_offsets (base, info);
  368 +
  369 + /* check for protected sectors */
  370 + for (i = 0; i < info->sector_count; i++) {
  371 + /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  372 + /* D0 = 1 if protected */
  373 +#ifdef CONFIG_MVS_16BIT_FLASH
  374 + addr = (vu_short *)(info->start[i]);
  375 +#else
  376 + addr = (vu_long *)(info->start[i]);
  377 +#endif
  378 + info->protect[i] = addr[2] & 1;
  379 + }
  380 +
  381 + /*
  382 + * Prevent writes to uninitialized FLASH.
  383 + */
  384 + if (info->flash_id != FLASH_UNKNOWN) {
  385 +#ifdef CONFIG_MVS_16BIT_FLASH
  386 + addr = (vu_short *)info->start[0];
  387 +#else
  388 + addr = (vu_long *)info->start[0];
  389 +#endif
  390 + *addr = RESET_BANK_DATA; /* reset bank */
  391 + }
  392 +
  393 + return (info->size);
  394 +}
  395 +
  396 +
  397 +/*-----------------------------------------------------------------------
  398 + */
  399 +
  400 +#define ERASE_ADDR1 0x0555
  401 +#define ERASE_ADDR2 0x02AA
  402 +#define ERASE_ADDR3 ERASE_ADDR1
  403 +#define ERASE_ADDR4 ERASE_ADDR1
  404 +#define ERASE_ADDR5 ERASE_ADDR2
  405 +
  406 +#define ERASE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
  407 +#define ERASE_DATA2 (0x00550055 & FLASH_DATA_MASK)
  408 +#define ERASE_DATA3 (0x00800080 & FLASH_DATA_MASK)
  409 +#define ERASE_DATA4 ERASE_DATA1
  410 +#define ERASE_DATA5 ERASE_DATA2
  411 +
  412 +#define ERASE_SECTOR_DATA (0x00300030 & FLASH_DATA_MASK)
  413 +#define ERASE_CHIP_DATA (0x00100010 & FLASH_DATA_MASK)
  414 +#define ERASE_CONFIRM_DATA (0x00800080 & FLASH_DATA_MASK)
  415 +
  416 +int flash_erase (flash_info_t *info, int s_first, int s_last)
  417 +{
  418 +#ifdef CONFIG_MVS_16BIT_FLASH
  419 + vu_short *addr = (vu_short *)(info->start[0]);
  420 +#else
  421 + vu_long *addr = (vu_long *)(info->start[0]);
  422 +#endif
  423 + int flag, prot, sect, l_sect;
  424 + ulong start, now, last;
  425 +
  426 + if ((s_first < 0) || (s_first > s_last)) {
  427 + if (info->flash_id == FLASH_UNKNOWN) {
  428 + printf ("- missing\n");
  429 + } else {
  430 + printf ("- no sectors to erase\n");
  431 + }
  432 + return 1;
  433 + }
  434 +
  435 + if ((info->flash_id == FLASH_UNKNOWN) ||
  436 + (info->flash_id > FLASH_AMD_COMP)) {
  437 + printf ("Can't erase unknown flash type %08lx - aborted\n",
  438 + info->flash_id);
  439 + return 1;
  440 + }
  441 +
  442 + prot = 0;
  443 + for (sect=s_first; sect<=s_last; ++sect) {
  444 + if (info->protect[sect]) {
  445 + prot++;
  446 + }
  447 + }
  448 +
  449 + if (prot) {
  450 + printf ("- Warning: %d protected sectors will not be erased!\n",
  451 + prot);
  452 + } else {
  453 + printf ("\n");
  454 + }
  455 +
  456 + l_sect = -1;
  457 +
  458 + /* Disable interrupts which might cause a timeout here */
  459 + flag = disable_interrupts();
  460 +
  461 + addr[ERASE_ADDR1] = ERASE_DATA1;
  462 + addr[ERASE_ADDR2] = ERASE_DATA2;
  463 + addr[ERASE_ADDR3] = ERASE_DATA3;
  464 + addr[ERASE_ADDR4] = ERASE_DATA4;
  465 + addr[ERASE_ADDR5] = ERASE_DATA5;
  466 +
  467 + /* Start erase on unprotected sectors */
  468 + for (sect = s_first; sect<=s_last; sect++) {
  469 + if (info->protect[sect] == 0) { /* not protected */
  470 +#ifdef CONFIG_MVS_16BIT_FLASH
  471 + addr = (vu_short *)(info->start[sect]);
  472 +#else
  473 + addr = (vu_long *)(info->start[sect]);
  474 +#endif
  475 + addr[0] = ERASE_SECTOR_DATA;
  476 + l_sect = sect;
  477 + }
  478 + }
  479 +
  480 + /* re-enable interrupts if necessary */
  481 + if (flag)
  482 + enable_interrupts();
  483 +
  484 + /* wait at least 80us - let's wait 1 ms */
  485 + udelay (1000);
  486 +
  487 + /*
  488 + * We wait for the last triggered sector
  489 + */
  490 + if (l_sect < 0)
  491 + goto DONE;
  492 +
  493 + start = get_timer (0);
  494 + last = start;
  495 +#ifdef CONFIG_MVS_16BIT_FLASH
  496 + addr = (vu_short *)(info->start[l_sect]);
  497 +#else
  498 + addr = (vu_long *)(info->start[l_sect]);
  499 +#endif
  500 + while ((addr[0] & ERASE_CONFIRM_DATA) != ERASE_CONFIRM_DATA) {
  501 + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  502 + printf ("Timeout\n");
  503 + return 1;
  504 + }
  505 + /* show that we're waiting */
  506 + if ((now - last) > 1000) { /* every second */
  507 + putc ('.');
  508 + last = now;
  509 + }
  510 + }
  511 +
  512 +DONE:
  513 + /* reset to read mode */
  514 +#ifdef CONFIG_MVS_16BIT_FLASH
  515 + addr = (vu_short *)info->start[0];
  516 +#else
  517 + addr = (vu_long *)info->start[0];
  518 +#endif
  519 + addr[0] = RESET_BANK_DATA; /* reset bank */
  520 +
  521 + printf (" done\n");
  522 + return 0;
  523 +}
  524 +
  525 +
  526 +/*-----------------------------------------------------------------------
  527 + * Copy memory to flash, returns:
  528 + * 0 - OK
  529 + * 1 - write timeout
  530 + * 2 - Flash not erased
  531 + */
  532 +
  533 +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  534 +{
  535 +#define BUFF_INC 4
  536 + ulong cp, wp, data;
  537 + int i, l, rc;
  538 +
  539 + mvdebug (("+write_buff %p ==> 0x%08lx, count = 0x%08lx\n", src, addr, cnt));
  540 +
  541 + wp = (addr & ~3); /* get lower word aligned address */
  542 + /*
  543 + * handle unaligned start bytes
  544 + */
  545 + if ((l = addr - wp) != 0) {
  546 + mvdebug ((" handle unaligned start bytes (cnt = 0x%08%lx)\n", cnt));
  547 + data = 0;
  548 + for (i=0, cp=wp; i<l; ++i, ++cp) {
  549 + data = (data << 8) | (*(uchar *)cp);
  550 + }
  551 + for (; i<BUFF_INC && cnt>0; ++i) {
  552 + data = (data << 8) | *src++;
  553 + --cnt;
  554 + ++cp;
  555 + }
  556 + for (; cnt==0 && i<BUFF_INC; ++i, ++cp) {
  557 + data = (data << 8) | (*(uchar *)cp);
  558 + }
  559 +
  560 + if ((rc = write_word(info, wp, data)) != 0) {
  561 + return (rc);
  562 + }
  563 + wp += BUFF_INC;
  564 + }
  565 +
  566 + /*
  567 + * handle (half)word aligned part
  568 + */
  569 + mvdebug ((" handle word aligned part (cnt = 0x%08%lx)\n", cnt));
  570 + while (cnt >= BUFF_INC) {
  571 + data = 0;
  572 + for (i=0; i<BUFF_INC; ++i) {
  573 + data = (data << 8) | *src++;
  574 + }
  575 + if ((rc = write_word(info, wp, data)) != 0) {
  576 + return (rc);
  577 + }
  578 + wp += BUFF_INC;
  579 + cnt -= BUFF_INC;
  580 + }
  581 +
  582 + if (cnt == 0) {
  583 + return (0);
  584 + }
  585 +
  586 + /*
  587 + * handle unaligned tail bytes
  588 + */
  589 + mvdebug ((" handle unaligned tail bytes (cnt = 0x%08%lx)\n", cnt));
  590 + data = 0;
  591 + for (i=0, cp=wp; i<BUFF_INC && cnt>0; ++i, ++cp) {
  592 + data = (data << 8) | *src++;
  593 + --cnt;
  594 + }
  595 + for (; i<BUFF_INC; ++i, ++cp) {
  596 + data = (data << 8) | (*(uchar *)cp);
  597 + }
  598 +
  599 + return (write_word(info, wp, data));
  600 +}
  601 +
  602 +#define WRITE_ADDR1 0x0555
  603 +#define WRITE_ADDR2 0x02AA
  604 +#define WRITE_ADDR3 WRITE_ADDR1
  605 +
  606 +#define WRITE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
  607 +#define WRITE_DATA2 (0x00550055 & FLASH_DATA_MASK)
  608 +#define WRITE_DATA3 (0x00A000A0 & FLASH_DATA_MASK)
  609 +
  610 +#define WRITE_CONFIRM_DATA ERASE_CONFIRM_DATA
  611 +
  612 +#ifndef CONFIG_MVS_16BIT_FLASH
  613 +/*-----------------------------------------------------------------------
  614 + * Write a word to Flash, returns:
  615 + * 0 - OK
  616 + * 1 - write timeout
  617 + * 2 - Flash not erased
  618 + */
  619 +static int write_word (flash_info_t *info, ulong dest, ulong data)
  620 +{
  621 + vu_long *addr = (vu_long *)(info->start[0]);
  622 + ulong start;
  623 + int flag;
  624 +
  625 + mvdebug (("+write_word (to 0x%08lx)\n", dest));
  626 + /* Check if Flash is (sufficiently) erased */
  627 + if ((*((vu_long *)dest) & data) != data) {
  628 + return (2);
  629 + }
  630 + /* Disable interrupts which might cause a timeout here */
  631 + flag = disable_interrupts();
  632 +
  633 + addr[WRITE_ADDR1] = WRITE_DATA1;
  634 + addr[WRITE_ADDR2] = WRITE_DATA2;
  635 + addr[WRITE_ADDR3] = WRITE_DATA3;
  636 +
  637 + *((vu_long *)dest) = data;
  638 +
  639 + /* re-enable interrupts if necessary */
  640 + if (flag)
  641 + enable_interrupts();
  642 +
  643 + /* data polling for D7 */
  644 + start = get_timer (0);
  645 + addr = (vu_long *)dest;
  646 + while ((*addr & WRITE_CONFIRM_DATA) != (data & WRITE_CONFIRM_DATA)) {
  647 + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  648 + return (1);
  649 + }
  650 + }
  651 +
  652 + mvdebug (("-write_word\n"));
  653 + return (0);
  654 +}
  655 +#else /* CONFIG_MVS_16BIT_FLASH */
  656 +/*-----------------------------------------------------------------------
  657 + * Write a halfword to Flash, returns:
  658 + * 0 - OK
  659 + * 1 - write timeout
  660 + * 2 - Flash not erased
  661 + */
  662 +static int write_halfword (flash_info_t *info, ulong dest, ushort data)
  663 +{
  664 + vu_short *addr = (vu_short *)(info->start[0]);
  665 + ulong start;
  666 + int flag;
  667 +
  668 + mvdebug (("+write_halfword (to 0x%08lx)\n", dest));
  669 + /* Check if Flash is (sufficiently) erased */
  670 + if ((*((vu_short *)dest) & data) != data) {
  671 + return (2);
  672 + }
  673 + /* Disable interrupts which might cause a timeout here */
  674 + flag = disable_interrupts();
  675 +
  676 + addr[WRITE_ADDR1] = WRITE_DATA1;
  677 + addr[WRITE_ADDR2] = WRITE_DATA2;
  678 + addr[WRITE_ADDR3] = WRITE_DATA3;
  679 +
  680 + *((vu_short *)dest) = data;
  681 +
  682 + /* re-enable interrupts if necessary */
  683 + if (flag)
  684 + enable_interrupts();
  685 +
  686 + /* data polling for D7 */
  687 + start = get_timer (0);
  688 + addr = (vu_short *)dest;
  689 + while ((*addr & WRITE_CONFIRM_DATA) != (data & WRITE_CONFIRM_DATA)) {
  690 + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  691 + return (1);
  692 + }
  693 + }
  694 + mvdebug (("-write_halfword\n"));
  695 + return (0);
  696 +}
  697 +
  698 +
  699 +/*-----------------------------------------------------------------------
  700 + * Write a word to Flash, returns:
  701 + * 0 - OK
  702 + * 1 - write timeout
  703 + * 2 - Flash not erased
  704 + */
  705 +static int write_word (flash_info_t *info, ulong dest, ulong data)
  706 +{
  707 + int result = 0;
  708 +
  709 + if (write_halfword (info, dest, (data & ~FLASH_DATA_MASK) >> 16) == 0)
  710 + {
  711 + dest += 2;
  712 + data = data & FLASH_DATA_MASK;
  713 + result = write_halfword (info, dest, data);
  714 + }
  715 + return result;
  716 +}
  717 +#endif
  718 +/*-----------------------------------------------------------------------
  719 + */