Home | History | Annotate | Download | only in mach-socfpga
      1 // SPDX-License-Identifier: BSD-3-Clause
      2 /*
      3  * Copyright (C) 2012 Altera Corporation <www.altera.com>
      4  * All rights reserved.
      5  *
      6  * This file contains only support functions used also by the SoCFPGA
      7  * platform code, the real meat is located in drivers/fpga/socfpga.c .
      8  */
      9 
     10 #include <common.h>
     11 #include <asm/io.h>
     12 #include <linux/errno.h>
     13 #include <asm/arch/fpga_manager.h>
     14 #include <asm/arch/reset_manager.h>
     15 #include <asm/arch/system_manager.h>
     16 
     17 /* Timeout count */
     18 #define FPGA_TIMEOUT_CNT		0x1000000
     19 
     20 static struct socfpga_fpga_manager *fpgamgr_regs =
     21 	(struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS;
     22 
     23 /* Check whether FPGA Init_Done signal is high */
     24 static int is_fpgamgr_initdone_high(void)
     25 {
     26 	unsigned long val;
     27 
     28 	val = readl(&fpgamgr_regs->gpio_ext_porta);
     29 	return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK;
     30 }
     31 
     32 /* Get the FPGA mode */
     33 int fpgamgr_get_mode(void)
     34 {
     35 	unsigned long val;
     36 
     37 	val = readl(&fpgamgr_regs->stat);
     38 	return val & FPGAMGRREGS_STAT_MODE_MASK;
     39 }
     40 
     41 /* Check whether FPGA is ready to be accessed */
     42 int fpgamgr_test_fpga_ready(void)
     43 {
     44 	/* Check for init done signal */
     45 	if (!is_fpgamgr_initdone_high())
     46 		return 0;
     47 
     48 	/* Check again to avoid false glitches */
     49 	if (!is_fpgamgr_initdone_high())
     50 		return 0;
     51 
     52 	if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE)
     53 		return 0;
     54 
     55 	return 1;
     56 }
     57 
     58 /* Poll until FPGA is ready to be accessed or timeout occurred */
     59 int fpgamgr_poll_fpga_ready(void)
     60 {
     61 	unsigned long i;
     62 
     63 	/* If FPGA is blank, wait till WD invoke warm reset */
     64 	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
     65 		/* check for init done signal */
     66 		if (!is_fpgamgr_initdone_high())
     67 			continue;
     68 		/* check again to avoid false glitches */
     69 		if (!is_fpgamgr_initdone_high())
     70 			continue;
     71 		return 1;
     72 	}
     73 
     74 	return 0;
     75 }
     76