Logo Search packages:      
Sourcecode: linux version File versions

mpp.c

/*
 * arch/arm/mach-orion5x/mpp.c
 *
 * MPP functions for Marvell Orion 5x SoCs
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include "common.h"
#include "mpp.h"

static int is_5181l(void)
{
      u32 dev;
      u32 rev;

      orion5x_pcie_id(&dev, &rev);

      return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0);
}

static int is_5182(void)
{
      u32 dev;
      u32 rev;

      orion5x_pcie_id(&dev, &rev);

      return !!(dev == MV88F5182_DEV_ID);
}

static int is_5281(void)
{
      u32 dev;
      u32 rev;

      orion5x_pcie_id(&dev, &rev);

      return !!(dev == MV88F5281_DEV_ID);
}

static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type)
{
      switch (type) {
      case MPP_UNUSED:
      case MPP_GPIO:
            if (mpp == 0)
                  return 3;
            if (mpp >= 1 && mpp <= 15)
                  return 0;
            if (mpp >= 16 && mpp <= 19) {
                  if (is_5182())
                        return 5;
                  if (type == MPP_UNUSED)
                        return 0;
            }
            return -1;

      case MPP_PCIE_RST_OUTn:
            if (mpp == 0)
                  return 0;
            return -1;

      case MPP_PCI_ARB:
            if (mpp >= 0 && mpp <= 7)
                  return 2;
            return -1;

      case MPP_PCI_PMEn:
            if (mpp == 2)
                  return 3;
            return -1;

      case MPP_GIGE:
            if (mpp >= 8 && mpp <= 19)
                  return 1;
            return -1;

      case MPP_NAND:
            if (is_5182() || is_5281()) {
                  if (mpp >= 4 && mpp <= 7)
                        return 4;
                  if (mpp >= 12 && mpp <= 17)
                        return 4;
            }
            return -1;

      case MPP_PCI_CLK:
            if (is_5181l() && mpp >= 6 && mpp <= 7)
                  return 5;
            return -1;

      case MPP_SATA_LED:
            if (is_5182()) {
                  if (mpp >= 4 && mpp <= 7)
                        return 5;
                  if (mpp >= 12 && mpp <= 15)
                        return 5;
            }
            return -1;

      case MPP_UART:
            if (mpp >= 16 && mpp <= 19)
                  return 0;
            return -1;
      }

      printk(KERN_INFO "unknown MPP type %d\n", type);

      return -1;
}

void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
{
      u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL);
      u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL);
      u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL);

      while (mode->mpp >= 0) {
            u32 *reg;
            int num_type;
            int shift;

            if (mode->mpp >= 0 && mode->mpp <= 7)
                  reg = &mpp_0_7_ctrl;
            else if (mode->mpp >= 8 && mode->mpp <= 15)
                  reg = &mpp_8_15_ctrl;
            else if (mode->mpp >= 16 && mode->mpp <= 19)
                  reg = &mpp_16_19_ctrl;
            else {
                  printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
                              "(%d)\n", mode->mpp);
                  continue;
            }

            num_type = determine_type_encoding(mode->mpp, mode->type);
            if (num_type < 0) {
                  printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
                              "combination (%d, %d)\n", mode->mpp,
                              mode->type);
                  continue;
            }

            shift = (mode->mpp & 7) << 2;
            *reg &= ~(0xf << shift);
            *reg |= (num_type & 0xf) << shift;

            orion5x_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO));

            mode++;
      }

      writel(mpp_0_7_ctrl, MPP_0_7_CTRL);
      writel(mpp_8_15_ctrl, MPP_8_15_CTRL);
      writel(mpp_16_19_ctrl, MPP_16_19_CTRL);
}

Generated by  Doxygen 1.6.0   Back to index