socfpga.c (17196B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * FPGA Manager Driver for Altera SOCFPGA 4 * 5 * Copyright (C) 2013-2015 Altera Corporation 6 */ 7#include <linux/completion.h> 8#include <linux/delay.h> 9#include <linux/fpga/fpga-mgr.h> 10#include <linux/interrupt.h> 11#include <linux/io.h> 12#include <linux/module.h> 13#include <linux/of_address.h> 14#include <linux/of_irq.h> 15#include <linux/pm.h> 16 17/* Register offsets */ 18#define SOCFPGA_FPGMGR_STAT_OFST 0x0 19#define SOCFPGA_FPGMGR_CTL_OFST 0x4 20#define SOCFPGA_FPGMGR_DCLKCNT_OFST 0x8 21#define SOCFPGA_FPGMGR_DCLKSTAT_OFST 0xc 22#define SOCFPGA_FPGMGR_GPIO_INTEN_OFST 0x830 23#define SOCFPGA_FPGMGR_GPIO_INTMSK_OFST 0x834 24#define SOCFPGA_FPGMGR_GPIO_INTTYPE_LEVEL_OFST 0x838 25#define SOCFPGA_FPGMGR_GPIO_INT_POL_OFST 0x83c 26#define SOCFPGA_FPGMGR_GPIO_INTSTAT_OFST 0x840 27#define SOCFPGA_FPGMGR_GPIO_RAW_INTSTAT_OFST 0x844 28#define SOCFPGA_FPGMGR_GPIO_PORTA_EOI_OFST 0x84c 29#define SOCFPGA_FPGMGR_GPIO_EXT_PORTA_OFST 0x850 30 31/* Register bit defines */ 32/* SOCFPGA_FPGMGR_STAT register mode field values */ 33#define SOCFPGA_FPGMGR_STAT_POWER_UP 0x0 /*ramping*/ 34#define SOCFPGA_FPGMGR_STAT_RESET 0x1 35#define SOCFPGA_FPGMGR_STAT_CFG 0x2 36#define SOCFPGA_FPGMGR_STAT_INIT 0x3 37#define SOCFPGA_FPGMGR_STAT_USER_MODE 0x4 38#define SOCFPGA_FPGMGR_STAT_UNKNOWN 0x5 39#define SOCFPGA_FPGMGR_STAT_STATE_MASK 0x7 40/* This is a flag value that doesn't really happen in this register field */ 41#define SOCFPGA_FPGMGR_STAT_POWER_OFF 0x0 42 43#define MSEL_PP16_FAST_NOAES_NODC 0x0 44#define MSEL_PP16_FAST_AES_NODC 0x1 45#define MSEL_PP16_FAST_AESOPT_DC 0x2 46#define MSEL_PP16_SLOW_NOAES_NODC 0x4 47#define MSEL_PP16_SLOW_AES_NODC 0x5 48#define MSEL_PP16_SLOW_AESOPT_DC 0x6 49#define MSEL_PP32_FAST_NOAES_NODC 0x8 50#define MSEL_PP32_FAST_AES_NODC 0x9 51#define MSEL_PP32_FAST_AESOPT_DC 0xa 52#define MSEL_PP32_SLOW_NOAES_NODC 0xc 53#define MSEL_PP32_SLOW_AES_NODC 0xd 54#define MSEL_PP32_SLOW_AESOPT_DC 0xe 55#define SOCFPGA_FPGMGR_STAT_MSEL_MASK 0x000000f8 56#define SOCFPGA_FPGMGR_STAT_MSEL_SHIFT 3 57 58/* SOCFPGA_FPGMGR_CTL register */ 59#define SOCFPGA_FPGMGR_CTL_EN 0x00000001 60#define SOCFPGA_FPGMGR_CTL_NCE 0x00000002 61#define SOCFPGA_FPGMGR_CTL_NCFGPULL 0x00000004 62 63#define CDRATIO_X1 0x00000000 64#define CDRATIO_X2 0x00000040 65#define CDRATIO_X4 0x00000080 66#define CDRATIO_X8 0x000000c0 67#define SOCFPGA_FPGMGR_CTL_CDRATIO_MASK 0x000000c0 68 69#define SOCFPGA_FPGMGR_CTL_AXICFGEN 0x00000100 70 71#define CFGWDTH_16 0x00000000 72#define CFGWDTH_32 0x00000200 73#define SOCFPGA_FPGMGR_CTL_CFGWDTH_MASK 0x00000200 74 75/* SOCFPGA_FPGMGR_DCLKSTAT register */ 76#define SOCFPGA_FPGMGR_DCLKSTAT_DCNTDONE_E_DONE 0x1 77 78/* SOCFPGA_FPGMGR_GPIO_* registers share the same bit positions */ 79#define SOCFPGA_FPGMGR_MON_NSTATUS 0x0001 80#define SOCFPGA_FPGMGR_MON_CONF_DONE 0x0002 81#define SOCFPGA_FPGMGR_MON_INIT_DONE 0x0004 82#define SOCFPGA_FPGMGR_MON_CRC_ERROR 0x0008 83#define SOCFPGA_FPGMGR_MON_CVP_CONF_DONE 0x0010 84#define SOCFPGA_FPGMGR_MON_PR_READY 0x0020 85#define SOCFPGA_FPGMGR_MON_PR_ERROR 0x0040 86#define SOCFPGA_FPGMGR_MON_PR_DONE 0x0080 87#define SOCFPGA_FPGMGR_MON_NCONFIG_PIN 0x0100 88#define SOCFPGA_FPGMGR_MON_NSTATUS_PIN 0x0200 89#define SOCFPGA_FPGMGR_MON_CONF_DONE_PIN 0x0400 90#define SOCFPGA_FPGMGR_MON_FPGA_POWER_ON 0x0800 91#define SOCFPGA_FPGMGR_MON_STATUS_MASK 0x0fff 92 93#define SOCFPGA_FPGMGR_NUM_SUPPLIES 3 94#define SOCFPGA_RESUME_TIMEOUT 3 95 96/* In power-up order. Reverse for power-down. */ 97static const char *supply_names[SOCFPGA_FPGMGR_NUM_SUPPLIES] __maybe_unused = { 98 "FPGA-1.5V", 99 "FPGA-1.1V", 100 "FPGA-2.5V", 101}; 102 103struct socfpga_fpga_priv { 104 void __iomem *fpga_base_addr; 105 void __iomem *fpga_data_addr; 106 struct completion status_complete; 107 int irq; 108}; 109 110struct cfgmgr_mode { 111 /* Values to set in the CTRL register */ 112 u32 ctrl; 113 114 /* flag that this table entry is a valid mode */ 115 bool valid; 116}; 117 118/* For SOCFPGA_FPGMGR_STAT_MSEL field */ 119static struct cfgmgr_mode cfgmgr_modes[] = { 120 [MSEL_PP16_FAST_NOAES_NODC] = { CFGWDTH_16 | CDRATIO_X1, 1 }, 121 [MSEL_PP16_FAST_AES_NODC] = { CFGWDTH_16 | CDRATIO_X2, 1 }, 122 [MSEL_PP16_FAST_AESOPT_DC] = { CFGWDTH_16 | CDRATIO_X4, 1 }, 123 [MSEL_PP16_SLOW_NOAES_NODC] = { CFGWDTH_16 | CDRATIO_X1, 1 }, 124 [MSEL_PP16_SLOW_AES_NODC] = { CFGWDTH_16 | CDRATIO_X2, 1 }, 125 [MSEL_PP16_SLOW_AESOPT_DC] = { CFGWDTH_16 | CDRATIO_X4, 1 }, 126 [MSEL_PP32_FAST_NOAES_NODC] = { CFGWDTH_32 | CDRATIO_X1, 1 }, 127 [MSEL_PP32_FAST_AES_NODC] = { CFGWDTH_32 | CDRATIO_X4, 1 }, 128 [MSEL_PP32_FAST_AESOPT_DC] = { CFGWDTH_32 | CDRATIO_X8, 1 }, 129 [MSEL_PP32_SLOW_NOAES_NODC] = { CFGWDTH_32 | CDRATIO_X1, 1 }, 130 [MSEL_PP32_SLOW_AES_NODC] = { CFGWDTH_32 | CDRATIO_X4, 1 }, 131 [MSEL_PP32_SLOW_AESOPT_DC] = { CFGWDTH_32 | CDRATIO_X8, 1 }, 132}; 133 134static u32 socfpga_fpga_readl(struct socfpga_fpga_priv *priv, u32 reg_offset) 135{ 136 return readl(priv->fpga_base_addr + reg_offset); 137} 138 139static void socfpga_fpga_writel(struct socfpga_fpga_priv *priv, u32 reg_offset, 140 u32 value) 141{ 142 writel(value, priv->fpga_base_addr + reg_offset); 143} 144 145static u32 socfpga_fpga_raw_readl(struct socfpga_fpga_priv *priv, 146 u32 reg_offset) 147{ 148 return __raw_readl(priv->fpga_base_addr + reg_offset); 149} 150 151static void socfpga_fpga_raw_writel(struct socfpga_fpga_priv *priv, 152 u32 reg_offset, u32 value) 153{ 154 __raw_writel(value, priv->fpga_base_addr + reg_offset); 155} 156 157static void socfpga_fpga_data_writel(struct socfpga_fpga_priv *priv, u32 value) 158{ 159 writel(value, priv->fpga_data_addr); 160} 161 162static inline void socfpga_fpga_set_bitsl(struct socfpga_fpga_priv *priv, 163 u32 offset, u32 bits) 164{ 165 u32 val; 166 167 val = socfpga_fpga_readl(priv, offset); 168 val |= bits; 169 socfpga_fpga_writel(priv, offset, val); 170} 171 172static inline void socfpga_fpga_clr_bitsl(struct socfpga_fpga_priv *priv, 173 u32 offset, u32 bits) 174{ 175 u32 val; 176 177 val = socfpga_fpga_readl(priv, offset); 178 val &= ~bits; 179 socfpga_fpga_writel(priv, offset, val); 180} 181 182static u32 socfpga_fpga_mon_status_get(struct socfpga_fpga_priv *priv) 183{ 184 return socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_GPIO_EXT_PORTA_OFST) & 185 SOCFPGA_FPGMGR_MON_STATUS_MASK; 186} 187 188static u32 socfpga_fpga_state_get(struct socfpga_fpga_priv *priv) 189{ 190 u32 status = socfpga_fpga_mon_status_get(priv); 191 192 if ((status & SOCFPGA_FPGMGR_MON_FPGA_POWER_ON) == 0) 193 return SOCFPGA_FPGMGR_STAT_POWER_OFF; 194 195 return socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_STAT_OFST) & 196 SOCFPGA_FPGMGR_STAT_STATE_MASK; 197} 198 199static void socfpga_fpga_clear_done_status(struct socfpga_fpga_priv *priv) 200{ 201 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_DCLKSTAT_OFST, 202 SOCFPGA_FPGMGR_DCLKSTAT_DCNTDONE_E_DONE); 203} 204 205/* 206 * Set the DCLKCNT, wait for DCLKSTAT to report the count completed, and clear 207 * the complete status. 208 */ 209static int socfpga_fpga_dclk_set_and_wait_clear(struct socfpga_fpga_priv *priv, 210 u32 count) 211{ 212 int timeout = 2; 213 u32 done; 214 215 /* Clear any existing DONE status. */ 216 if (socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_DCLKSTAT_OFST)) 217 socfpga_fpga_clear_done_status(priv); 218 219 /* Issue the DCLK count. */ 220 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_DCLKCNT_OFST, count); 221 222 /* Poll DCLKSTAT to see if it completed in the timeout period. */ 223 do { 224 done = socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_DCLKSTAT_OFST); 225 if (done == SOCFPGA_FPGMGR_DCLKSTAT_DCNTDONE_E_DONE) { 226 socfpga_fpga_clear_done_status(priv); 227 return 0; 228 } 229 udelay(1); 230 } while (timeout--); 231 232 return -ETIMEDOUT; 233} 234 235static int socfpga_fpga_wait_for_state(struct socfpga_fpga_priv *priv, 236 u32 state) 237{ 238 int timeout = 2; 239 240 /* 241 * HW doesn't support an interrupt for changes in state, so poll to see 242 * if it matches the requested state within the timeout period. 243 */ 244 do { 245 if ((socfpga_fpga_state_get(priv) & state) != 0) 246 return 0; 247 msleep(20); 248 } while (timeout--); 249 250 return -ETIMEDOUT; 251} 252 253static void socfpga_fpga_enable_irqs(struct socfpga_fpga_priv *priv, u32 irqs) 254{ 255 /* set irqs to level sensitive */ 256 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_INTTYPE_LEVEL_OFST, 0); 257 258 /* set interrupt polarity */ 259 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_INT_POL_OFST, irqs); 260 261 /* clear irqs */ 262 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_PORTA_EOI_OFST, irqs); 263 264 /* unmask interrupts */ 265 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_INTMSK_OFST, 0); 266 267 /* enable interrupts */ 268 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_INTEN_OFST, irqs); 269} 270 271static void socfpga_fpga_disable_irqs(struct socfpga_fpga_priv *priv) 272{ 273 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_INTEN_OFST, 0); 274} 275 276static irqreturn_t socfpga_fpga_isr(int irq, void *dev_id) 277{ 278 struct socfpga_fpga_priv *priv = dev_id; 279 u32 irqs, st; 280 bool conf_done, nstatus; 281 282 /* clear irqs */ 283 irqs = socfpga_fpga_raw_readl(priv, SOCFPGA_FPGMGR_GPIO_INTSTAT_OFST); 284 285 socfpga_fpga_raw_writel(priv, SOCFPGA_FPGMGR_GPIO_PORTA_EOI_OFST, irqs); 286 287 st = socfpga_fpga_raw_readl(priv, SOCFPGA_FPGMGR_GPIO_EXT_PORTA_OFST); 288 conf_done = (st & SOCFPGA_FPGMGR_MON_CONF_DONE) != 0; 289 nstatus = (st & SOCFPGA_FPGMGR_MON_NSTATUS) != 0; 290 291 /* success */ 292 if (conf_done && nstatus) { 293 /* disable irqs */ 294 socfpga_fpga_raw_writel(priv, 295 SOCFPGA_FPGMGR_GPIO_INTEN_OFST, 0); 296 complete(&priv->status_complete); 297 } 298 299 return IRQ_HANDLED; 300} 301 302static int socfpga_fpga_wait_for_config_done(struct socfpga_fpga_priv *priv) 303{ 304 int timeout, ret = 0; 305 306 socfpga_fpga_disable_irqs(priv); 307 init_completion(&priv->status_complete); 308 socfpga_fpga_enable_irqs(priv, SOCFPGA_FPGMGR_MON_CONF_DONE); 309 310 timeout = wait_for_completion_interruptible_timeout( 311 &priv->status_complete, 312 msecs_to_jiffies(10)); 313 if (timeout == 0) 314 ret = -ETIMEDOUT; 315 316 socfpga_fpga_disable_irqs(priv); 317 return ret; 318} 319 320static int socfpga_fpga_cfg_mode_get(struct socfpga_fpga_priv *priv) 321{ 322 u32 msel; 323 324 msel = socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_STAT_OFST); 325 msel &= SOCFPGA_FPGMGR_STAT_MSEL_MASK; 326 msel >>= SOCFPGA_FPGMGR_STAT_MSEL_SHIFT; 327 328 /* Check that this MSEL setting is supported */ 329 if ((msel >= ARRAY_SIZE(cfgmgr_modes)) || !cfgmgr_modes[msel].valid) 330 return -EINVAL; 331 332 return msel; 333} 334 335static int socfpga_fpga_cfg_mode_set(struct socfpga_fpga_priv *priv) 336{ 337 u32 ctrl_reg; 338 int mode; 339 340 /* get value from MSEL pins */ 341 mode = socfpga_fpga_cfg_mode_get(priv); 342 if (mode < 0) 343 return mode; 344 345 /* Adjust CTRL for the CDRATIO */ 346 ctrl_reg = socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_CTL_OFST); 347 ctrl_reg &= ~SOCFPGA_FPGMGR_CTL_CDRATIO_MASK; 348 ctrl_reg &= ~SOCFPGA_FPGMGR_CTL_CFGWDTH_MASK; 349 ctrl_reg |= cfgmgr_modes[mode].ctrl; 350 351 /* Set NCE to 0. */ 352 ctrl_reg &= ~SOCFPGA_FPGMGR_CTL_NCE; 353 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_CTL_OFST, ctrl_reg); 354 355 return 0; 356} 357 358static int socfpga_fpga_reset(struct fpga_manager *mgr) 359{ 360 struct socfpga_fpga_priv *priv = mgr->priv; 361 u32 ctrl_reg, status; 362 int ret; 363 364 /* 365 * Step 1: 366 * - Set CTRL.CFGWDTH, CTRL.CDRATIO to match cfg mode 367 * - Set CTRL.NCE to 0 368 */ 369 ret = socfpga_fpga_cfg_mode_set(priv); 370 if (ret) 371 return ret; 372 373 /* Step 2: Set CTRL.EN to 1 */ 374 socfpga_fpga_set_bitsl(priv, SOCFPGA_FPGMGR_CTL_OFST, 375 SOCFPGA_FPGMGR_CTL_EN); 376 377 /* Step 3: Set CTRL.NCONFIGPULL to 1 to put FPGA in reset */ 378 ctrl_reg = socfpga_fpga_readl(priv, SOCFPGA_FPGMGR_CTL_OFST); 379 ctrl_reg |= SOCFPGA_FPGMGR_CTL_NCFGPULL; 380 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_CTL_OFST, ctrl_reg); 381 382 /* Step 4: Wait for STATUS.MODE to report FPGA is in reset phase */ 383 status = socfpga_fpga_wait_for_state(priv, SOCFPGA_FPGMGR_STAT_RESET); 384 385 /* Step 5: Set CONTROL.NCONFIGPULL to 0 to release FPGA from reset */ 386 ctrl_reg &= ~SOCFPGA_FPGMGR_CTL_NCFGPULL; 387 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_CTL_OFST, ctrl_reg); 388 389 /* Timeout waiting for reset */ 390 if (status) 391 return -ETIMEDOUT; 392 393 return 0; 394} 395 396/* 397 * Prepare the FPGA to receive the configuration data. 398 */ 399static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, 400 struct fpga_image_info *info, 401 const char *buf, size_t count) 402{ 403 struct socfpga_fpga_priv *priv = mgr->priv; 404 int ret; 405 406 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { 407 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); 408 return -EINVAL; 409 } 410 /* Steps 1 - 5: Reset the FPGA */ 411 ret = socfpga_fpga_reset(mgr); 412 if (ret) 413 return ret; 414 415 /* Step 6: Wait for FPGA to enter configuration phase */ 416 if (socfpga_fpga_wait_for_state(priv, SOCFPGA_FPGMGR_STAT_CFG)) 417 return -ETIMEDOUT; 418 419 /* Step 7: Clear nSTATUS interrupt */ 420 socfpga_fpga_writel(priv, SOCFPGA_FPGMGR_GPIO_PORTA_EOI_OFST, 421 SOCFPGA_FPGMGR_MON_NSTATUS); 422 423 /* Step 8: Set CTRL.AXICFGEN to 1 to enable transfer of config data */ 424 socfpga_fpga_set_bitsl(priv, SOCFPGA_FPGMGR_CTL_OFST, 425 SOCFPGA_FPGMGR_CTL_AXICFGEN); 426 427 return 0; 428} 429 430/* 431 * Step 9: write data to the FPGA data register 432 */ 433static int socfpga_fpga_ops_configure_write(struct fpga_manager *mgr, 434 const char *buf, size_t count) 435{ 436 struct socfpga_fpga_priv *priv = mgr->priv; 437 u32 *buffer_32 = (u32 *)buf; 438 size_t i = 0; 439 440 if (count <= 0) 441 return -EINVAL; 442 443 /* Write out the complete 32-bit chunks. */ 444 while (count >= sizeof(u32)) { 445 socfpga_fpga_data_writel(priv, buffer_32[i++]); 446 count -= sizeof(u32); 447 } 448 449 /* Write out remaining non 32-bit chunks. */ 450 switch (count) { 451 case 3: 452 socfpga_fpga_data_writel(priv, buffer_32[i++] & 0x00ffffff); 453 break; 454 case 2: 455 socfpga_fpga_data_writel(priv, buffer_32[i++] & 0x0000ffff); 456 break; 457 case 1: 458 socfpga_fpga_data_writel(priv, buffer_32[i++] & 0x000000ff); 459 break; 460 case 0: 461 break; 462 default: 463 /* This will never happen. */ 464 return -EFAULT; 465 } 466 467 return 0; 468} 469 470static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr, 471 struct fpga_image_info *info) 472{ 473 struct socfpga_fpga_priv *priv = mgr->priv; 474 u32 status; 475 476 /* 477 * Step 10: 478 * - Observe CONF_DONE and nSTATUS (active low) 479 * - if CONF_DONE = 1 and nSTATUS = 1, configuration was successful 480 * - if CONF_DONE = 0 and nSTATUS = 0, configuration failed 481 */ 482 status = socfpga_fpga_wait_for_config_done(priv); 483 if (status) 484 return status; 485 486 /* Step 11: Clear CTRL.AXICFGEN to disable transfer of config data */ 487 socfpga_fpga_clr_bitsl(priv, SOCFPGA_FPGMGR_CTL_OFST, 488 SOCFPGA_FPGMGR_CTL_AXICFGEN); 489 490 /* 491 * Step 12: 492 * - Write 4 to DCLKCNT 493 * - Wait for STATUS.DCNTDONE = 1 494 * - Clear W1C bit in STATUS.DCNTDONE 495 */ 496 if (socfpga_fpga_dclk_set_and_wait_clear(priv, 4)) 497 return -ETIMEDOUT; 498 499 /* Step 13: Wait for STATUS.MODE to report USER MODE */ 500 if (socfpga_fpga_wait_for_state(priv, SOCFPGA_FPGMGR_STAT_USER_MODE)) 501 return -ETIMEDOUT; 502 503 /* Step 14: Set CTRL.EN to 0 */ 504 socfpga_fpga_clr_bitsl(priv, SOCFPGA_FPGMGR_CTL_OFST, 505 SOCFPGA_FPGMGR_CTL_EN); 506 507 return 0; 508} 509 510/* Translate state register values to FPGA framework state */ 511static const enum fpga_mgr_states socfpga_state_to_framework_state[] = { 512 [SOCFPGA_FPGMGR_STAT_POWER_OFF] = FPGA_MGR_STATE_POWER_OFF, 513 [SOCFPGA_FPGMGR_STAT_RESET] = FPGA_MGR_STATE_RESET, 514 [SOCFPGA_FPGMGR_STAT_CFG] = FPGA_MGR_STATE_WRITE_INIT, 515 [SOCFPGA_FPGMGR_STAT_INIT] = FPGA_MGR_STATE_WRITE_INIT, 516 [SOCFPGA_FPGMGR_STAT_USER_MODE] = FPGA_MGR_STATE_OPERATING, 517 [SOCFPGA_FPGMGR_STAT_UNKNOWN] = FPGA_MGR_STATE_UNKNOWN, 518}; 519 520static enum fpga_mgr_states socfpga_fpga_ops_state(struct fpga_manager *mgr) 521{ 522 struct socfpga_fpga_priv *priv = mgr->priv; 523 enum fpga_mgr_states ret; 524 u32 state; 525 526 state = socfpga_fpga_state_get(priv); 527 528 if (state < ARRAY_SIZE(socfpga_state_to_framework_state)) 529 ret = socfpga_state_to_framework_state[state]; 530 else 531 ret = FPGA_MGR_STATE_UNKNOWN; 532 533 return ret; 534} 535 536static const struct fpga_manager_ops socfpga_fpga_ops = { 537 .state = socfpga_fpga_ops_state, 538 .write_init = socfpga_fpga_ops_configure_init, 539 .write = socfpga_fpga_ops_configure_write, 540 .write_complete = socfpga_fpga_ops_configure_complete, 541}; 542 543static int socfpga_fpga_probe(struct platform_device *pdev) 544{ 545 struct device *dev = &pdev->dev; 546 struct socfpga_fpga_priv *priv; 547 struct fpga_manager *mgr; 548 struct resource *res; 549 int ret; 550 551 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 552 if (!priv) 553 return -ENOMEM; 554 555 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 556 priv->fpga_base_addr = devm_ioremap_resource(dev, res); 557 if (IS_ERR(priv->fpga_base_addr)) 558 return PTR_ERR(priv->fpga_base_addr); 559 560 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 561 priv->fpga_data_addr = devm_ioremap_resource(dev, res); 562 if (IS_ERR(priv->fpga_data_addr)) 563 return PTR_ERR(priv->fpga_data_addr); 564 565 priv->irq = platform_get_irq(pdev, 0); 566 if (priv->irq < 0) 567 return priv->irq; 568 569 ret = devm_request_irq(dev, priv->irq, socfpga_fpga_isr, 0, 570 dev_name(dev), priv); 571 if (ret) 572 return ret; 573 574 mgr = devm_fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager", 575 &socfpga_fpga_ops, priv); 576 return PTR_ERR_OR_ZERO(mgr); 577} 578 579#ifdef CONFIG_OF 580static const struct of_device_id socfpga_fpga_of_match[] = { 581 { .compatible = "altr,socfpga-fpga-mgr", }, 582 {}, 583}; 584 585MODULE_DEVICE_TABLE(of, socfpga_fpga_of_match); 586#endif 587 588static struct platform_driver socfpga_fpga_driver = { 589 .probe = socfpga_fpga_probe, 590 .driver = { 591 .name = "socfpga_fpga_manager", 592 .of_match_table = of_match_ptr(socfpga_fpga_of_match), 593 }, 594}; 595 596module_platform_driver(socfpga_fpga_driver); 597 598MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 599MODULE_DESCRIPTION("Altera SOCFPGA FPGA Manager"); 600MODULE_LICENSE("GPL v2");