1*83d290c5STom Rini // SPDX-License-Identifier: BSD-3-Clause 205a21721SMasahiro Yamada /* 305a21721SMasahiro Yamada * Copyright (C) 2012 Altera Corporation <www.altera.com> 405a21721SMasahiro Yamada * All rights reserved. 505a21721SMasahiro Yamada * 605a21721SMasahiro Yamada * This file contains only support functions used also by the SoCFPGA 705a21721SMasahiro Yamada * platform code, the real meat is located in drivers/fpga/socfpga.c . 805a21721SMasahiro Yamada */ 905a21721SMasahiro Yamada 1005a21721SMasahiro Yamada #include <common.h> 1105a21721SMasahiro Yamada #include <asm/io.h> 121221ce45SMasahiro Yamada #include <linux/errno.h> 1305a21721SMasahiro Yamada #include <asm/arch/fpga_manager.h> 1405a21721SMasahiro Yamada #include <asm/arch/reset_manager.h> 1505a21721SMasahiro Yamada #include <asm/arch/system_manager.h> 1605a21721SMasahiro Yamada 1705a21721SMasahiro Yamada /* Timeout count */ 1805a21721SMasahiro Yamada #define FPGA_TIMEOUT_CNT 0x1000000 1905a21721SMasahiro Yamada 2005a21721SMasahiro Yamada static struct socfpga_fpga_manager *fpgamgr_regs = 2105a21721SMasahiro Yamada (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; 2205a21721SMasahiro Yamada 2305a21721SMasahiro Yamada /* Check whether FPGA Init_Done signal is high */ is_fpgamgr_initdone_high(void)2405a21721SMasahiro Yamadastatic int is_fpgamgr_initdone_high(void) 2505a21721SMasahiro Yamada { 2605a21721SMasahiro Yamada unsigned long val; 2705a21721SMasahiro Yamada 2805a21721SMasahiro Yamada val = readl(&fpgamgr_regs->gpio_ext_porta); 2905a21721SMasahiro Yamada return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK; 3005a21721SMasahiro Yamada } 3105a21721SMasahiro Yamada 3205a21721SMasahiro Yamada /* Get the FPGA mode */ fpgamgr_get_mode(void)3305a21721SMasahiro Yamadaint fpgamgr_get_mode(void) 3405a21721SMasahiro Yamada { 3505a21721SMasahiro Yamada unsigned long val; 3605a21721SMasahiro Yamada 3705a21721SMasahiro Yamada val = readl(&fpgamgr_regs->stat); 3805a21721SMasahiro Yamada return val & FPGAMGRREGS_STAT_MODE_MASK; 3905a21721SMasahiro Yamada } 4005a21721SMasahiro Yamada 4105a21721SMasahiro Yamada /* Check whether FPGA is ready to be accessed */ fpgamgr_test_fpga_ready(void)4205a21721SMasahiro Yamadaint fpgamgr_test_fpga_ready(void) 4305a21721SMasahiro Yamada { 4405a21721SMasahiro Yamada /* Check for init done signal */ 4505a21721SMasahiro Yamada if (!is_fpgamgr_initdone_high()) 4605a21721SMasahiro Yamada return 0; 4705a21721SMasahiro Yamada 4805a21721SMasahiro Yamada /* Check again to avoid false glitches */ 4905a21721SMasahiro Yamada if (!is_fpgamgr_initdone_high()) 5005a21721SMasahiro Yamada return 0; 5105a21721SMasahiro Yamada 5205a21721SMasahiro Yamada if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) 5305a21721SMasahiro Yamada return 0; 5405a21721SMasahiro Yamada 5505a21721SMasahiro Yamada return 1; 5605a21721SMasahiro Yamada } 5705a21721SMasahiro Yamada 5805a21721SMasahiro Yamada /* Poll until FPGA is ready to be accessed or timeout occurred */ fpgamgr_poll_fpga_ready(void)5905a21721SMasahiro Yamadaint fpgamgr_poll_fpga_ready(void) 6005a21721SMasahiro Yamada { 6105a21721SMasahiro Yamada unsigned long i; 6205a21721SMasahiro Yamada 6305a21721SMasahiro Yamada /* If FPGA is blank, wait till WD invoke warm reset */ 6405a21721SMasahiro Yamada for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { 6505a21721SMasahiro Yamada /* check for init done signal */ 6605a21721SMasahiro Yamada if (!is_fpgamgr_initdone_high()) 6705a21721SMasahiro Yamada continue; 6805a21721SMasahiro Yamada /* check again to avoid false glitches */ 6905a21721SMasahiro Yamada if (!is_fpgamgr_initdone_high()) 7005a21721SMasahiro Yamada continue; 7105a21721SMasahiro Yamada return 1; 7205a21721SMasahiro Yamada } 7305a21721SMasahiro Yamada 7405a21721SMasahiro Yamada return 0; 7505a21721SMasahiro Yamada } 76