linux/drivers/fpga/socfpga.c
<<
>>
Prefs
   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_create(dev, "Altera SOCFPGA FPGA Manager",
 575                                   &socfpga_fpga_ops, priv);
 576        if (!mgr)
 577                return -ENOMEM;
 578
 579        return devm_fpga_mgr_register(dev, mgr);
 580}
 581
 582#ifdef CONFIG_OF
 583static const struct of_device_id socfpga_fpga_of_match[] = {
 584        { .compatible = "altr,socfpga-fpga-mgr", },
 585        {},
 586};
 587
 588MODULE_DEVICE_TABLE(of, socfpga_fpga_of_match);
 589#endif
 590
 591static struct platform_driver socfpga_fpga_driver = {
 592        .probe = socfpga_fpga_probe,
 593        .driver = {
 594                .name   = "socfpga_fpga_manager",
 595                .of_match_table = of_match_ptr(socfpga_fpga_of_match),
 596        },
 597};
 598
 599module_platform_driver(socfpga_fpga_driver);
 600
 601MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
 602MODULE_DESCRIPTION("Altera SOCFPGA FPGA Manager");
 603MODULE_LICENSE("GPL v2");
 604