linux/arch/powerpc/sysdev/cpm_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Common CPM code
   4 *
   5 * Author: Scott Wood <scottwood@freescale.com>
   6 *
   7 * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
   8 *
   9 * Some parts derived from commproc.c/cpm2_common.c, which is:
  10 * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
  11 * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
  12 * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
  13 * 2006 (c) MontaVista Software, Inc.
  14 * Vitaly Bordug <vbordug@ru.mvista.com>
  15 */
  16
  17#include <linux/init.h>
  18#include <linux/of_device.h>
  19#include <linux/spinlock.h>
  20#include <linux/export.h>
  21#include <linux/of.h>
  22#include <linux/of_address.h>
  23#include <linux/slab.h>
  24
  25#include <asm/udbg.h>
  26#include <asm/io.h>
  27#include <asm/cpm.h>
  28#include <asm/fixmap.h>
  29#include <soc/fsl/qe/qe.h>
  30
  31#include <mm/mmu_decl.h>
  32
  33#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
  34#include <linux/of_gpio.h>
  35#endif
  36
  37static int __init cpm_init(void)
  38{
  39        struct device_node *np;
  40
  41        np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
  42        if (!np)
  43                np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
  44        if (!np)
  45                return -ENODEV;
  46        cpm_muram_init();
  47        of_node_put(np);
  48        return 0;
  49}
  50subsys_initcall(cpm_init);
  51
  52#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
  53static u32 __iomem *cpm_udbg_txdesc;
  54static u8 __iomem *cpm_udbg_txbuf;
  55
  56static void udbg_putc_cpm(char c)
  57{
  58        if (c == '\n')
  59                udbg_putc_cpm('\r');
  60
  61        while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
  62                ;
  63
  64        out_8(cpm_udbg_txbuf, c);
  65        out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
  66}
  67
  68void __init udbg_init_cpm(void)
  69{
  70#ifdef CONFIG_PPC_8xx
  71        cpm_udbg_txdesc = (u32 __iomem __force *)
  72                          (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
  73                           VIRT_IMMR_BASE);
  74        cpm_udbg_txbuf = (u8 __iomem __force *)
  75                         (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
  76                          VIRT_IMMR_BASE);
  77#else
  78        cpm_udbg_txdesc = (u32 __iomem __force *)
  79                          CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
  80        cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
  81#endif
  82
  83        if (cpm_udbg_txdesc) {
  84#ifdef CONFIG_CPM2
  85                setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
  86#endif
  87                udbg_putc = udbg_putc_cpm;
  88        }
  89}
  90#endif
  91
  92#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
  93
  94struct cpm2_ioports {
  95        u32 dir, par, sor, odr, dat;
  96        u32 res[3];
  97};
  98
  99struct cpm2_gpio32_chip {
 100        struct of_mm_gpio_chip mm_gc;
 101        spinlock_t lock;
 102
 103        /* shadowed data register to clear/set bits safely */
 104        u32 cpdata;
 105};
 106
 107static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
 108{
 109        struct cpm2_gpio32_chip *cpm2_gc =
 110                container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc);
 111        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 112
 113        cpm2_gc->cpdata = in_be32(&iop->dat);
 114}
 115
 116static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
 117{
 118        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 119        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 120        u32 pin_mask;
 121
 122        pin_mask = 1 << (31 - gpio);
 123
 124        return !!(in_be32(&iop->dat) & pin_mask);
 125}
 126
 127static void __cpm2_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
 128        int value)
 129{
 130        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(&mm_gc->gc);
 131        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 132
 133        if (value)
 134                cpm2_gc->cpdata |= pin_mask;
 135        else
 136                cpm2_gc->cpdata &= ~pin_mask;
 137
 138        out_be32(&iop->dat, cpm2_gc->cpdata);
 139}
 140
 141static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
 142{
 143        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 144        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 145        unsigned long flags;
 146        u32 pin_mask = 1 << (31 - gpio);
 147
 148        spin_lock_irqsave(&cpm2_gc->lock, flags);
 149
 150        __cpm2_gpio32_set(mm_gc, pin_mask, value);
 151
 152        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 153}
 154
 155static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 156{
 157        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 158        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 159        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 160        unsigned long flags;
 161        u32 pin_mask = 1 << (31 - gpio);
 162
 163        spin_lock_irqsave(&cpm2_gc->lock, flags);
 164
 165        setbits32(&iop->dir, pin_mask);
 166        __cpm2_gpio32_set(mm_gc, pin_mask, val);
 167
 168        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 169
 170        return 0;
 171}
 172
 173static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
 174{
 175        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 176        struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
 177        struct cpm2_ioports __iomem *iop = mm_gc->regs;
 178        unsigned long flags;
 179        u32 pin_mask = 1 << (31 - gpio);
 180
 181        spin_lock_irqsave(&cpm2_gc->lock, flags);
 182
 183        clrbits32(&iop->dir, pin_mask);
 184
 185        spin_unlock_irqrestore(&cpm2_gc->lock, flags);
 186
 187        return 0;
 188}
 189
 190int cpm2_gpiochip_add32(struct device *dev)
 191{
 192        struct device_node *np = dev->of_node;
 193        struct cpm2_gpio32_chip *cpm2_gc;
 194        struct of_mm_gpio_chip *mm_gc;
 195        struct gpio_chip *gc;
 196
 197        cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
 198        if (!cpm2_gc)
 199                return -ENOMEM;
 200
 201        spin_lock_init(&cpm2_gc->lock);
 202
 203        mm_gc = &cpm2_gc->mm_gc;
 204        gc = &mm_gc->gc;
 205
 206        mm_gc->save_regs = cpm2_gpio32_save_regs;
 207        gc->ngpio = 32;
 208        gc->direction_input = cpm2_gpio32_dir_in;
 209        gc->direction_output = cpm2_gpio32_dir_out;
 210        gc->get = cpm2_gpio32_get;
 211        gc->set = cpm2_gpio32_set;
 212        gc->parent = dev;
 213        gc->owner = THIS_MODULE;
 214
 215        return of_mm_gpiochip_add_data(np, mm_gc, cpm2_gc);
 216}
 217#endif /* CONFIG_CPM2 || CONFIG_8xx_GPIO */
 218