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