123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * Stout board CPLD access support
- *
- * Copyright (C) 2015 Renesas Electronics Europe GmbH
- * Copyright (C) 2015 Renesas Electronics Corporation
- * Copyright (C) 2015 Cogent Embedded, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0
- */
- #include <common.h>
- #include <asm/io.h>
- #include <asm/gpio.h>
- #include "cpld.h"
- #define SCLK GPIO_GP_3_24
- #define SSTBZ GPIO_GP_3_25
- #define MOSI GPIO_GP_3_26
- #define MISO GPIO_GP_3_27
- #define CPLD_ADDR_MODE 0x00 /* RW */
- #define CPLD_ADDR_MUX 0x01 /* RW */
- #define CPLD_ADDR_HDMI 0x02 /* RW */
- #define CPLD_ADDR_DIPSW 0x08 /* R */
- #define CPLD_ADDR_RESET 0x80 /* RW */
- #define CPLD_ADDR_VERSION 0xFF /* R */
- static u32 cpld_read(u8 addr)
- {
- int i;
- u32 data = 0;
- for (i = 0; i < 8; i++) {
- gpio_set_value(MOSI, addr & 0x80); /* MSB first */
- gpio_set_value(SCLK, 1);
- addr <<= 1;
- gpio_set_value(SCLK, 0);
- }
- gpio_set_value(MOSI, 0); /* READ */
- gpio_set_value(SSTBZ, 0);
- gpio_set_value(SCLK, 1);
- gpio_set_value(SCLK, 0);
- gpio_set_value(SSTBZ, 1);
- for (i = 0; i < 32; i++) {
- gpio_set_value(SCLK, 1);
- data <<= 1;
- data |= gpio_get_value(MISO); /* MSB first */
- gpio_set_value(SCLK, 0);
- }
- return data;
- }
- static void cpld_write(u8 addr, u32 data)
- {
- int i;
- for (i = 0; i < 32; i++) {
- gpio_set_value(MOSI, data & (1 << 31)); /* MSB first */
- gpio_set_value(SCLK, 1);
- data <<= 1;
- gpio_set_value(SCLK, 0);
- }
- for (i = 0; i < 8; i++) {
- gpio_set_value(MOSI, addr & 0x80); /* MSB first */
- gpio_set_value(SCLK, 1);
- addr <<= 1;
- gpio_set_value(SCLK, 0);
- }
- gpio_set_value(MOSI, 1); /* WRITE */
- gpio_set_value(SSTBZ, 0);
- gpio_set_value(SCLK, 1);
- gpio_set_value(SCLK, 0);
- gpio_set_value(SSTBZ, 1);
- }
- /* LSI pin pull-up control */
- #define PUPR3 0xe606010C
- #define PUPR3_SD3_DAT1 (1 << 27)
- void cpld_init(void)
- {
- u32 val;
- /* PULL-UP on MISO line */
- val = readl(PUPR3);
- val |= PUPR3_SD3_DAT1;
- writel(val, PUPR3);
- gpio_request(SCLK, NULL);
- gpio_request(SSTBZ, NULL);
- gpio_request(MOSI, NULL);
- gpio_request(MISO, NULL);
- gpio_direction_output(SCLK, 0);
- gpio_direction_output(SSTBZ, 1);
- gpio_direction_output(MOSI, 0);
- gpio_direction_input(MISO);
- /* dummy read */
- cpld_read(CPLD_ADDR_VERSION);
- printf("CPLD version: 0x%08x\n",
- cpld_read(CPLD_ADDR_VERSION));
- printf("H2 Mode setting (MD0..28): 0x%08x\n",
- cpld_read(CPLD_ADDR_MODE));
- printf("Multiplexer settings: 0x%08x\n",
- cpld_read(CPLD_ADDR_MUX));
- printf("HDMI setting: 0x%08x\n",
- cpld_read(CPLD_ADDR_HDMI));
- printf("DIPSW (SW3): 0x%08x\n",
- cpld_read(CPLD_ADDR_DIPSW));
- #ifdef CONFIG_SH_SDHI
- /* switch MUX to SD0 */
- val = cpld_read(CPLD_ADDR_MUX);
- val &= ~MUX_MSK_SD0;
- val |= MUX_VAL_SD0;
- cpld_write(CPLD_ADDR_MUX, val);
- #endif
- }
- static int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
- {
- u32 addr, val;
- if (argc < 3)
- return CMD_RET_USAGE;
- addr = simple_strtoul(argv[2], NULL, 16);
- if (!(addr == CPLD_ADDR_VERSION || addr == CPLD_ADDR_MODE ||
- addr == CPLD_ADDR_MUX || addr == CPLD_ADDR_HDMI ||
- addr == CPLD_ADDR_DIPSW || addr == CPLD_ADDR_RESET)) {
- printf("cpld invalid addr\n");
- return CMD_RET_USAGE;
- }
- if (argc == 3 && strcmp(argv[1], "read") == 0) {
- printf("0x%x\n", cpld_read(addr));
- } else if (argc == 4 && strcmp(argv[1], "write") == 0) {
- val = simple_strtoul(argv[3], NULL, 16);
- if (addr == CPLD_ADDR_MUX) {
- /* never mask SCIFA0 console */
- val &= ~MUX_MSK_SCIFA0_USB;
- val |= MUX_VAL_SCIFA0_USB;
- }
- cpld_write(addr, val);
- }
- return 0;
- }
- U_BOOT_CMD(
- cpld, 4, 1, do_cpld,
- "CPLD access",
- "read addr\n"
- "cpld write addr val\n"
- );
- void reset_cpu(ulong addr)
- {
- cpld_write(CPLD_ADDR_RESET, 1);
- }
|