1 /** 2 * Copyright 2013 Freescale Semiconductor 3 * Author: Mingkai Hu <Mingkai.hu@freescale.com> 4 * Po Liu <Po.Liu@freescale.com> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 * This file provides support for the board-specific CPLD used on some Freescale 12 * reference boards. 13 * 14 * The following macros need to be defined: 15 * 16 * CONFIG_SYS_CPLD_BASE - The virtual address of the base of the 17 * CPLD register map 18 * 19 */ 20 21 #include <common.h> 22 #include <command.h> 23 #include <asm/io.h> 24 25 #include "cpld.h" 26 /** 27 * Set the boot bank to the alternate bank 28 */ 29 void cpld_set_altbank(u8 banksel) 30 { 31 struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); 32 u8 reg11; 33 34 reg11 = in_8(&cpld_data->flhcsr); 35 36 switch (banksel) { 37 case 1: 38 out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK) 39 | CPLD_BANKSEL_EN | CPLD_SELECT_BANK1); 40 break; 41 case 2: 42 out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK) 43 | CPLD_BANKSEL_EN | CPLD_SELECT_BANK2); 44 break; 45 case 3: 46 out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK) 47 | CPLD_BANKSEL_EN | CPLD_SELECT_BANK3); 48 break; 49 case 4: 50 out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK) 51 | CPLD_BANKSEL_EN | CPLD_SELECT_BANK4); 52 break; 53 default: 54 printf("Invalid value! [1-4]\n"); 55 return; 56 } 57 58 udelay(100); 59 do_reset(NULL, 0, 0, NULL); 60 } 61 62 /** 63 * Set the boot bank to the default bank 64 */ 65 void cpld_set_defbank(void) 66 { 67 cpld_set_altbank(4); 68 } 69 70 #ifdef DEBUG 71 static void cpld_dump_regs(void) 72 { 73 struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); 74 75 printf("chipid1 = 0x%02x\n", in_8(&cpld_data->chipid1)); 76 printf("chipid2 = 0x%02x\n", in_8(&cpld_data->chipid2)); 77 printf("hwver = 0x%02x\n", in_8(&cpld_data->hwver)); 78 printf("cpldver = 0x%02x\n", in_8(&cpld_data->cpldver)); 79 printf("rstcon = 0x%02x\n", in_8(&cpld_data->rstcon)); 80 printf("flhcsr = 0x%02x\n", in_8(&cpld_data->flhcsr)); 81 printf("wdcsr = 0x%02x\n", in_8(&cpld_data->wdcsr)); 82 printf("wdkick = 0x%02x\n", in_8(&cpld_data->wdkick)); 83 printf("fancsr = 0x%02x\n", in_8(&cpld_data->fancsr)); 84 printf("ledcsr = 0x%02x\n", in_8(&cpld_data->ledcsr)); 85 printf("misc = 0x%02x\n", in_8(&cpld_data->misccsr)); 86 printf("bootor = 0x%02x\n", in_8(&cpld_data->bootor)); 87 printf("bootcfg1 = 0x%02x\n", in_8(&cpld_data->bootcfg1)); 88 printf("bootcfg2 = 0x%02x\n", in_8(&cpld_data->bootcfg2)); 89 printf("bootcfg3 = 0x%02x\n", in_8(&cpld_data->bootcfg3)); 90 printf("bootcfg4 = 0x%02x\n", in_8(&cpld_data->bootcfg4)); 91 putc('\n'); 92 } 93 #endif 94 95 int cpld_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 96 { 97 int rc = 0; 98 unsigned char value; 99 100 if (argc <= 1) 101 return cmd_usage(cmdtp); 102 103 if (strcmp(argv[1], "reset") == 0) { 104 if (!strcmp(argv[2], "altbank") && argv[3]) { 105 value = (u8)simple_strtoul(argv[3], NULL, 16); 106 cpld_set_altbank(value); 107 } else if (!argv[2]) 108 cpld_set_defbank(); 109 else 110 cmd_usage(cmdtp); 111 #ifdef DEBUG 112 } else if (strcmp(argv[1], "dump") == 0) { 113 cpld_dump_regs(); 114 #endif 115 } else 116 rc = cmd_usage(cmdtp); 117 118 return rc; 119 } 120 121 U_BOOT_CMD( 122 cpld_cmd, CONFIG_SYS_MAXARGS, 1, cpld_cmd, 123 "Reset the board using the CPLD sequencer", 124 "reset - hard reset to default bank 4\n" 125 "cpld_cmd reset altbank [bank]- reset to alternate bank\n" 126 " - [bank] bank value select 1-4\n" 127 " - bank 1 on the flash 0x0000000~0x0ffffff\n" 128 " - bank 2 on the flash 0x1000000~0x1ffffff\n" 129 " - bank 3 on the flash 0x2000000~0x2ffffff\n" 130 " - bank 4 on the flash 0x3000000~0x3ffffff\n" 131 #ifdef DEBUG 132 "cpld_cmd dump - display the CPLD registers\n" 133 #endif 134 ); 135