uboot/board/freescale/common/qixis.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011 Freescale Semiconductor
   3 * Author: Shengzhou Liu <Shengzhou.Liu@freescale.com>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 *
   7 * This file provides support for the QIXIS of some Freescale reference boards.
   8 */
   9
  10#include <common.h>
  11#include <command.h>
  12#include <asm/io.h>
  13#include <linux/time.h>
  14#include <i2c.h>
  15#include "qixis.h"
  16
  17#ifndef QIXIS_LBMAP_BRDCFG_REG
  18/*
  19 * For consistency with existing platforms
  20 */
  21#define QIXIS_LBMAP_BRDCFG_REG 0x00
  22#endif
  23
  24#ifdef CONFIG_SYS_I2C_FPGA_ADDR
  25u8 qixis_read_i2c(unsigned int reg)
  26{
  27        return i2c_reg_read(CONFIG_SYS_I2C_FPGA_ADDR, reg);
  28}
  29
  30void qixis_write_i2c(unsigned int reg, u8 value)
  31{
  32        u8 val = value;
  33        i2c_reg_write(CONFIG_SYS_I2C_FPGA_ADDR, reg, val);
  34}
  35#endif
  36
  37#ifdef QIXIS_BASE
  38u8 qixis_read(unsigned int reg)
  39{
  40        void *p = (void *)QIXIS_BASE;
  41
  42        return in_8(p + reg);
  43}
  44
  45void qixis_write(unsigned int reg, u8 value)
  46{
  47        void *p = (void *)QIXIS_BASE;
  48
  49        out_8(p + reg, value);
  50}
  51#endif
  52
  53u16 qixis_read_minor(void)
  54{
  55        u16 minor;
  56
  57        /* this data is in little endian */
  58        QIXIS_WRITE(tagdata, 5);
  59        minor = QIXIS_READ(tagdata);
  60        QIXIS_WRITE(tagdata, 6);
  61        minor += QIXIS_READ(tagdata) << 8;
  62
  63        return minor;
  64}
  65
  66char *qixis_read_time(char *result)
  67{
  68        time_t time = 0;
  69        int i;
  70
  71        /* timestamp is in 32-bit big endian */
  72        for (i = 8; i <= 11; i++) {
  73                QIXIS_WRITE(tagdata, i);
  74                time =  (time << 8) + QIXIS_READ(tagdata);
  75        }
  76
  77        return ctime_r(&time, result);
  78}
  79
  80char *qixis_read_tag(char *buf)
  81{
  82        int i;
  83        char tag, *ptr = buf;
  84
  85        for (i = 16; i <= 63; i++) {
  86                QIXIS_WRITE(tagdata, i);
  87                tag = QIXIS_READ(tagdata);
  88                *(ptr++) = tag;
  89                if (!tag)
  90                        break;
  91        }
  92        if (i > 63)
  93                *ptr = '\0';
  94
  95        return buf;
  96}
  97
  98/*
  99 * return the string of binary of u8 in the format of
 100 * 1010 10_0. The masked bit is filled as underscore.
 101 */
 102const char *byte_to_binary_mask(u8 val, u8 mask, char *buf)
 103{
 104        char *ptr;
 105        int i;
 106
 107        ptr = buf;
 108        for (i = 0x80; i > 0x08 ; i >>= 1, ptr++)
 109                *ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
 110        *(ptr++) = ' ';
 111        for (i = 0x08; i > 0 ; i >>= 1, ptr++)
 112                *ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
 113
 114        *ptr = '\0';
 115
 116        return buf;
 117}
 118
 119#ifdef QIXIS_RST_FORCE_MEM
 120void board_assert_mem_reset(void)
 121{
 122        u8 rst;
 123
 124        rst = QIXIS_READ(rst_frc[0]);
 125        if (!(rst & QIXIS_RST_FORCE_MEM))
 126                QIXIS_WRITE(rst_frc[0], rst | QIXIS_RST_FORCE_MEM);
 127}
 128
 129void board_deassert_mem_reset(void)
 130{
 131        u8 rst;
 132
 133        rst = QIXIS_READ(rst_frc[0]);
 134        if (rst & QIXIS_RST_FORCE_MEM)
 135                QIXIS_WRITE(rst_frc[0], rst & ~QIXIS_RST_FORCE_MEM);
 136}
 137#endif
 138
 139void qixis_reset(void)
 140{
 141        QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET);
 142}
 143
 144void qixis_bank_reset(void)
 145{
 146        QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
 147        QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
 148}
 149
 150static void __maybe_unused set_lbmap(int lbmap)
 151{
 152        u8 reg;
 153
 154        reg = QIXIS_READ(brdcfg[QIXIS_LBMAP_BRDCFG_REG]);
 155        reg = (reg & ~QIXIS_LBMAP_MASK) | lbmap;
 156        QIXIS_WRITE(brdcfg[QIXIS_LBMAP_BRDCFG_REG], reg);
 157}
 158
 159static void __maybe_unused set_rcw_src(int rcw_src)
 160{
 161        u8 reg;
 162
 163        reg = QIXIS_READ(dutcfg[1]);
 164        reg = (reg & ~1) | (rcw_src & 1);
 165        QIXIS_WRITE(dutcfg[1], reg);
 166        QIXIS_WRITE(dutcfg[0], (rcw_src >> 1) & 0xff);
 167}
 168
 169static void qixis_dump_regs(void)
 170{
 171        int i;
 172
 173        printf("id      = %02x\n", QIXIS_READ(id));
 174        printf("arch    = %02x\n", QIXIS_READ(arch));
 175        printf("scver   = %02x\n", QIXIS_READ(scver));
 176        printf("model   = %02x\n", QIXIS_READ(model));
 177        printf("rst_ctl = %02x\n", QIXIS_READ(rst_ctl));
 178        printf("aux     = %02x\n", QIXIS_READ(aux));
 179        for (i = 0; i < 16; i++)
 180                printf("brdcfg%02d = %02x\n", i, QIXIS_READ(brdcfg[i]));
 181        for (i = 0; i < 16; i++)
 182                printf("dutcfg%02d = %02x\n", i, QIXIS_READ(dutcfg[i]));
 183        printf("sclk    = %02x%02x%02x\n", QIXIS_READ(sclk[0]),
 184                QIXIS_READ(sclk[1]), QIXIS_READ(sclk[2]));
 185        printf("dclk    = %02x%02x%02x\n", QIXIS_READ(dclk[0]),
 186                QIXIS_READ(dclk[1]), QIXIS_READ(dclk[2]));
 187        printf("aux     = %02x\n", QIXIS_READ(aux));
 188        printf("watch   = %02x\n", QIXIS_READ(watch));
 189        printf("ctl_sys = %02x\n", QIXIS_READ(ctl_sys));
 190        printf("rcw_ctl = %02x\n", QIXIS_READ(rcw_ctl));
 191        printf("present = %02x\n", QIXIS_READ(present));
 192        printf("present2 = %02x\n", QIXIS_READ(present2));
 193        printf("clk_spd = %02x\n", QIXIS_READ(clk_spd));
 194        printf("stat_dut = %02x\n", QIXIS_READ(stat_dut));
 195        printf("stat_sys = %02x\n", QIXIS_READ(stat_sys));
 196        printf("stat_alrm = %02x\n", QIXIS_READ(stat_alrm));
 197}
 198
 199static void __qixis_dump_switch(void)
 200{
 201        puts("Reverse engineering switch is not implemented for this board\n");
 202}
 203
 204void qixis_dump_switch(void)
 205        __attribute__((weak, alias("__qixis_dump_switch")));
 206
 207int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 208{
 209        int i;
 210
 211        if (argc <= 1) {
 212                set_lbmap(QIXIS_LBMAP_DFLTBANK);
 213                qixis_reset();
 214        } else if (strcmp(argv[1], "altbank") == 0) {
 215                set_lbmap(QIXIS_LBMAP_ALTBANK);
 216                qixis_bank_reset();
 217        } else if (strcmp(argv[1], "nand") == 0) {
 218#ifdef QIXIS_LBMAP_NAND
 219                QIXIS_WRITE(rst_ctl, 0x30);
 220                QIXIS_WRITE(rcfg_ctl, 0);
 221                set_lbmap(QIXIS_LBMAP_NAND);
 222                set_rcw_src(QIXIS_RCW_SRC_NAND);
 223                QIXIS_WRITE(rcfg_ctl, 0x20);
 224                QIXIS_WRITE(rcfg_ctl, 0x21);
 225#else
 226                printf("Not implemented\n");
 227#endif
 228        } else if (strcmp(argv[1], "sd") == 0) {
 229#ifdef QIXIS_LBMAP_SD
 230                QIXIS_WRITE(rst_ctl, 0x30);
 231                QIXIS_WRITE(rcfg_ctl, 0);
 232                set_lbmap(QIXIS_LBMAP_SD);
 233                set_rcw_src(QIXIS_RCW_SRC_SD);
 234                QIXIS_WRITE(rcfg_ctl, 0x20);
 235                QIXIS_WRITE(rcfg_ctl, 0x21);
 236#else
 237                printf("Not implemented\n");
 238#endif
 239        } else if (strcmp(argv[1], "sd_qspi") == 0) {
 240#ifdef QIXIS_LBMAP_SD_QSPI
 241                QIXIS_WRITE(rst_ctl, 0x30);
 242                QIXIS_WRITE(rcfg_ctl, 0);
 243                set_lbmap(QIXIS_LBMAP_SD_QSPI);
 244                set_rcw_src(QIXIS_RCW_SRC_SD);
 245                qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x20);
 246                qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x21);
 247#else
 248                printf("Not implemented\n");
 249#endif
 250        } else if (strcmp(argv[1], "qspi") == 0) {
 251#ifdef QIXIS_LBMAP_QSPI
 252                QIXIS_WRITE(rst_ctl, 0x30);
 253                QIXIS_WRITE(rcfg_ctl, 0);
 254                set_lbmap(QIXIS_LBMAP_QSPI);
 255                set_rcw_src(QIXIS_RCW_SRC_QSPI);
 256                qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x20);
 257                qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x21);
 258#else
 259                printf("Not implemented\n");
 260#endif
 261        } else if (strcmp(argv[1], "watchdog") == 0) {
 262                static char *period[9] = {"2s", "4s", "8s", "16s", "32s",
 263                                          "1min", "2min", "4min", "8min"};
 264                u8 rcfg = QIXIS_READ(rcfg_ctl);
 265
 266                if (argv[2] == NULL) {
 267                        printf("qixis watchdog <watchdog_period>\n");
 268                        return 0;
 269                }
 270                for (i = 0; i < ARRAY_SIZE(period); i++) {
 271                        if (strcmp(argv[2], period[i]) == 0) {
 272                                /* disable watchdog */
 273                                QIXIS_WRITE(rcfg_ctl,
 274                                        rcfg & ~QIXIS_RCFG_CTL_WATCHDOG_ENBLE);
 275                                QIXIS_WRITE(watch, ((i<<2) - 1));
 276                                QIXIS_WRITE(rcfg_ctl, rcfg);
 277                                return 0;
 278                        }
 279                }
 280        } else if (strcmp(argv[1], "dump") == 0) {
 281                qixis_dump_regs();
 282                return 0;
 283        } else if (strcmp(argv[1], "switch") == 0) {
 284                qixis_dump_switch();
 285                return 0;
 286        } else {
 287                printf("Invalid option: %s\n", argv[1]);
 288                return 1;
 289        }
 290
 291        return 0;
 292}
 293
 294U_BOOT_CMD(
 295        qixis_reset, CONFIG_SYS_MAXARGS, 1, qixis_reset_cmd,
 296        "Reset the board using the FPGA sequencer",
 297        "- hard reset to default bank\n"
 298        "qixis_reset altbank - reset to alternate bank\n"
 299        "qixis_reset nand - reset to nand\n"
 300        "qixis_reset sd - reset to sd\n"
 301        "qixis_reset sd_qspi - reset to sd with qspi support\n"
 302        "qixis_reset qspi - reset to qspi\n"
 303        "qixis watchdog <watchdog_period> - set the watchdog period\n"
 304        "       period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n"
 305        "qixis_reset dump - display the QIXIS registers\n"
 306        "qixis_reset switch - display switch\n"
 307        );
 308