Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Common CPM code
0004  *
0005  * Author: Scott Wood <scottwood@freescale.com>
0006  *
0007  * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
0008  *
0009  * Some parts derived from commproc.c/cpm2_common.c, which is:
0010  * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
0011  * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
0012  * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
0013  * 2006 (c) MontaVista Software, Inc.
0014  * Vitaly Bordug <vbordug@ru.mvista.com>
0015  */
0016 
0017 #include <linux/init.h>
0018 #include <linux/of_device.h>
0019 #include <linux/spinlock.h>
0020 #include <linux/export.h>
0021 #include <linux/of.h>
0022 #include <linux/of_address.h>
0023 #include <linux/slab.h>
0024 
0025 #include <asm/udbg.h>
0026 #include <asm/io.h>
0027 #include <asm/cpm.h>
0028 #include <asm/fixmap.h>
0029 #include <soc/fsl/qe/qe.h>
0030 
0031 #include <mm/mmu_decl.h>
0032 
0033 #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
0034 #include <linux/of_gpio.h>
0035 #endif
0036 
0037 static int __init cpm_init(void)
0038 {
0039     struct device_node *np;
0040 
0041     np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
0042     if (!np)
0043         np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
0044     if (!np)
0045         return -ENODEV;
0046     cpm_muram_init();
0047     of_node_put(np);
0048     return 0;
0049 }
0050 subsys_initcall(cpm_init);
0051 
0052 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
0053 static u32 __iomem *cpm_udbg_txdesc;
0054 static u8 __iomem *cpm_udbg_txbuf;
0055 
0056 static void udbg_putc_cpm(char c)
0057 {
0058     if (c == '\n')
0059         udbg_putc_cpm('\r');
0060 
0061     while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
0062         ;
0063 
0064     out_8(cpm_udbg_txbuf, c);
0065     out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
0066 }
0067 
0068 void __init udbg_init_cpm(void)
0069 {
0070 #ifdef CONFIG_PPC_8xx
0071     mmu_mapin_immr();
0072 
0073     cpm_udbg_txdesc = (u32 __iomem __force *)
0074               (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
0075                VIRT_IMMR_BASE);
0076     cpm_udbg_txbuf = (u8 __iomem __force *)
0077              (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
0078               VIRT_IMMR_BASE);
0079 #else
0080     cpm_udbg_txdesc = (u32 __iomem __force *)
0081               CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
0082     cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
0083 #endif
0084 
0085     if (cpm_udbg_txdesc) {
0086 #ifdef CONFIG_CPM2
0087         setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
0088 #endif
0089         udbg_putc = udbg_putc_cpm;
0090     }
0091 }
0092 #endif
0093 
0094 #if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
0095 
0096 struct cpm2_ioports {
0097     u32 dir, par, sor, odr, dat;
0098     u32 res[3];
0099 };
0100 
0101 struct cpm2_gpio32_chip {
0102     struct of_mm_gpio_chip mm_gc;
0103     spinlock_t lock;
0104 
0105     /* shadowed data register to clear/set bits safely */
0106     u32 cpdata;
0107 };
0108 
0109 static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
0110 {
0111     struct cpm2_gpio32_chip *cpm2_gc =
0112         container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc);
0113     struct cpm2_ioports __iomem *iop = mm_gc->regs;
0114 
0115     cpm2_gc->cpdata = in_be32(&iop->dat);
0116 }
0117 
0118 static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
0119 {
0120     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0121     struct cpm2_ioports __iomem *iop = mm_gc->regs;
0122     u32 pin_mask;
0123 
0124     pin_mask = 1 << (31 - gpio);
0125 
0126     return !!(in_be32(&iop->dat) & pin_mask);
0127 }
0128 
0129 static void __cpm2_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
0130     int value)
0131 {
0132     struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(&mm_gc->gc);
0133     struct cpm2_ioports __iomem *iop = mm_gc->regs;
0134 
0135     if (value)
0136         cpm2_gc->cpdata |= pin_mask;
0137     else
0138         cpm2_gc->cpdata &= ~pin_mask;
0139 
0140     out_be32(&iop->dat, cpm2_gc->cpdata);
0141 }
0142 
0143 static void cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
0144 {
0145     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0146     struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
0147     unsigned long flags;
0148     u32 pin_mask = 1 << (31 - gpio);
0149 
0150     spin_lock_irqsave(&cpm2_gc->lock, flags);
0151 
0152     __cpm2_gpio32_set(mm_gc, pin_mask, value);
0153 
0154     spin_unlock_irqrestore(&cpm2_gc->lock, flags);
0155 }
0156 
0157 static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0158 {
0159     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0160     struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
0161     struct cpm2_ioports __iomem *iop = mm_gc->regs;
0162     unsigned long flags;
0163     u32 pin_mask = 1 << (31 - gpio);
0164 
0165     spin_lock_irqsave(&cpm2_gc->lock, flags);
0166 
0167     setbits32(&iop->dir, pin_mask);
0168     __cpm2_gpio32_set(mm_gc, pin_mask, val);
0169 
0170     spin_unlock_irqrestore(&cpm2_gc->lock, flags);
0171 
0172     return 0;
0173 }
0174 
0175 static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
0176 {
0177     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0178     struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
0179     struct cpm2_ioports __iomem *iop = mm_gc->regs;
0180     unsigned long flags;
0181     u32 pin_mask = 1 << (31 - gpio);
0182 
0183     spin_lock_irqsave(&cpm2_gc->lock, flags);
0184 
0185     clrbits32(&iop->dir, pin_mask);
0186 
0187     spin_unlock_irqrestore(&cpm2_gc->lock, flags);
0188 
0189     return 0;
0190 }
0191 
0192 int cpm2_gpiochip_add32(struct device *dev)
0193 {
0194     struct device_node *np = dev->of_node;
0195     struct cpm2_gpio32_chip *cpm2_gc;
0196     struct of_mm_gpio_chip *mm_gc;
0197     struct gpio_chip *gc;
0198 
0199     cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
0200     if (!cpm2_gc)
0201         return -ENOMEM;
0202 
0203     spin_lock_init(&cpm2_gc->lock);
0204 
0205     mm_gc = &cpm2_gc->mm_gc;
0206     gc = &mm_gc->gc;
0207 
0208     mm_gc->save_regs = cpm2_gpio32_save_regs;
0209     gc->ngpio = 32;
0210     gc->direction_input = cpm2_gpio32_dir_in;
0211     gc->direction_output = cpm2_gpio32_dir_out;
0212     gc->get = cpm2_gpio32_get;
0213     gc->set = cpm2_gpio32_set;
0214     gc->parent = dev;
0215     gc->owner = THIS_MODULE;
0216 
0217     return of_mm_gpiochip_add_data(np, mm_gc, cpm2_gc);
0218 }
0219 #endif /* CONFIG_CPM2 || CONFIG_8xx_GPIO */