Commit a9e3e12f authored by Olof Johansson's avatar Olof Johansson

Merge tag 'soc-fsl-next-v5.6' of...

Merge tag 'soc-fsl-next-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/drivers

NXP/FSL SoC driver updates for v5.6

QUICC Engine drivers
- Improve the QE drivers to be compatible with ARM/ARM64/PPC64
architectures
- Various cleanups to the QE drivers

* tag 'soc-fsl-next-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux: (49 commits)
  soc: fsl: qe: remove set but not used variable 'mm_gc'
  soc: fsl: qe: remove PPC32 dependency from CONFIG_QUICC_ENGINE
  soc: fsl: qe: remove unused #include of asm/irq.h from ucc.c
  net: ethernet: freescale: make UCC_GETH explicitly depend on PPC32
  net/wan/fsl_ucc_hdlc: reject muram offsets above 64K
  net/wan/fsl_ucc_hdlc: fix reading of __be16 registers
  net/wan/fsl_ucc_hdlc: avoid use of IS_ERR_VALUE()
  soc: fsl: qe: avoid IS_ERR_VALUE in ucc_fast.c
  soc: fsl: qe: drop pointless check in qe_sdma_init()
  soc: fsl: qe: drop use of IS_ERR_VALUE in qe_sdma_init()
  soc: fsl: qe: avoid IS_ERR_VALUE in ucc_slow.c
  soc: fsl: qe: refactor cpm_muram_alloc_common to prevent BUG on error path
  soc: fsl: qe: drop broken lazy call of cpm_muram_init()
  soc: fsl: qe: make cpm_muram_free() ignore a negative offset
  soc: fsl: qe: make cpm_muram_free() return void
  soc: fsl: qe: change return type of cpm_muram_alloc() to s32
  serial: ucc_uart: access __be32 field using be32_to_cpu
  serial: ucc_uart: limit brg-frequency workaround to PPC32
  serial: ucc_uart: use of_property_read_u32() in ucc_uart_probe()
  serial: ucc_uart: stub out soft_uart_init for !CONFIG_PPC32
  ...

Link: https://lore.kernel.org/r/1578608351-23289-1-git-send-email-leoyang.li@nxp.comSigned-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 0f827273 6e62bd36
/* SPDX-License-Identifier: GPL-2.0 */ #include <soc/fsl/cpm.h>
#ifndef __CPM_H
#define __CPM_H
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <soc/fsl/qe/qe.h>
/*
* SPI Parameter RAM common to QE and CPM.
*/
struct spi_pram {
__be16 rbase; /* Rx Buffer descriptor base address */
__be16 tbase; /* Tx Buffer descriptor base address */
u8 rfcr; /* Rx function code */
u8 tfcr; /* Tx function code */
__be16 mrblr; /* Max receive buffer length */
__be32 rstate; /* Internal */
__be32 rdp; /* Internal */
__be16 rbptr; /* Internal */
__be16 rbc; /* Internal */
__be32 rxtmp; /* Internal */
__be32 tstate; /* Internal */
__be32 tdp; /* Internal */
__be16 tbptr; /* Internal */
__be16 tbc; /* Internal */
__be32 txtmp; /* Internal */
__be32 res; /* Tx temp. */
__be16 rpbase; /* Relocation pointer (CPM1 only) */
__be16 res1; /* Reserved */
};
/*
* USB Controller pram common to QE and CPM.
*/
struct usb_ctlr {
u8 usb_usmod;
u8 usb_usadr;
u8 usb_uscom;
u8 res1[1];
__be16 usb_usep[4];
u8 res2[4];
__be16 usb_usber;
u8 res3[2];
__be16 usb_usbmr;
u8 res4[1];
u8 usb_usbs;
/* Fields down below are QE-only */
__be16 usb_ussft;
u8 res5[2];
__be16 usb_usfrn;
u8 res6[0x22];
} __attribute__ ((packed));
/*
* Function code bits, usually generic to devices.
*/
#ifdef CONFIG_CPM1
#define CPMFCR_GBL ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_TC2 ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_DTB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_BDB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#else
#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */
#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */
#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */
#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */
#endif
#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */
/* Opcodes common to CPM1 and CPM2
*/
#define CPM_CR_INIT_TRX ((ushort)0x0000)
#define CPM_CR_INIT_RX ((ushort)0x0001)
#define CPM_CR_INIT_TX ((ushort)0x0002)
#define CPM_CR_HUNT_MODE ((ushort)0x0003)
#define CPM_CR_STOP_TX ((ushort)0x0004)
#define CPM_CR_GRA_STOP_TX ((ushort)0x0005)
#define CPM_CR_RESTART_TX ((ushort)0x0006)
#define CPM_CR_CLOSE_RX_BD ((ushort)0x0007)
#define CPM_CR_SET_GADDR ((ushort)0x0008)
#define CPM_CR_SET_TIMER ((ushort)0x0008)
#define CPM_CR_STOP_IDMA ((ushort)0x000b)
/* Buffer descriptors used by many of the CPM protocols. */
typedef struct cpm_buf_desc {
ushort cbd_sc; /* Status and Control */
ushort cbd_datlen; /* Data length in buffer */
uint cbd_bufaddr; /* Buffer address in host memory */
} cbd_t;
/* Buffer descriptor control/status used by serial
*/
#define BD_SC_EMPTY (0x8000) /* Receive is empty */
#define BD_SC_READY (0x8000) /* Transmit is ready */
#define BD_SC_WRAP (0x2000) /* Last buffer descriptor */
#define BD_SC_INTRPT (0x1000) /* Interrupt on change */
#define BD_SC_LAST (0x0800) /* Last buffer in frame */
#define BD_SC_TC (0x0400) /* Transmit CRC */
#define BD_SC_CM (0x0200) /* Continuous mode */
#define BD_SC_ID (0x0100) /* Rec'd too many idles */
#define BD_SC_P (0x0100) /* xmt preamble */
#define BD_SC_BR (0x0020) /* Break received */
#define BD_SC_FR (0x0010) /* Framing error */
#define BD_SC_PR (0x0008) /* Parity error */
#define BD_SC_NAK (0x0004) /* NAK - did not respond */
#define BD_SC_OV (0x0002) /* Overrun */
#define BD_SC_UN (0x0002) /* Underrun */
#define BD_SC_CD (0x0001) /* */
#define BD_SC_CL (0x0001) /* Collision */
/* Buffer descriptor control/status used by Ethernet receive.
* Common to SCC and FCC.
*/
#define BD_ENET_RX_EMPTY (0x8000)
#define BD_ENET_RX_WRAP (0x2000)
#define BD_ENET_RX_INTR (0x1000)
#define BD_ENET_RX_LAST (0x0800)
#define BD_ENET_RX_FIRST (0x0400)
#define BD_ENET_RX_MISS (0x0100)
#define BD_ENET_RX_BC (0x0080) /* FCC Only */
#define BD_ENET_RX_MC (0x0040) /* FCC Only */
#define BD_ENET_RX_LG (0x0020)
#define BD_ENET_RX_NO (0x0010)
#define BD_ENET_RX_SH (0x0008)
#define BD_ENET_RX_CR (0x0004)
#define BD_ENET_RX_OV (0x0002)
#define BD_ENET_RX_CL (0x0001)
#define BD_ENET_RX_STATS (0x01ff) /* All status bits */
/* Buffer descriptor control/status used by Ethernet transmit.
* Common to SCC and FCC.
*/
#define BD_ENET_TX_READY (0x8000)
#define BD_ENET_TX_PAD (0x4000)
#define BD_ENET_TX_WRAP (0x2000)
#define BD_ENET_TX_INTR (0x1000)
#define BD_ENET_TX_LAST (0x0800)
#define BD_ENET_TX_TC (0x0400)
#define BD_ENET_TX_DEF (0x0200)
#define BD_ENET_TX_HB (0x0100)
#define BD_ENET_TX_LC (0x0080)
#define BD_ENET_TX_RL (0x0040)
#define BD_ENET_TX_RCMASK (0x003c)
#define BD_ENET_TX_UN (0x0002)
#define BD_ENET_TX_CSL (0x0001)
#define BD_ENET_TX_STATS (0x03ff) /* All status bits */
/* Buffer descriptor control/status used by Transparent mode SCC.
*/
#define BD_SCC_TX_LAST (0x0800)
/* Buffer descriptor control/status used by I2C.
*/
#define BD_I2C_START (0x0400)
#ifdef CONFIG_CPM
int cpm_command(u32 command, u8 opcode);
#else
static inline int cpm_command(u32 command, u8 opcode)
{
return -ENOSYS;
}
#endif /* CONFIG_CPM */
int cpm2_gpiochip_add32(struct device *dev);
#endif
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h" #include "mpc83xx.h"
...@@ -178,7 +177,7 @@ define_machine(mpc83xx_km) { ...@@ -178,7 +177,7 @@ define_machine(mpc83xx_km) {
.name = "mpc83xx-km-platform", .name = "mpc83xx-km-platform",
.probe = mpc83xx_km_probe, .probe = mpc83xx_km_probe,
.setup_arch = mpc83xx_km_setup_arch, .setup_arch = mpc83xx_km_setup_arch,
.init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .init_IRQ = mpc83xx_ipic_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .time_init = mpc83xx_time_init,
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/ipic.h> #include <asm/ipic.h>
#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
...@@ -91,28 +90,6 @@ void __init mpc83xx_ipic_init_IRQ(void) ...@@ -91,28 +90,6 @@ void __init mpc83xx_ipic_init_IRQ(void)
ipic_set_default_priority(); ipic_set_default_priority();
} }
#ifdef CONFIG_QUICC_ENGINE
void __init mpc83xx_qe_init_IRQ(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (!np) {
np = of_find_node_by_type(NULL, "qeic");
if (!np)
return;
}
qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
of_node_put(np);
}
void __init mpc83xx_ipic_and_qe_init_IRQ(void)
{
mpc83xx_ipic_init_IRQ();
mpc83xx_qe_init_IRQ();
}
#endif /* CONFIG_QUICC_ENGINE */
static const struct of_device_id of_bus_ids[] __initconst = { static const struct of_device_id of_bus_ids[] __initconst = {
{ .type = "soc", }, { .type = "soc", },
{ .compatible = "soc", }, { .compatible = "soc", },
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h" #include "mpc83xx.h"
...@@ -102,7 +101,7 @@ define_machine(mpc832x_mds) { ...@@ -102,7 +101,7 @@ define_machine(mpc832x_mds) {
.name = "MPC832x MDS", .name = "MPC832x MDS",
.probe = mpc832x_sys_probe, .probe = mpc832x_sys_probe,
.setup_arch = mpc832x_sys_setup_arch, .setup_arch = mpc832x_sys_setup_arch,
.init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .init_IRQ = mpc83xx_ipic_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .time_init = mpc83xx_time_init,
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <asm/ipic.h> #include <asm/ipic.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
...@@ -220,7 +219,7 @@ define_machine(mpc832x_rdb) { ...@@ -220,7 +219,7 @@ define_machine(mpc832x_rdb) {
.name = "MPC832x RDB", .name = "MPC832x RDB",
.probe = mpc832x_rdb_probe, .probe = mpc832x_rdb_probe,
.setup_arch = mpc832x_rdb_setup_arch, .setup_arch = mpc832x_rdb_setup_arch,
.init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .init_IRQ = mpc83xx_ipic_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .time_init = mpc83xx_time_init,
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h" #include "mpc83xx.h"
...@@ -202,7 +201,7 @@ define_machine(mpc836x_mds) { ...@@ -202,7 +201,7 @@ define_machine(mpc836x_mds) {
.name = "MPC836x MDS", .name = "MPC836x MDS",
.probe = mpc836x_mds_probe, .probe = mpc836x_mds_probe,
.setup_arch = mpc836x_mds_setup_arch, .setup_arch = mpc836x_mds_setup_arch,
.init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .init_IRQ = mpc83xx_ipic_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .time_init = mpc83xx_time_init,
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <asm/ipic.h> #include <asm/ipic.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
...@@ -42,7 +41,7 @@ define_machine(mpc836x_rdk) { ...@@ -42,7 +41,7 @@ define_machine(mpc836x_rdk) {
.name = "MPC836x RDK", .name = "MPC836x RDK",
.probe = mpc836x_rdk_probe, .probe = mpc836x_rdk_probe,
.setup_arch = mpc836x_rdk_setup_arch, .setup_arch = mpc836x_rdk_setup_arch,
.init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .init_IRQ = mpc83xx_ipic_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .time_init = mpc83xx_time_init,
......
...@@ -72,13 +72,6 @@ extern int mpc837x_usb_cfg(void); ...@@ -72,13 +72,6 @@ extern int mpc837x_usb_cfg(void);
extern int mpc834x_usb_cfg(void); extern int mpc834x_usb_cfg(void);
extern int mpc831x_usb_cfg(void); extern int mpc831x_usb_cfg(void);
extern void mpc83xx_ipic_init_IRQ(void); extern void mpc83xx_ipic_init_IRQ(void);
#ifdef CONFIG_QUICC_ENGINE
extern void mpc83xx_qe_init_IRQ(void);
extern void mpc83xx_ipic_and_qe_init_IRQ(void);
#else
static inline void __init mpc83xx_qe_init_IRQ(void) {}
#define mpc83xx_ipic_and_qe_init_IRQ mpc83xx_ipic_init_IRQ
#endif /* CONFIG_QUICC_ENGINE */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
extern void mpc83xx_setup_pci(void); extern void mpc83xx_setup_pci(void);
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/ehv_pic.h> #include <asm/ehv_pic.h>
#include <asm/swiotlb.h> #include <asm/swiotlb.h>
#include <soc/fsl/qe/qe_ic.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
...@@ -38,8 +37,6 @@ void __init corenet_gen_pic_init(void) ...@@ -38,8 +37,6 @@ void __init corenet_gen_pic_init(void)
unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
MPIC_NO_RESET; MPIC_NO_RESET;
struct device_node *np;
if (ppc_md.get_irq == mpic_get_coreint_irq) if (ppc_md.get_irq == mpic_get_coreint_irq)
flags |= MPIC_ENABLE_COREINT; flags |= MPIC_ENABLE_COREINT;
...@@ -47,13 +44,6 @@ void __init corenet_gen_pic_init(void) ...@@ -47,13 +44,6 @@ void __init corenet_gen_pic_init(void)
BUG_ON(mpic == NULL); BUG_ON(mpic == NULL);
mpic_init(mpic); mpic_init(mpic);
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (np) {
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
of_node_put(np);
}
} }
/* /*
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/swiotlb.h> #include <asm/swiotlb.h>
#include "smp.h" #include "smp.h"
...@@ -268,33 +267,8 @@ static void __init mpc85xx_mds_qe_init(void) ...@@ -268,33 +267,8 @@ static void __init mpc85xx_mds_qe_init(void)
} }
} }
static void __init mpc85xx_mds_qeic_init(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!of_device_is_available(np)) {
of_node_put(np);
return;
}
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (!np) {
np = of_find_node_by_type(NULL, "qeic");
if (!np)
return;
}
if (machine_is(p1021_mds))
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
else
qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
of_node_put(np);
}
#else #else
static void __init mpc85xx_mds_qe_init(void) { } static void __init mpc85xx_mds_qe_init(void) { }
static void __init mpc85xx_mds_qeic_init(void) { }
#endif /* CONFIG_QUICC_ENGINE */ #endif /* CONFIG_QUICC_ENGINE */
static void __init mpc85xx_mds_setup_arch(void) static void __init mpc85xx_mds_setup_arch(void)
...@@ -364,7 +338,6 @@ static void __init mpc85xx_mds_pic_init(void) ...@@ -364,7 +338,6 @@ static void __init mpc85xx_mds_pic_init(void)
BUG_ON(mpic == NULL); BUG_ON(mpic == NULL);
mpic_init(mpic); mpic_init(mpic);
mpc85xx_mds_qeic_init();
} }
static int __init mpc85xx_mds_probe(void) static int __init mpc85xx_mds_probe(void)
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
...@@ -44,10 +43,6 @@ void __init mpc85xx_rdb_pic_init(void) ...@@ -44,10 +43,6 @@ void __init mpc85xx_rdb_pic_init(void)
{ {
struct mpic *mpic; struct mpic *mpic;
#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
if (of_machine_is_compatible("fsl,MPC85XXRDB-CAMP")) { if (of_machine_is_compatible("fsl,MPC85XXRDB-CAMP")) {
mpic = mpic_alloc(NULL, 0, MPIC_NO_RESET | mpic = mpic_alloc(NULL, 0, MPIC_NO_RESET |
MPIC_BIG_ENDIAN | MPIC_BIG_ENDIAN |
...@@ -62,18 +57,6 @@ void __init mpc85xx_rdb_pic_init(void) ...@@ -62,18 +57,6 @@ void __init mpc85xx_rdb_pic_init(void)
BUG_ON(mpic == NULL); BUG_ON(mpic == NULL);
mpic_init(mpic); mpic_init(mpic);
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (np) {
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
of_node_put(np);
} else
pr_err("%s: Could not find qe-ic node\n", __func__);
#endif
} }
/* /*
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
...@@ -31,26 +30,12 @@ static void __init twr_p1025_pic_init(void) ...@@ -31,26 +30,12 @@ static void __init twr_p1025_pic_init(void)
{ {
struct mpic *mpic; struct mpic *mpic;
#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU, MPIC_SINGLE_DEST_CPU,
0, 256, " OpenPIC "); 0, 256, " OpenPIC ");
BUG_ON(mpic == NULL); BUG_ON(mpic == NULL);
mpic_init(mpic); mpic_init(mpic);
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (np) {
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
of_node_put(np);
} else
pr_err("Could not find qe-ic node\n");
#endif
} }
/* ************************************************************************ /* ************************************************************************
......
...@@ -74,7 +74,7 @@ config FSL_XGMAC_MDIO ...@@ -74,7 +74,7 @@ config FSL_XGMAC_MDIO
config UCC_GETH config UCC_GETH
tristate "Freescale QE Gigabit Ethernet" tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE depends on QUICC_ENGINE && PPC32
select FSL_PQ_MDIO select FSL_PQ_MDIO
select PHYLIB select PHYLIB
---help--- ---help---
......
...@@ -84,8 +84,8 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) ...@@ -84,8 +84,8 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
int ret, i; int ret, i;
void *bd_buffer; void *bd_buffer;
dma_addr_t bd_dma_addr; dma_addr_t bd_dma_addr;
u32 riptr; s32 riptr;
u32 tiptr; s32 tiptr;
u32 gumr; u32 gumr;
ut_info = priv->ut_info; ut_info = priv->ut_info;
...@@ -195,7 +195,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) ...@@ -195,7 +195,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
priv->ucc_pram_offset = qe_muram_alloc(sizeof(struct ucc_hdlc_param), priv->ucc_pram_offset = qe_muram_alloc(sizeof(struct ucc_hdlc_param),
ALIGNMENT_OF_UCC_HDLC_PRAM); ALIGNMENT_OF_UCC_HDLC_PRAM);
if (IS_ERR_VALUE(priv->ucc_pram_offset)) { if (priv->ucc_pram_offset < 0) {
dev_err(priv->dev, "Can not allocate MURAM for hdlc parameter.\n"); dev_err(priv->dev, "Can not allocate MURAM for hdlc parameter.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_tx_bd; goto free_tx_bd;
...@@ -233,18 +233,23 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) ...@@ -233,18 +233,23 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
/* Alloc riptr, tiptr */ /* Alloc riptr, tiptr */
riptr = qe_muram_alloc(32, 32); riptr = qe_muram_alloc(32, 32);
if (IS_ERR_VALUE(riptr)) { if (riptr < 0) {
dev_err(priv->dev, "Cannot allocate MURAM mem for Receive internal temp data pointer\n"); dev_err(priv->dev, "Cannot allocate MURAM mem for Receive internal temp data pointer\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_tx_skbuff; goto free_tx_skbuff;
} }
tiptr = qe_muram_alloc(32, 32); tiptr = qe_muram_alloc(32, 32);
if (IS_ERR_VALUE(tiptr)) { if (tiptr < 0) {
dev_err(priv->dev, "Cannot allocate MURAM mem for Transmit internal temp data pointer\n"); dev_err(priv->dev, "Cannot allocate MURAM mem for Transmit internal temp data pointer\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_riptr; goto free_riptr;
} }
if (riptr != (u16)riptr || tiptr != (u16)tiptr) {
dev_err(priv->dev, "MURAM allocation out of addressable range\n");
ret = -ENOMEM;
goto free_tiptr;
}
/* Set RIPTR, TIPTR */ /* Set RIPTR, TIPTR */
iowrite16be(riptr, &priv->ucc_pram->riptr); iowrite16be(riptr, &priv->ucc_pram->riptr);
...@@ -623,8 +628,8 @@ static int ucc_hdlc_poll(struct napi_struct *napi, int budget) ...@@ -623,8 +628,8 @@ static int ucc_hdlc_poll(struct napi_struct *napi, int budget)
if (howmany < budget) { if (howmany < budget) {
napi_complete_done(napi, howmany); napi_complete_done(napi, howmany);
qe_setbits32(priv->uccf->p_uccm, qe_setbits_be32(priv->uccf->p_uccm,
(UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS) << 16); (UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS) << 16);
} }
return howmany; return howmany;
...@@ -732,8 +737,8 @@ static int uhdlc_open(struct net_device *dev) ...@@ -732,8 +737,8 @@ static int uhdlc_open(struct net_device *dev)
static void uhdlc_memclean(struct ucc_hdlc_private *priv) static void uhdlc_memclean(struct ucc_hdlc_private *priv)
{ {
qe_muram_free(priv->ucc_pram->riptr); qe_muram_free(ioread16be(&priv->ucc_pram->riptr));
qe_muram_free(priv->ucc_pram->tiptr); qe_muram_free(ioread16be(&priv->ucc_pram->tiptr));
if (priv->rx_bd_base) { if (priv->rx_bd_base) {
dma_free_coherent(priv->dev, dma_free_coherent(priv->dev,
......
...@@ -98,7 +98,7 @@ struct ucc_hdlc_private { ...@@ -98,7 +98,7 @@ struct ucc_hdlc_private {
unsigned short tx_ring_size; unsigned short tx_ring_size;
unsigned short rx_ring_size; unsigned short rx_ring_size;
u32 ucc_pram_offset; s32 ucc_pram_offset;
unsigned short encoding; unsigned short encoding;
unsigned short parity; unsigned short parity;
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
config QUICC_ENGINE config QUICC_ENGINE
bool "QUICC Engine (QE) framework support" bool "QUICC Engine (QE) framework support"
depends on FSL_SOC && PPC32 depends on OF && HAS_IOMEM
depends on PPC || ARM || ARM64 || COMPILE_TEST
select GENERIC_ALLOCATOR select GENERIC_ALLOCATOR
select CRC32 select CRC32
help help
......
...@@ -41,13 +41,13 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) ...@@ -41,13 +41,13 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
container_of(mm_gc, struct qe_gpio_chip, mm_gc); container_of(mm_gc, struct qe_gpio_chip, mm_gc);
struct qe_pio_regs __iomem *regs = mm_gc->regs; struct qe_pio_regs __iomem *regs = mm_gc->regs;
qe_gc->cpdata = in_be32(&regs->cpdata); qe_gc->cpdata = qe_ioread32be(&regs->cpdata);
qe_gc->saved_regs.cpdata = qe_gc->cpdata; qe_gc->saved_regs.cpdata = qe_gc->cpdata;
qe_gc->saved_regs.cpdir1 = in_be32(&regs->cpdir1); qe_gc->saved_regs.cpdir1 = qe_ioread32be(&regs->cpdir1);
qe_gc->saved_regs.cpdir2 = in_be32(&regs->cpdir2); qe_gc->saved_regs.cpdir2 = qe_ioread32be(&regs->cpdir2);
qe_gc->saved_regs.cppar1 = in_be32(&regs->cppar1); qe_gc->saved_regs.cppar1 = qe_ioread32be(&regs->cppar1);
qe_gc->saved_regs.cppar2 = in_be32(&regs->cppar2); qe_gc->saved_regs.cppar2 = qe_ioread32be(&regs->cppar2);
qe_gc->saved_regs.cpodr = in_be32(&regs->cpodr); qe_gc->saved_regs.cpodr = qe_ioread32be(&regs->cpodr);
} }
static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
...@@ -56,7 +56,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) ...@@ -56,7 +56,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
struct qe_pio_regs __iomem *regs = mm_gc->regs; struct qe_pio_regs __iomem *regs = mm_gc->regs;
u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
return !!(in_be32(&regs->cpdata) & pin_mask); return !!(qe_ioread32be(&regs->cpdata) & pin_mask);
} }
static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
...@@ -74,7 +74,7 @@ static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) ...@@ -74,7 +74,7 @@ static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
else else
qe_gc->cpdata &= ~pin_mask; qe_gc->cpdata &= ~pin_mask;
out_be32(&regs->cpdata, qe_gc->cpdata); qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
spin_unlock_irqrestore(&qe_gc->lock, flags); spin_unlock_irqrestore(&qe_gc->lock, flags);
} }
...@@ -101,7 +101,7 @@ static void qe_gpio_set_multiple(struct gpio_chip *gc, ...@@ -101,7 +101,7 @@ static void qe_gpio_set_multiple(struct gpio_chip *gc,
} }
} }
out_be32(&regs->cpdata, qe_gc->cpdata); qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
spin_unlock_irqrestore(&qe_gc->lock, flags); spin_unlock_irqrestore(&qe_gc->lock, flags);
} }
...@@ -160,7 +160,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) ...@@ -160,7 +160,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
{ {
struct qe_pin *qe_pin; struct qe_pin *qe_pin;
struct gpio_chip *gc; struct gpio_chip *gc;
struct of_mm_gpio_chip *mm_gc;
struct qe_gpio_chip *qe_gc; struct qe_gpio_chip *qe_gc;
int err; int err;
unsigned long flags; unsigned long flags;
...@@ -186,7 +185,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) ...@@ -186,7 +185,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
goto err0; goto err0;
} }
mm_gc = to_of_mm_gpio_chip(gc);
qe_gc = gpiochip_get_data(gc); qe_gc = gpiochip_get_data(gc);
spin_lock_irqsave(&qe_gc->lock, flags); spin_lock_irqsave(&qe_gc->lock, flags);
...@@ -255,11 +253,15 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin) ...@@ -255,11 +253,15 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
spin_lock_irqsave(&qe_gc->lock, flags); spin_lock_irqsave(&qe_gc->lock, flags);
if (second_reg) { if (second_reg) {
clrsetbits_be32(&regs->cpdir2, mask2, sregs->cpdir2 & mask2); qe_clrsetbits_be32(&regs->cpdir2, mask2,
clrsetbits_be32(&regs->cppar2, mask2, sregs->cppar2 & mask2); sregs->cpdir2 & mask2);
qe_clrsetbits_be32(&regs->cppar2, mask2,
sregs->cppar2 & mask2);
} else { } else {
clrsetbits_be32(&regs->cpdir1, mask2, sregs->cpdir1 & mask2); qe_clrsetbits_be32(&regs->cpdir1, mask2,
clrsetbits_be32(&regs->cppar1, mask2, sregs->cppar1 & mask2); sregs->cpdir1 & mask2);
qe_clrsetbits_be32(&regs->cppar1, mask2,
sregs->cppar1 & mask2);
} }
if (sregs->cpdata & mask1) if (sregs->cpdata & mask1)
...@@ -267,8 +269,8 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin) ...@@ -267,8 +269,8 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
else else
qe_gc->cpdata &= ~mask1; qe_gc->cpdata &= ~mask1;
out_be32(&regs->cpdata, qe_gc->cpdata); qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1); qe_clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);
spin_unlock_irqrestore(&qe_gc->lock, flags); spin_unlock_irqrestore(&qe_gc->lock, flags);
} }
......
...@@ -22,16 +22,12 @@ ...@@ -22,16 +22,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/iopoll.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <asm/irq.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/immap_qe.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <asm/prom.h>
#include <asm/rheap.h>
static void qe_snums_init(void); static void qe_snums_init(void);
static int qe_sdma_init(void); static int qe_sdma_init(void);
...@@ -108,11 +104,12 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) ...@@ -108,11 +104,12 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
{ {
unsigned long flags; unsigned long flags;
u8 mcn_shift = 0, dev_shift = 0; u8 mcn_shift = 0, dev_shift = 0;
u32 ret; u32 val;
int ret;
spin_lock_irqsave(&qe_lock, flags); spin_lock_irqsave(&qe_lock, flags);
if (cmd == QE_RESET) { if (cmd == QE_RESET) {
out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG)); qe_iowrite32be((u32)(cmd | QE_CR_FLG), &qe_immr->cp.cecr);
} else { } else {
if (cmd == QE_ASSIGN_PAGE) { if (cmd == QE_ASSIGN_PAGE) {
/* Here device is the SNUM, not sub-block */ /* Here device is the SNUM, not sub-block */
...@@ -129,20 +126,18 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) ...@@ -129,20 +126,18 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
mcn_shift = QE_CR_MCN_NORMAL_SHIFT; mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
} }
out_be32(&qe_immr->cp.cecdr, cmd_input); qe_iowrite32be(cmd_input, &qe_immr->cp.cecdr);
out_be32(&qe_immr->cp.cecr, qe_iowrite32be((cmd | QE_CR_FLG | ((u32)device << dev_shift) | (u32)mcn_protocol << mcn_shift),
(cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) &qe_immr->cp.cecr);
mcn_protocol << mcn_shift));
} }
/* wait for the QE_CR_FLG to clear */ /* wait for the QE_CR_FLG to clear */
ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, ret = readx_poll_timeout_atomic(qe_ioread32be, &qe_immr->cp.cecr, val,
100, 0); (val & QE_CR_FLG) == 0, 0, 100);
/* On timeout (e.g. failure), the expression will be false (ret == 0), /* On timeout, ret is -ETIMEDOUT, otherwise it will be 0. */
otherwise it will be true (ret == 1). */
spin_unlock_irqrestore(&qe_lock, flags); spin_unlock_irqrestore(&qe_lock, flags);
return ret == 1; return ret == 0;
} }
EXPORT_SYMBOL(qe_issue_cmd); EXPORT_SYMBOL(qe_issue_cmd);
...@@ -164,8 +159,7 @@ static unsigned int brg_clk = 0; ...@@ -164,8 +159,7 @@ static unsigned int brg_clk = 0;
unsigned int qe_get_brg_clk(void) unsigned int qe_get_brg_clk(void)
{ {
struct device_node *qe; struct device_node *qe;
int size; u32 brg;
const u32 *prop;
unsigned int mod; unsigned int mod;
if (brg_clk) if (brg_clk)
...@@ -175,9 +169,8 @@ unsigned int qe_get_brg_clk(void) ...@@ -175,9 +169,8 @@ unsigned int qe_get_brg_clk(void)
if (!qe) if (!qe)
return brg_clk; return brg_clk;
prop = of_get_property(qe, "brg-frequency", &size); if (!of_property_read_u32(qe, "brg-frequency", &brg))
if (prop && size == sizeof(*prop)) brg_clk = brg;
brg_clk = *prop;
of_node_put(qe); of_node_put(qe);
...@@ -197,6 +190,14 @@ EXPORT_SYMBOL(qe_get_brg_clk); ...@@ -197,6 +190,14 @@ EXPORT_SYMBOL(qe_get_brg_clk);
#define PVR_VER_836x 0x8083 #define PVR_VER_836x 0x8083
#define PVR_VER_832x 0x8084 #define PVR_VER_832x 0x8084
static bool qe_general4_errata(void)
{
#ifdef CONFIG_PPC32
return pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x);
#endif
return false;
}
/* Program the BRG to the given sampling rate and multiplier /* Program the BRG to the given sampling rate and multiplier
* *
* @brg: the BRG, QE_BRG1 - QE_BRG16 * @brg: the BRG, QE_BRG1 - QE_BRG16
...@@ -223,14 +224,14 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) ...@@ -223,14 +224,14 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
that the BRG divisor must be even if you're not using divide-by-16 that the BRG divisor must be even if you're not using divide-by-16
mode. */ mode. */
if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x)) if (qe_general4_errata())
if (!div16 && (divisor & 1) && (divisor > 3)) if (!div16 && (divisor & 1) && (divisor > 3))
divisor++; divisor++;
tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
QE_BRGC_ENABLE | div16; QE_BRGC_ENABLE | div16;
out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval); qe_iowrite32be(tempval, &qe_immr->brg.brgc[brg - QE_BRG1]);
return 0; return 0;
} }
...@@ -364,22 +365,20 @@ EXPORT_SYMBOL(qe_put_snum); ...@@ -364,22 +365,20 @@ EXPORT_SYMBOL(qe_put_snum);
static int qe_sdma_init(void) static int qe_sdma_init(void)
{ {
struct sdma __iomem *sdma = &qe_immr->sdma; struct sdma __iomem *sdma = &qe_immr->sdma;
static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM; static s32 sdma_buf_offset = -ENOMEM;
if (!sdma)
return -ENODEV;
/* allocate 2 internal temporary buffers (512 bytes size each) for /* allocate 2 internal temporary buffers (512 bytes size each) for
* the SDMA */ * the SDMA */
if (IS_ERR_VALUE(sdma_buf_offset)) { if (sdma_buf_offset < 0) {
sdma_buf_offset = qe_muram_alloc(512 * 2, 4096); sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
if (IS_ERR_VALUE(sdma_buf_offset)) if (sdma_buf_offset < 0)
return -ENOMEM; return -ENOMEM;
} }
out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK); qe_iowrite32be((u32)sdma_buf_offset & QE_SDEBCR_BA_MASK,
out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | &sdma->sdebcr);
(0x1 << QE_SDMR_CEN_SHIFT))); qe_iowrite32be((QE_SDMR_GLB_1_MSK | (0x1 << QE_SDMR_CEN_SHIFT)),
&sdma->sdmr);
return 0; return 0;
} }
...@@ -417,14 +416,14 @@ static void qe_upload_microcode(const void *base, ...@@ -417,14 +416,14 @@ static void qe_upload_microcode(const void *base,
"uploading microcode '%s'\n", ucode->id); "uploading microcode '%s'\n", ucode->id);
/* Use auto-increment */ /* Use auto-increment */
out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | qe_iowrite32be(be32_to_cpu(ucode->iram_offset) | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR,
QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); &qe_immr->iram.iadd);
for (i = 0; i < be32_to_cpu(ucode->count); i++) for (i = 0; i < be32_to_cpu(ucode->count); i++)
out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
/* Set I-RAM Ready Register */ /* Set I-RAM Ready Register */
out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY)); qe_iowrite32be(be32_to_cpu(QE_IRAM_READY), &qe_immr->iram.iready);
} }
/* /*
...@@ -509,7 +508,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) ...@@ -509,7 +508,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
* If the microcode calls for it, split the I-RAM. * If the microcode calls for it, split the I-RAM.
*/ */
if (!firmware->split) if (!firmware->split)
setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); qe_setbits_be16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
if (firmware->soc.model) if (firmware->soc.model)
printk(KERN_INFO printk(KERN_INFO
...@@ -543,11 +542,13 @@ int qe_upload_firmware(const struct qe_firmware *firmware) ...@@ -543,11 +542,13 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
u32 trap = be32_to_cpu(ucode->traps[j]); u32 trap = be32_to_cpu(ucode->traps[j]);
if (trap) if (trap)
out_be32(&qe_immr->rsp[i].tibcr[j], trap); qe_iowrite32be(trap,
&qe_immr->rsp[i].tibcr[j]);
} }
/* Enable traps */ /* Enable traps */
out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); qe_iowrite32be(be32_to_cpu(ucode->eccr),
&qe_immr->rsp[i].eccr);
} }
qe_firmware_uploaded = 1; qe_firmware_uploaded = 1;
...@@ -565,11 +566,9 @@ EXPORT_SYMBOL(qe_upload_firmware); ...@@ -565,11 +566,9 @@ EXPORT_SYMBOL(qe_upload_firmware);
struct qe_firmware_info *qe_get_firmware_info(void) struct qe_firmware_info *qe_get_firmware_info(void)
{ {
static int initialized; static int initialized;
struct property *prop;
struct device_node *qe; struct device_node *qe;
struct device_node *fw = NULL; struct device_node *fw = NULL;
const char *sprop; const char *sprop;
unsigned int i;
/* /*
* If we haven't checked yet, and a driver hasn't uploaded a firmware * If we haven't checked yet, and a driver hasn't uploaded a firmware
...@@ -603,20 +602,11 @@ struct qe_firmware_info *qe_get_firmware_info(void) ...@@ -603,20 +602,11 @@ struct qe_firmware_info *qe_get_firmware_info(void)
strlcpy(qe_firmware_info.id, sprop, strlcpy(qe_firmware_info.id, sprop,
sizeof(qe_firmware_info.id)); sizeof(qe_firmware_info.id));
prop = of_find_property(fw, "extended-modes", NULL); of_property_read_u64(fw, "extended-modes",
if (prop && (prop->length == sizeof(u64))) { &qe_firmware_info.extended_modes);
const u64 *iprop = prop->value;
qe_firmware_info.extended_modes = *iprop;
}
prop = of_find_property(fw, "virtual-traps", NULL); of_property_read_u32_array(fw, "virtual-traps", qe_firmware_info.vtraps,
if (prop && (prop->length == 32)) { ARRAY_SIZE(qe_firmware_info.vtraps));
const u32 *iprop = prop->value;
for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
qe_firmware_info.vtraps[i] = iprop[i];
}
of_node_put(fw); of_node_put(fw);
...@@ -627,17 +617,13 @@ EXPORT_SYMBOL(qe_get_firmware_info); ...@@ -627,17 +617,13 @@ EXPORT_SYMBOL(qe_get_firmware_info);
unsigned int qe_get_num_of_risc(void) unsigned int qe_get_num_of_risc(void)
{ {
struct device_node *qe; struct device_node *qe;
int size;
unsigned int num_of_risc = 0; unsigned int num_of_risc = 0;
const u32 *prop;
qe = qe_get_device_node(); qe = qe_get_device_node();
if (!qe) if (!qe)
return num_of_risc; return num_of_risc;
prop = of_get_property(qe, "fsl,qe-num-riscs", &size); of_property_read_u32(qe, "fsl,qe-num-riscs", &num_of_risc);
if (prop && size == sizeof(*prop))
num_of_risc = *prop;
of_node_put(qe); of_node_put(qe);
......
...@@ -32,7 +32,7 @@ static phys_addr_t muram_pbase; ...@@ -32,7 +32,7 @@ static phys_addr_t muram_pbase;
struct muram_block { struct muram_block {
struct list_head head; struct list_head head;
unsigned long start; s32 start;
int size; int size;
}; };
...@@ -110,34 +110,30 @@ int cpm_muram_init(void) ...@@ -110,34 +110,30 @@ int cpm_muram_init(void)
* @algo: algorithm for alloc. * @algo: algorithm for alloc.
* @data: data for genalloc's algorithm. * @data: data for genalloc's algorithm.
* *
* This function returns an offset into the muram area. * This function returns a non-negative offset into the muram area, or
* a negative errno on failure.
*/ */
static unsigned long cpm_muram_alloc_common(unsigned long size, static s32 cpm_muram_alloc_common(unsigned long size,
genpool_algo_t algo, void *data) genpool_algo_t algo, void *data)
{ {
struct muram_block *entry; struct muram_block *entry;
unsigned long start; s32 start;
if (!muram_pool && cpm_muram_init())
goto out2;
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return -ENOMEM;
start = gen_pool_alloc_algo(muram_pool, size, algo, data); start = gen_pool_alloc_algo(muram_pool, size, algo, data);
if (!start) if (!start) {
goto out2; kfree(entry);
return -ENOMEM;
}
start = start - GENPOOL_OFFSET; start = start - GENPOOL_OFFSET;
memset_io(cpm_muram_addr(start), 0, size); memset_io(cpm_muram_addr(start), 0, size);
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
goto out1;
entry->start = start; entry->start = start;
entry->size = size; entry->size = size;
list_add(&entry->head, &muram_block_list); list_add(&entry->head, &muram_block_list);
return start; return start;
out1:
gen_pool_free(muram_pool, start, size);
out2:
return (unsigned long)-ENOMEM;
} }
/* /*
...@@ -145,13 +141,14 @@ static unsigned long cpm_muram_alloc_common(unsigned long size, ...@@ -145,13 +141,14 @@ static unsigned long cpm_muram_alloc_common(unsigned long size,
* @size: number of bytes to allocate * @size: number of bytes to allocate
* @align: requested alignment, in bytes * @align: requested alignment, in bytes
* *
* This function returns an offset into the muram area. * This function returns a non-negative offset into the muram area, or
* a negative errno on failure.
* Use cpm_dpram_addr() to get the virtual address of the area. * Use cpm_dpram_addr() to get the virtual address of the area.
* Use cpm_muram_free() to free the allocation. * Use cpm_muram_free() to free the allocation.
*/ */
unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) s32 cpm_muram_alloc(unsigned long size, unsigned long align)
{ {
unsigned long start; s32 start;
unsigned long flags; unsigned long flags;
struct genpool_data_align muram_pool_data; struct genpool_data_align muram_pool_data;
...@@ -168,12 +165,15 @@ EXPORT_SYMBOL(cpm_muram_alloc); ...@@ -168,12 +165,15 @@ EXPORT_SYMBOL(cpm_muram_alloc);
* cpm_muram_free - free a chunk of multi-user ram * cpm_muram_free - free a chunk of multi-user ram
* @offset: The beginning of the chunk as returned by cpm_muram_alloc(). * @offset: The beginning of the chunk as returned by cpm_muram_alloc().
*/ */
int cpm_muram_free(unsigned long offset) void cpm_muram_free(s32 offset)
{ {
unsigned long flags; unsigned long flags;
int size; int size;
struct muram_block *tmp; struct muram_block *tmp;
if (offset < 0)
return;
size = 0; size = 0;
spin_lock_irqsave(&cpm_muram_lock, flags); spin_lock_irqsave(&cpm_muram_lock, flags);
list_for_each_entry(tmp, &muram_block_list, head) { list_for_each_entry(tmp, &muram_block_list, head) {
...@@ -186,7 +186,6 @@ int cpm_muram_free(unsigned long offset) ...@@ -186,7 +186,6 @@ int cpm_muram_free(unsigned long offset)
} }
gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size); gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size);
spin_unlock_irqrestore(&cpm_muram_lock, flags); spin_unlock_irqrestore(&cpm_muram_lock, flags);
return size;
} }
EXPORT_SYMBOL(cpm_muram_free); EXPORT_SYMBOL(cpm_muram_free);
...@@ -194,13 +193,14 @@ EXPORT_SYMBOL(cpm_muram_free); ...@@ -194,13 +193,14 @@ EXPORT_SYMBOL(cpm_muram_free);
* cpm_muram_alloc_fixed - reserve a specific region of multi-user ram * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram
* @offset: offset of allocation start address * @offset: offset of allocation start address
* @size: number of bytes to allocate * @size: number of bytes to allocate
* This function returns an offset into the muram area * This function returns @offset if the area was available, a negative
* errno otherwise.
* Use cpm_dpram_addr() to get the virtual address of the area. * Use cpm_dpram_addr() to get the virtual address of the area.
* Use cpm_muram_free() to free the allocation. * Use cpm_muram_free() to free the allocation.
*/ */
unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) s32 cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
{ {
unsigned long start; s32 start;
unsigned long flags; unsigned long flags;
struct genpool_data_fixed muram_pool_data_fixed; struct genpool_data_fixed muram_pool_data_fixed;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/irq.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/stddef.h> #include <linux/stddef.h>
...@@ -24,9 +25,57 @@ ...@@ -24,9 +25,57 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <soc/fsl/qe/qe_ic.h> #include <soc/fsl/qe/qe.h>
#define NR_QE_IC_INTS 64
/* QE IC registers offset */
#define QEIC_CICR 0x00
#define QEIC_CIVEC 0x04
#define QEIC_CIPXCC 0x10
#define QEIC_CIPYCC 0x14
#define QEIC_CIPWCC 0x18
#define QEIC_CIPZCC 0x1c
#define QEIC_CIMR 0x20
#define QEIC_CRIMR 0x24
#define QEIC_CIPRTA 0x30
#define QEIC_CIPRTB 0x34
#define QEIC_CHIVEC 0x60
struct qe_ic {
/* Control registers offset */
u32 __iomem *regs;
/* The remapper for this QEIC */
struct irq_domain *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
/* VIRQ numbers of QE high/low irqs */
unsigned int virq_high;
unsigned int virq_low;
};
#include "qe_ic.h" /*
* QE interrupt controller internal structure
*/
struct qe_ic_info {
/* Location of this source at the QIMR register */
u32 mask;
/* Mask register offset */
u32 mask_reg;
/*
* For grouped interrupts sources - the interrupt code as
* appears at the group priority register
*/
u8 pri_code;
/* Group priority register offset */
u32 pri_reg;
};
static DEFINE_RAW_SPINLOCK(qe_ic_lock); static DEFINE_RAW_SPINLOCK(qe_ic_lock);
...@@ -171,15 +220,15 @@ static struct qe_ic_info qe_ic_info[] = { ...@@ -171,15 +220,15 @@ static struct qe_ic_info qe_ic_info[] = {
}, },
}; };
static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg) static inline u32 qe_ic_read(__be32 __iomem *base, unsigned int reg)
{ {
return in_be32(base + (reg >> 2)); return qe_ioread32be(base + (reg >> 2));
} }
static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg, static inline void qe_ic_write(__be32 __iomem *base, unsigned int reg,
u32 value) u32 value)
{ {
out_be32(base + (reg >> 2), value); qe_iowrite32be(value, base + (reg >> 2));
} }
static inline struct qe_ic *qe_ic_from_irq(unsigned int virq) static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
...@@ -281,8 +330,8 @@ static const struct irq_domain_ops qe_ic_host_ops = { ...@@ -281,8 +330,8 @@ static const struct irq_domain_ops qe_ic_host_ops = {
.xlate = irq_domain_xlate_onetwocell, .xlate = irq_domain_xlate_onetwocell,
}; };
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ /* Return an interrupt vector or 0 if no interrupt is pending. */
unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) static unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
{ {
int irq; int irq;
...@@ -292,13 +341,13 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) ...@@ -292,13 +341,13 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26; irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
if (irq == 0) if (irq == 0)
return NO_IRQ; return 0;
return irq_linear_revmap(qe_ic->irqhost, irq); return irq_linear_revmap(qe_ic->irqhost, irq);
} }
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ /* Return an interrupt vector or 0 if no interrupt is pending. */
unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) static unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
{ {
int irq; int irq;
...@@ -308,18 +357,60 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) ...@@ -308,18 +357,60 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26; irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
if (irq == 0) if (irq == 0)
return NO_IRQ; return 0;
return irq_linear_revmap(qe_ic->irqhost, irq); return irq_linear_revmap(qe_ic->irqhost, irq);
} }
void __init qe_ic_init(struct device_node *node, unsigned int flags, static void qe_ic_cascade_low(struct irq_desc *desc)
void (*low_handler)(struct irq_desc *desc), {
void (*high_handler)(struct irq_desc *desc)) struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != 0)
generic_handle_irq(cascade_irq);
if (chip->irq_eoi)
chip->irq_eoi(&desc->irq_data);
}
static void qe_ic_cascade_high(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != 0)
generic_handle_irq(cascade_irq);
if (chip->irq_eoi)
chip->irq_eoi(&desc->irq_data);
}
static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
{ {
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq;
struct irq_chip *chip = irq_desc_get_chip(desc);
cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq == 0)
cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != 0)
generic_handle_irq(cascade_irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init qe_ic_init(struct device_node *node)
{
void (*low_handler)(struct irq_desc *desc);
void (*high_handler)(struct irq_desc *desc);
struct qe_ic *qe_ic; struct qe_ic *qe_ic;
struct resource res; struct resource res;
u32 temp = 0, ret, high_active = 0; u32 ret;
ret = of_address_to_resource(node, 0, &res); ret = of_address_to_resource(node, 0, &res);
if (ret) if (ret)
...@@ -343,166 +434,42 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, ...@@ -343,166 +434,42 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
qe_ic->virq_high = irq_of_parse_and_map(node, 0); qe_ic->virq_high = irq_of_parse_and_map(node, 0);
qe_ic->virq_low = irq_of_parse_and_map(node, 1); qe_ic->virq_low = irq_of_parse_and_map(node, 1);
if (qe_ic->virq_low == NO_IRQ) { if (!qe_ic->virq_low) {
printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
kfree(qe_ic); kfree(qe_ic);
return; return;
} }
if (qe_ic->virq_high != qe_ic->virq_low) {
/* default priority scheme is grouped. If spread mode is */ low_handler = qe_ic_cascade_low;
/* required, configure cicr accordingly. */ high_handler = qe_ic_cascade_high;
if (flags & QE_IC_SPREADMODE_GRP_W) } else {
temp |= CICR_GWCC; low_handler = qe_ic_cascade_muxed_mpic;
if (flags & QE_IC_SPREADMODE_GRP_X) high_handler = NULL;
temp |= CICR_GXCC;
if (flags & QE_IC_SPREADMODE_GRP_Y)
temp |= CICR_GYCC;
if (flags & QE_IC_SPREADMODE_GRP_Z)
temp |= CICR_GZCC;
if (flags & QE_IC_SPREADMODE_GRP_RISCA)
temp |= CICR_GRTA;
if (flags & QE_IC_SPREADMODE_GRP_RISCB)
temp |= CICR_GRTB;
/* choose destination signal for highest priority interrupt */
if (flags & QE_IC_HIGH_SIGNAL) {
temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
high_active = 1;
} }
qe_ic_write(qe_ic->regs, QEIC_CICR, temp); qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
irq_set_handler_data(qe_ic->virq_low, qe_ic); irq_set_handler_data(qe_ic->virq_low, qe_ic);
irq_set_chained_handler(qe_ic->virq_low, low_handler); irq_set_chained_handler(qe_ic->virq_low, low_handler);
if (qe_ic->virq_high != NO_IRQ && if (qe_ic->virq_high && qe_ic->virq_high != qe_ic->virq_low) {
qe_ic->virq_high != qe_ic->virq_low) {
irq_set_handler_data(qe_ic->virq_high, qe_ic); irq_set_handler_data(qe_ic->virq_high, qe_ic);
irq_set_chained_handler(qe_ic->virq_high, high_handler); irq_set_chained_handler(qe_ic->virq_high, high_handler);
} }
} }
void qe_ic_set_highest_priority(unsigned int virq, int high) static int __init qe_ic_of_init(void)
{ {
struct qe_ic *qe_ic = qe_ic_from_irq(virq); struct device_node *np;
unsigned int src = virq_to_hw(virq);
u32 temp = 0;
temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
temp &= ~CICR_HP_MASK;
temp |= src << CICR_HP_SHIFT;
temp &= ~CICR_HPIT_MASK;
temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
}
/* Set Priority level within its group, from 1 to 8 */
int qe_ic_set_priority(unsigned int virq, unsigned int priority)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
u32 temp;
if (priority > 8 || priority == 0) np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
return -EINVAL; if (!np) {
if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info), np = of_find_node_by_type(NULL, "qeic");
"%s: Invalid hw irq number for QEIC\n", __func__)) if (!np)
return -EINVAL; return -ENODEV;
if (qe_ic_info[src].pri_reg == 0)
return -EINVAL;
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
if (priority < 4) {
temp &= ~(0x7 << (32 - priority * 3));
temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
} else {
temp &= ~(0x7 << (24 - priority * 3));
temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
} }
qe_ic_init(np);
qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp); of_node_put(np);
return 0; return 0;
} }
subsys_initcall(qe_ic_of_init);
/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
u32 temp, control_reg = QEIC_CICNR, shift = 0;
if (priority > 2 || priority == 0)
return -EINVAL;
if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
"%s: Invalid hw irq number for QEIC\n", __func__))
return -EINVAL;
switch (qe_ic_info[src].pri_reg) {
case QEIC_CIPZCC:
shift = CICNR_ZCC1T_SHIFT;
break;
case QEIC_CIPWCC:
shift = CICNR_WCC1T_SHIFT;
break;
case QEIC_CIPYCC:
shift = CICNR_YCC1T_SHIFT;
break;
case QEIC_CIPXCC:
shift = CICNR_XCC1T_SHIFT;
break;
case QEIC_CIPRTA:
shift = CRICR_RTA1T_SHIFT;
control_reg = QEIC_CRICR;
break;
case QEIC_CIPRTB:
shift = CRICR_RTB1T_SHIFT;
control_reg = QEIC_CRICR;
break;
default:
return -EINVAL;
}
shift += (2 - priority) * 2;
temp = qe_ic_read(qe_ic->regs, control_reg);
temp &= ~(SIGNAL_MASK << shift);
temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
qe_ic_write(qe_ic->regs, control_reg, temp);
return 0;
}
static struct bus_type qe_ic_subsys = {
.name = "qe_ic",
.dev_name = "qe_ic",
};
static struct device device_qe_ic = {
.id = 0,
.bus = &qe_ic_subsys,
};
static int __init init_qe_ic_sysfs(void)
{
int rc;
printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
rc = subsys_system_register(&qe_ic_subsys, NULL);
if (rc) {
printk(KERN_ERR "Failed registering qe_ic sys class\n");
return -ENODEV;
}
rc = device_register(&device_qe_ic);
if (rc) {
printk(KERN_ERR "Failed registering qe_ic sys device\n");
return -ENODEV;
}
return 0;
}
subsys_initcall(init_qe_ic_sysfs);
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* drivers/soc/fsl/qe/qe_ic.h
*
* QUICC ENGINE Interrupt Controller Header
*
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
*
* Author: Li Yang <leoli@freescale.com>
* Based on code from Shlomi Gridish <gridish@freescale.com>
*/
#ifndef _POWERPC_SYSDEV_QE_IC_H
#define _POWERPC_SYSDEV_QE_IC_H
#include <soc/fsl/qe/qe_ic.h>
#define NR_QE_IC_INTS 64
/* QE IC registers offset */
#define QEIC_CICR 0x00
#define QEIC_CIVEC 0x04
#define QEIC_CRIPNR 0x08
#define QEIC_CIPNR 0x0c
#define QEIC_CIPXCC 0x10
#define QEIC_CIPYCC 0x14
#define QEIC_CIPWCC 0x18
#define QEIC_CIPZCC 0x1c
#define QEIC_CIMR 0x20
#define QEIC_CRIMR 0x24
#define QEIC_CICNR 0x28
#define QEIC_CIPRTA 0x30
#define QEIC_CIPRTB 0x34
#define QEIC_CRICR 0x3c
#define QEIC_CHIVEC 0x60
/* Interrupt priority registers */
#define CIPCC_SHIFT_PRI0 29
#define CIPCC_SHIFT_PRI1 26
#define CIPCC_SHIFT_PRI2 23
#define CIPCC_SHIFT_PRI3 20
#define CIPCC_SHIFT_PRI4 13
#define CIPCC_SHIFT_PRI5 10
#define CIPCC_SHIFT_PRI6 7
#define CIPCC_SHIFT_PRI7 4
/* CICR priority modes */
#define CICR_GWCC 0x00040000
#define CICR_GXCC 0x00020000
#define CICR_GYCC 0x00010000
#define CICR_GZCC 0x00080000
#define CICR_GRTA 0x00200000
#define CICR_GRTB 0x00400000
#define CICR_HPIT_SHIFT 8
#define CICR_HPIT_MASK 0x00000300
#define CICR_HP_SHIFT 24
#define CICR_HP_MASK 0x3f000000
/* CICNR */
#define CICNR_WCC1T_SHIFT 20
#define CICNR_ZCC1T_SHIFT 28
#define CICNR_YCC1T_SHIFT 12
#define CICNR_XCC1T_SHIFT 4
/* CRICR */
#define CRICR_RTA1T_SHIFT 20
#define CRICR_RTB1T_SHIFT 28
/* Signal indicator */
#define SIGNAL_MASK 3
#define SIGNAL_HIGH 2
#define SIGNAL_LOW 0
struct qe_ic {
/* Control registers offset */
volatile u32 __iomem *regs;
/* The remapper for this QEIC */
struct irq_domain *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
/* VIRQ numbers of QE high/low irqs */
unsigned int virq_high;
unsigned int virq_low;
};
/*
* QE interrupt controller internal structure
*/
struct qe_ic_info {
u32 mask; /* location of this source at the QIMR register. */
u32 mask_reg; /* Mask register offset */
u8 pri_code; /* for grouped interrupts sources - the interrupt
code as appears at the group priority register */
u32 pri_reg; /* Group priority register offset */
};
#endif /* _POWERPC_SYSDEV_QE_IC_H */
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <asm/prom.h>
#include <sysdev/fsl_soc.h>
#undef DEBUG #undef DEBUG
...@@ -30,7 +28,7 @@ int par_io_init(struct device_node *np) ...@@ -30,7 +28,7 @@ int par_io_init(struct device_node *np)
{ {
struct resource res; struct resource res;
int ret; int ret;
const u32 *num_ports; u32 num_ports;
/* Map Parallel I/O ports registers */ /* Map Parallel I/O ports registers */
ret = of_address_to_resource(np, 0, &res); ret = of_address_to_resource(np, 0, &res);
...@@ -38,9 +36,8 @@ int par_io_init(struct device_node *np) ...@@ -38,9 +36,8 @@ int par_io_init(struct device_node *np)
return ret; return ret;
par_io = ioremap(res.start, resource_size(&res)); par_io = ioremap(res.start, resource_size(&res));
num_ports = of_get_property(np, "num-ports", NULL); if (!of_property_read_u32(np, "num-ports", &num_ports))
if (num_ports) num_par_io_ports = num_ports;
num_par_io_ports = *num_ports;
return 0; return 0;
} }
...@@ -57,16 +54,16 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir, ...@@ -57,16 +54,16 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1))); pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1)));
/* Set open drain, if required */ /* Set open drain, if required */
tmp_val = in_be32(&par_io->cpodr); tmp_val = qe_ioread32be(&par_io->cpodr);
if (open_drain) if (open_drain)
out_be32(&par_io->cpodr, pin_mask1bit | tmp_val); qe_iowrite32be(pin_mask1bit | tmp_val, &par_io->cpodr);
else else
out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val); qe_iowrite32be(~pin_mask1bit & tmp_val, &par_io->cpodr);
/* define direction */ /* define direction */
tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
in_be32(&par_io->cpdir2) : qe_ioread32be(&par_io->cpdir2) :
in_be32(&par_io->cpdir1); qe_ioread32be(&par_io->cpdir1);
/* get all bits mask for 2 bit per port */ /* get all bits mask for 2 bit per port */
pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS - pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS -
...@@ -78,34 +75,30 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir, ...@@ -78,34 +75,30 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
/* clear and set 2 bits mask */ /* clear and set 2 bits mask */
if (pin > (QE_PIO_PINS / 2) - 1) { if (pin > (QE_PIO_PINS / 2) - 1) {
out_be32(&par_io->cpdir2, qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir2);
~pin_mask2bits & tmp_val);
tmp_val &= ~pin_mask2bits; tmp_val &= ~pin_mask2bits;
out_be32(&par_io->cpdir2, new_mask2bits | tmp_val); qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir2);
} else { } else {
out_be32(&par_io->cpdir1, qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir1);
~pin_mask2bits & tmp_val);
tmp_val &= ~pin_mask2bits; tmp_val &= ~pin_mask2bits;
out_be32(&par_io->cpdir1, new_mask2bits | tmp_val); qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir1);
} }
/* define pin assignment */ /* define pin assignment */
tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
in_be32(&par_io->cppar2) : qe_ioread32be(&par_io->cppar2) :
in_be32(&par_io->cppar1); qe_ioread32be(&par_io->cppar1);
new_mask2bits = (u32) (assignment << (QE_PIO_PINS - new_mask2bits = (u32) (assignment << (QE_PIO_PINS -
(pin % (QE_PIO_PINS / 2) + 1) * 2)); (pin % (QE_PIO_PINS / 2) + 1) * 2));
/* clear and set 2 bits mask */ /* clear and set 2 bits mask */
if (pin > (QE_PIO_PINS / 2) - 1) { if (pin > (QE_PIO_PINS / 2) - 1) {
out_be32(&par_io->cppar2, qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar2);
~pin_mask2bits & tmp_val);
tmp_val &= ~pin_mask2bits; tmp_val &= ~pin_mask2bits;
out_be32(&par_io->cppar2, new_mask2bits | tmp_val); qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cppar2);
} else { } else {
out_be32(&par_io->cppar1, qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar1);
~pin_mask2bits & tmp_val);
tmp_val &= ~pin_mask2bits; tmp_val &= ~pin_mask2bits;
out_be32(&par_io->cppar1, new_mask2bits | tmp_val); qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cppar1);
} }
} }
EXPORT_SYMBOL(__par_io_config_pin); EXPORT_SYMBOL(__par_io_config_pin);
...@@ -133,12 +126,12 @@ int par_io_data_set(u8 port, u8 pin, u8 val) ...@@ -133,12 +126,12 @@ int par_io_data_set(u8 port, u8 pin, u8 val)
/* calculate pin location */ /* calculate pin location */
pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin)); pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin));
tmp_val = in_be32(&par_io[port].cpdata); tmp_val = qe_ioread32be(&par_io[port].cpdata);
if (val == 0) /* clear */ if (val == 0) /* clear */
out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val); qe_iowrite32be(~pin_mask & tmp_val, &par_io[port].cpdata);
else /* set */ else /* set */
out_be32(&par_io[port].cpdata, pin_mask | tmp_val); qe_iowrite32be(pin_mask | tmp_val, &par_io[port].cpdata);
return 0; return 0;
} }
...@@ -147,23 +140,20 @@ EXPORT_SYMBOL(par_io_data_set); ...@@ -147,23 +140,20 @@ EXPORT_SYMBOL(par_io_data_set);
int par_io_of_config(struct device_node *np) int par_io_of_config(struct device_node *np)
{ {
struct device_node *pio; struct device_node *pio;
const phandle *ph;
int pio_map_len; int pio_map_len;
const unsigned int *pio_map; const __be32 *pio_map;
if (par_io == NULL) { if (par_io == NULL) {
printk(KERN_ERR "par_io not initialized\n"); printk(KERN_ERR "par_io not initialized\n");
return -1; return -1;
} }
ph = of_get_property(np, "pio-handle", NULL); pio = of_parse_phandle(np, "pio-handle", 0);
if (ph == NULL) { if (pio == NULL) {
printk(KERN_ERR "pio-handle not available\n"); printk(KERN_ERR "pio-handle not available\n");
return -1; return -1;
} }
pio = of_find_node_by_phandle(*ph);
pio_map = of_get_property(pio, "pio-map", &pio_map_len); pio_map = of_get_property(pio, "pio-map", &pio_map_len);
if (pio_map == NULL) { if (pio_map == NULL) {
printk(KERN_ERR "pio-map is not set!\n"); printk(KERN_ERR "pio-map is not set!\n");
...@@ -176,9 +166,15 @@ int par_io_of_config(struct device_node *np) ...@@ -176,9 +166,15 @@ int par_io_of_config(struct device_node *np)
} }
while (pio_map_len > 0) { while (pio_map_len > 0) {
par_io_config_pin((u8) pio_map[0], (u8) pio_map[1], u8 port = be32_to_cpu(pio_map[0]);
(int) pio_map[2], (int) pio_map[3], u8 pin = be32_to_cpu(pio_map[1]);
(int) pio_map[4], (int) pio_map[5]); int dir = be32_to_cpu(pio_map[2]);
int open_drain = be32_to_cpu(pio_map[3]);
int assignment = be32_to_cpu(pio_map[4]);
int has_irq = be32_to_cpu(pio_map[5]);
par_io_config_pin(port, pin, dir, open_drain,
assignment, has_irq);
pio_map += 6; pio_map += 6;
pio_map_len -= 6; pio_map_len -= 6;
} }
......
...@@ -169,10 +169,10 @@ void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info) ...@@ -169,10 +169,10 @@ void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
&siram[siram_entry_id * 32 + 0x200 + i]); &siram[siram_entry_id * 32 + 0x200 + i]);
} }
setbits16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)], qe_setbits_be16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)],
SIR_LAST); SIR_LAST);
setbits16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)], qe_setbits_be16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)],
SIR_LAST); SIR_LAST);
/* Set SIxMR register */ /* Set SIxMR register */
sixmr = SIMR_SAD(siram_entry_id); sixmr = SIMR_SAD(siram_entry_id);
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/export.h> #include <linux/export.h>
#include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/immap_qe.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
...@@ -35,8 +34,8 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) ...@@ -35,8 +34,8 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&cmxgcr_lock, flags); spin_lock_irqsave(&cmxgcr_lock, flags);
clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG, qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT); ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
spin_unlock_irqrestore(&cmxgcr_lock, flags); spin_unlock_irqrestore(&cmxgcr_lock, flags);
return 0; return 0;
...@@ -80,8 +79,8 @@ int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed) ...@@ -80,8 +79,8 @@ int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
return -EINVAL; return -EINVAL;
} }
clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK, qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
UCC_GUEMR_SET_RESERVED3 | speed); UCC_GUEMR_SET_RESERVED3 | speed);
return 0; return 0;
} }
...@@ -109,9 +108,9 @@ int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask) ...@@ -109,9 +108,9 @@ int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift); get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
if (set) if (set)
setbits32(cmxucr, mask << shift); qe_setbits_be32(cmxucr, mask << shift);
else else
clrbits32(cmxucr, mask << shift); qe_clrbits_be32(cmxucr, mask << shift);
return 0; return 0;
} }
...@@ -207,8 +206,8 @@ int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock, ...@@ -207,8 +206,8 @@ int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
if (mode == COMM_DIR_RX) if (mode == COMM_DIR_RX)
shift += 4; shift += 4;
clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift, qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
clock_bits << shift); clock_bits << shift);
return 0; return 0;
} }
...@@ -540,8 +539,8 @@ int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock, ...@@ -540,8 +539,8 @@ int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l : cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
&qe_mux_reg->cmxsi1cr_h; &qe_mux_reg->cmxsi1cr_h;
qe_clrsetbits32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift, qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
clock_bits << shift); clock_bits << shift);
return 0; return 0;
} }
...@@ -650,9 +649,9 @@ int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock, ...@@ -650,9 +649,9 @@ int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
shift = ucc_get_tdm_sync_shift(mode, tdm_num); shift = ucc_get_tdm_sync_shift(mode, tdm_num);
qe_clrsetbits32(&qe_mux_reg->cmxsi1syr, qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
QE_CMXUCR_TX_CLK_SRC_MASK << shift, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
source << shift); source << shift);
return 0; return 0;
} }
...@@ -29,41 +29,42 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf) ...@@ -29,41 +29,42 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
printk(KERN_INFO "Base address: 0x%p\n", uccf->uf_regs); printk(KERN_INFO "Base address: 0x%p\n", uccf->uf_regs);
printk(KERN_INFO "gumr : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "gumr : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr)); &uccf->uf_regs->gumr, qe_ioread32be(&uccf->uf_regs->gumr));
printk(KERN_INFO "upsmr : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "upsmr : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr)); &uccf->uf_regs->upsmr, qe_ioread32be(&uccf->uf_regs->upsmr));
printk(KERN_INFO "utodr : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "utodr : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr)); &uccf->uf_regs->utodr, qe_ioread16be(&uccf->uf_regs->utodr));
printk(KERN_INFO "udsr : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "udsr : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr)); &uccf->uf_regs->udsr, qe_ioread16be(&uccf->uf_regs->udsr));
printk(KERN_INFO "ucce : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "ucce : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce)); &uccf->uf_regs->ucce, qe_ioread32be(&uccf->uf_regs->ucce));
printk(KERN_INFO "uccm : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "uccm : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm)); &uccf->uf_regs->uccm, qe_ioread32be(&uccf->uf_regs->uccm));
printk(KERN_INFO "uccs : addr=0x%p, val=0x%02x\n", printk(KERN_INFO "uccs : addr=0x%p, val=0x%02x\n",
&uccf->uf_regs->uccs, in_8(&uccf->uf_regs->uccs)); &uccf->uf_regs->uccs, qe_ioread8(&uccf->uf_regs->uccs));
printk(KERN_INFO "urfb : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "urfb : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb)); &uccf->uf_regs->urfb, qe_ioread32be(&uccf->uf_regs->urfb));
printk(KERN_INFO "urfs : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "urfs : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs)); &uccf->uf_regs->urfs, qe_ioread16be(&uccf->uf_regs->urfs));
printk(KERN_INFO "urfet : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "urfet : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet)); &uccf->uf_regs->urfet, qe_ioread16be(&uccf->uf_regs->urfet));
printk(KERN_INFO "urfset: addr=0x%p, val=0x%04x\n", printk(KERN_INFO "urfset: addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->urfset, in_be16(&uccf->uf_regs->urfset)); &uccf->uf_regs->urfset,
qe_ioread16be(&uccf->uf_regs->urfset));
printk(KERN_INFO "utfb : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "utfb : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb)); &uccf->uf_regs->utfb, qe_ioread32be(&uccf->uf_regs->utfb));
printk(KERN_INFO "utfs : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "utfs : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs)); &uccf->uf_regs->utfs, qe_ioread16be(&uccf->uf_regs->utfs));
printk(KERN_INFO "utfet : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "utfet : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet)); &uccf->uf_regs->utfet, qe_ioread16be(&uccf->uf_regs->utfet));
printk(KERN_INFO "utftt : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "utftt : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt)); &uccf->uf_regs->utftt, qe_ioread16be(&uccf->uf_regs->utftt));
printk(KERN_INFO "utpt : addr=0x%p, val=0x%04x\n", printk(KERN_INFO "utpt : addr=0x%p, val=0x%04x\n",
&uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt)); &uccf->uf_regs->utpt, qe_ioread16be(&uccf->uf_regs->utpt));
printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n", printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n",
&uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry)); &uccf->uf_regs->urtry, qe_ioread32be(&uccf->uf_regs->urtry));
printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n", printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n",
&uccf->uf_regs->guemr, in_8(&uccf->uf_regs->guemr)); &uccf->uf_regs->guemr, qe_ioread8(&uccf->uf_regs->guemr));
} }
EXPORT_SYMBOL(ucc_fast_dump_regs); EXPORT_SYMBOL(ucc_fast_dump_regs);
...@@ -85,7 +86,7 @@ EXPORT_SYMBOL(ucc_fast_get_qe_cr_subblock); ...@@ -85,7 +86,7 @@ EXPORT_SYMBOL(ucc_fast_get_qe_cr_subblock);
void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf) void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
{ {
out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD); qe_iowrite16be(UCC_FAST_TOD, &uccf->uf_regs->utodr);
} }
EXPORT_SYMBOL(ucc_fast_transmit_on_demand); EXPORT_SYMBOL(ucc_fast_transmit_on_demand);
...@@ -97,7 +98,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode) ...@@ -97,7 +98,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
uf_regs = uccf->uf_regs; uf_regs = uccf->uf_regs;
/* Enable reception and/or transmission on this UCC. */ /* Enable reception and/or transmission on this UCC. */
gumr = in_be32(&uf_regs->gumr); gumr = qe_ioread32be(&uf_regs->gumr);
if (mode & COMM_DIR_TX) { if (mode & COMM_DIR_TX) {
gumr |= UCC_FAST_GUMR_ENT; gumr |= UCC_FAST_GUMR_ENT;
uccf->enabled_tx = 1; uccf->enabled_tx = 1;
...@@ -106,7 +107,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode) ...@@ -106,7 +107,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
gumr |= UCC_FAST_GUMR_ENR; gumr |= UCC_FAST_GUMR_ENR;
uccf->enabled_rx = 1; uccf->enabled_rx = 1;
} }
out_be32(&uf_regs->gumr, gumr); qe_iowrite32be(gumr, &uf_regs->gumr);
} }
EXPORT_SYMBOL(ucc_fast_enable); EXPORT_SYMBOL(ucc_fast_enable);
...@@ -118,7 +119,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode) ...@@ -118,7 +119,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
uf_regs = uccf->uf_regs; uf_regs = uccf->uf_regs;
/* Disable reception and/or transmission on this UCC. */ /* Disable reception and/or transmission on this UCC. */
gumr = in_be32(&uf_regs->gumr); gumr = qe_ioread32be(&uf_regs->gumr);
if (mode & COMM_DIR_TX) { if (mode & COMM_DIR_TX) {
gumr &= ~UCC_FAST_GUMR_ENT; gumr &= ~UCC_FAST_GUMR_ENT;
uccf->enabled_tx = 0; uccf->enabled_tx = 0;
...@@ -127,7 +128,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode) ...@@ -127,7 +128,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
gumr &= ~UCC_FAST_GUMR_ENR; gumr &= ~UCC_FAST_GUMR_ENR;
uccf->enabled_rx = 0; uccf->enabled_rx = 0;
} }
out_be32(&uf_regs->gumr, gumr); qe_iowrite32be(gumr, &uf_regs->gumr);
} }
EXPORT_SYMBOL(ucc_fast_disable); EXPORT_SYMBOL(ucc_fast_disable);
...@@ -196,6 +197,8 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ...@@ -196,6 +197,8 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
uccf->ucc_fast_tx_virtual_fifo_base_offset = -1;
uccf->ucc_fast_rx_virtual_fifo_base_offset = -1;
/* Fill fast UCC structure */ /* Fill fast UCC structure */
uccf->uf_info = uf_info; uccf->uf_info = uf_info;
...@@ -259,15 +262,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ...@@ -259,15 +262,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
gumr |= uf_info->tenc; gumr |= uf_info->tenc;
gumr |= uf_info->tcrc; gumr |= uf_info->tcrc;
gumr |= uf_info->mode; gumr |= uf_info->mode;
out_be32(&uf_regs->gumr, gumr); qe_iowrite32be(gumr, &uf_regs->gumr);
/* Allocate memory for Tx Virtual Fifo */ /* Allocate memory for Tx Virtual Fifo */
uccf->ucc_fast_tx_virtual_fifo_base_offset = uccf->ucc_fast_tx_virtual_fifo_base_offset =
qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) { if (uccf->ucc_fast_tx_virtual_fifo_base_offset < 0) {
printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n", printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n",
__func__); __func__);
uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
ucc_fast_free(uccf); ucc_fast_free(uccf);
return -ENOMEM; return -ENOMEM;
} }
...@@ -277,24 +279,25 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ...@@ -277,24 +279,25 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
qe_muram_alloc(uf_info->urfs + qe_muram_alloc(uf_info->urfs +
UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR, UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) { if (uccf->ucc_fast_rx_virtual_fifo_base_offset < 0) {
printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n", printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n",
__func__); __func__);
uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
ucc_fast_free(uccf); ucc_fast_free(uccf);
return -ENOMEM; return -ENOMEM;
} }
/* Set Virtual Fifo registers */ /* Set Virtual Fifo registers */
out_be16(&uf_regs->urfs, uf_info->urfs); qe_iowrite16be(uf_info->urfs, &uf_regs->urfs);
out_be16(&uf_regs->urfet, uf_info->urfet); qe_iowrite16be(uf_info->urfet, &uf_regs->urfet);
out_be16(&uf_regs->urfset, uf_info->urfset); qe_iowrite16be(uf_info->urfset, &uf_regs->urfset);
out_be16(&uf_regs->utfs, uf_info->utfs); qe_iowrite16be(uf_info->utfs, &uf_regs->utfs);
out_be16(&uf_regs->utfet, uf_info->utfet); qe_iowrite16be(uf_info->utfet, &uf_regs->utfet);
out_be16(&uf_regs->utftt, uf_info->utftt); qe_iowrite16be(uf_info->utftt, &uf_regs->utftt);
/* utfb, urfb are offsets from MURAM base */ /* utfb, urfb are offsets from MURAM base */
out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset); qe_iowrite32be(uccf->ucc_fast_tx_virtual_fifo_base_offset,
out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset); &uf_regs->utfb);
qe_iowrite32be(uccf->ucc_fast_rx_virtual_fifo_base_offset,
&uf_regs->urfb);
/* Mux clocking */ /* Mux clocking */
/* Grant Support */ /* Grant Support */
...@@ -362,14 +365,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ...@@ -362,14 +365,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
} }
/* Set interrupt mask register at UCC level. */ /* Set interrupt mask register at UCC level. */
out_be32(&uf_regs->uccm, uf_info->uccm_mask); qe_iowrite32be(uf_info->uccm_mask, &uf_regs->uccm);
/* First, clear anything pending at UCC level, /* First, clear anything pending at UCC level,
* otherwise, old garbage may come through * otherwise, old garbage may come through
* as soon as the dam is opened. */ * as soon as the dam is opened. */
/* Writing '1' clears */ /* Writing '1' clears */
out_be32(&uf_regs->ucce, 0xffffffff); qe_iowrite32be(0xffffffff, &uf_regs->ucce);
*uccf_ret = uccf; *uccf_ret = uccf;
return 0; return 0;
...@@ -381,11 +384,8 @@ void ucc_fast_free(struct ucc_fast_private * uccf) ...@@ -381,11 +384,8 @@ void ucc_fast_free(struct ucc_fast_private * uccf)
if (!uccf) if (!uccf)
return; return;
if (uccf->ucc_fast_tx_virtual_fifo_base_offset) qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset); qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
if (uccf->uf_regs) if (uccf->uf_regs)
iounmap(uccf->uf_regs); iounmap(uccf->uf_regs);
......
...@@ -78,7 +78,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode) ...@@ -78,7 +78,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
us_regs = uccs->us_regs; us_regs = uccs->us_regs;
/* Enable reception and/or transmission on this UCC. */ /* Enable reception and/or transmission on this UCC. */
gumr_l = in_be32(&us_regs->gumr_l); gumr_l = qe_ioread32be(&us_regs->gumr_l);
if (mode & COMM_DIR_TX) { if (mode & COMM_DIR_TX) {
gumr_l |= UCC_SLOW_GUMR_L_ENT; gumr_l |= UCC_SLOW_GUMR_L_ENT;
uccs->enabled_tx = 1; uccs->enabled_tx = 1;
...@@ -87,7 +87,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode) ...@@ -87,7 +87,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
gumr_l |= UCC_SLOW_GUMR_L_ENR; gumr_l |= UCC_SLOW_GUMR_L_ENR;
uccs->enabled_rx = 1; uccs->enabled_rx = 1;
} }
out_be32(&us_regs->gumr_l, gumr_l); qe_iowrite32be(gumr_l, &us_regs->gumr_l);
} }
EXPORT_SYMBOL(ucc_slow_enable); EXPORT_SYMBOL(ucc_slow_enable);
...@@ -99,7 +99,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode) ...@@ -99,7 +99,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
us_regs = uccs->us_regs; us_regs = uccs->us_regs;
/* Disable reception and/or transmission on this UCC. */ /* Disable reception and/or transmission on this UCC. */
gumr_l = in_be32(&us_regs->gumr_l); gumr_l = qe_ioread32be(&us_regs->gumr_l);
if (mode & COMM_DIR_TX) { if (mode & COMM_DIR_TX) {
gumr_l &= ~UCC_SLOW_GUMR_L_ENT; gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
uccs->enabled_tx = 0; uccs->enabled_tx = 0;
...@@ -108,7 +108,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode) ...@@ -108,7 +108,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
gumr_l &= ~UCC_SLOW_GUMR_L_ENR; gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
uccs->enabled_rx = 0; uccs->enabled_rx = 0;
} }
out_be32(&us_regs->gumr_l, gumr_l); qe_iowrite32be(gumr_l, &us_regs->gumr_l);
} }
EXPORT_SYMBOL(ucc_slow_disable); EXPORT_SYMBOL(ucc_slow_disable);
...@@ -154,6 +154,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -154,6 +154,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
uccs->rx_base_offset = -1;
uccs->tx_base_offset = -1;
uccs->us_pram_offset = -1;
/* Fill slow UCC structure */ /* Fill slow UCC structure */
uccs->us_info = us_info; uccs->us_info = us_info;
...@@ -179,7 +182,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -179,7 +182,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* Get PRAM base */ /* Get PRAM base */
uccs->us_pram_offset = uccs->us_pram_offset =
qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM); qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
if (IS_ERR_VALUE(uccs->us_pram_offset)) { if (uccs->us_pram_offset < 0) {
printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__); printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__);
ucc_slow_free(uccs); ucc_slow_free(uccs);
return -ENOMEM; return -ENOMEM;
...@@ -198,7 +201,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -198,7 +201,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
return ret; return ret;
} }
out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length); qe_iowrite16be(us_info->max_rx_buf_length, &uccs->us_pram->mrblr);
INIT_LIST_HEAD(&uccs->confQ); INIT_LIST_HEAD(&uccs->confQ);
...@@ -206,10 +209,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -206,10 +209,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
uccs->rx_base_offset = uccs->rx_base_offset =
qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd), qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
QE_ALIGNMENT_OF_BD); QE_ALIGNMENT_OF_BD);
if (IS_ERR_VALUE(uccs->rx_base_offset)) { if (uccs->rx_base_offset < 0) {
printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__, printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__,
us_info->rx_bd_ring_len); us_info->rx_bd_ring_len);
uccs->rx_base_offset = 0;
ucc_slow_free(uccs); ucc_slow_free(uccs);
return -ENOMEM; return -ENOMEM;
} }
...@@ -217,9 +219,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -217,9 +219,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
uccs->tx_base_offset = uccs->tx_base_offset =
qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd), qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
QE_ALIGNMENT_OF_BD); QE_ALIGNMENT_OF_BD);
if (IS_ERR_VALUE(uccs->tx_base_offset)) { if (uccs->tx_base_offset < 0) {
printk(KERN_ERR "%s: cannot allocate TX BDs", __func__); printk(KERN_ERR "%s: cannot allocate TX BDs", __func__);
uccs->tx_base_offset = 0;
ucc_slow_free(uccs); ucc_slow_free(uccs);
return -ENOMEM; return -ENOMEM;
} }
...@@ -228,27 +229,27 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -228,27 +229,27 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset); bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) { for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) {
/* clear bd buffer */ /* clear bd buffer */
out_be32(&bd->buf, 0); qe_iowrite32be(0, &bd->buf);
/* set bd status and length */ /* set bd status and length */
out_be32((u32 *) bd, 0); qe_iowrite32be(0, (u32 *)bd);
bd++; bd++;
} }
/* for last BD set Wrap bit */ /* for last BD set Wrap bit */
out_be32(&bd->buf, 0); qe_iowrite32be(0, &bd->buf);
out_be32((u32 *) bd, cpu_to_be32(T_W)); qe_iowrite32be(cpu_to_be32(T_W), (u32 *)bd);
/* Init Rx bds */ /* Init Rx bds */
bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset); bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) { for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
/* set bd status and length */ /* set bd status and length */
out_be32((u32*)bd, 0); qe_iowrite32be(0, (u32 *)bd);
/* clear bd buffer */ /* clear bd buffer */
out_be32(&bd->buf, 0); qe_iowrite32be(0, &bd->buf);
bd++; bd++;
} }
/* for last BD set Wrap bit */ /* for last BD set Wrap bit */
out_be32((u32*)bd, cpu_to_be32(R_W)); qe_iowrite32be(cpu_to_be32(R_W), (u32 *)bd);
out_be32(&bd->buf, 0); qe_iowrite32be(0, &bd->buf);
/* Set GUMR (For more details see the hardware spec.). */ /* Set GUMR (For more details see the hardware spec.). */
/* gumr_h */ /* gumr_h */
...@@ -269,7 +270,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -269,7 +270,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
gumr |= UCC_SLOW_GUMR_H_TXSY; gumr |= UCC_SLOW_GUMR_H_TXSY;
if (us_info->rtsm) if (us_info->rtsm)
gumr |= UCC_SLOW_GUMR_H_RTSM; gumr |= UCC_SLOW_GUMR_H_RTSM;
out_be32(&us_regs->gumr_h, gumr); qe_iowrite32be(gumr, &us_regs->gumr_h);
/* gumr_l */ /* gumr_l */
gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc | gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
...@@ -282,7 +283,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -282,7 +283,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
gumr |= UCC_SLOW_GUMR_L_TINV; gumr |= UCC_SLOW_GUMR_L_TINV;
if (us_info->tend) if (us_info->tend)
gumr |= UCC_SLOW_GUMR_L_TEND; gumr |= UCC_SLOW_GUMR_L_TEND;
out_be32(&us_regs->gumr_l, gumr); qe_iowrite32be(gumr, &us_regs->gumr_l);
/* Function code registers */ /* Function code registers */
...@@ -292,8 +293,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -292,8 +293,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
uccs->us_pram->rbmr = UCC_BMR_BO_BE; uccs->us_pram->rbmr = UCC_BMR_BO_BE;
/* rbase, tbase are offsets from MURAM base */ /* rbase, tbase are offsets from MURAM base */
out_be16(&uccs->us_pram->rbase, uccs->rx_base_offset); qe_iowrite16be(uccs->rx_base_offset, &uccs->us_pram->rbase);
out_be16(&uccs->us_pram->tbase, uccs->tx_base_offset); qe_iowrite16be(uccs->tx_base_offset, &uccs->us_pram->tbase);
/* Mux clocking */ /* Mux clocking */
/* Grant Support */ /* Grant Support */
...@@ -323,14 +324,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc ...@@ -323,14 +324,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
} }
/* Set interrupt mask register at UCC level. */ /* Set interrupt mask register at UCC level. */
out_be16(&us_regs->uccm, us_info->uccm_mask); qe_iowrite16be(us_info->uccm_mask, &us_regs->uccm);
/* First, clear anything pending at UCC level, /* First, clear anything pending at UCC level,
* otherwise, old garbage may come through * otherwise, old garbage may come through
* as soon as the dam is opened. */ * as soon as the dam is opened. */
/* Writing '1' clears */ /* Writing '1' clears */
out_be16(&us_regs->ucce, 0xffff); qe_iowrite16be(0xffff, &us_regs->ucce);
/* Issue QE Init command */ /* Issue QE Init command */
if (us_info->init_tx && us_info->init_rx) if (us_info->init_tx && us_info->init_rx)
...@@ -352,14 +353,9 @@ void ucc_slow_free(struct ucc_slow_private * uccs) ...@@ -352,14 +353,9 @@ void ucc_slow_free(struct ucc_slow_private * uccs)
if (!uccs) if (!uccs)
return; return;
if (uccs->rx_base_offset) qe_muram_free(uccs->rx_base_offset);
qe_muram_free(uccs->rx_base_offset); qe_muram_free(uccs->tx_base_offset);
qe_muram_free(uccs->us_pram_offset);
if (uccs->tx_base_offset)
qe_muram_free(uccs->tx_base_offset);
if (uccs->us_pram)
qe_muram_free(uccs->us_pram_offset);
if (uccs->us_regs) if (uccs->us_regs)
iounmap(uccs->us_regs); iounmap(uccs->us_regs);
......
...@@ -43,7 +43,7 @@ int qe_usb_clock_set(enum qe_clock clk, int rate) ...@@ -43,7 +43,7 @@ int qe_usb_clock_set(enum qe_clock clk, int rate)
spin_lock_irqsave(&cmxgcr_lock, flags); spin_lock_irqsave(&cmxgcr_lock, flags);
clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val); qe_clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val);
spin_unlock_irqrestore(&cmxgcr_lock, flags); spin_unlock_irqrestore(&cmxgcr_lock, flags);
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __CPM_H
#define __CPM_H
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <soc/fsl/qe/qe.h>
/*
* SPI Parameter RAM common to QE and CPM.
*/
struct spi_pram {
__be16 rbase; /* Rx Buffer descriptor base address */
__be16 tbase; /* Tx Buffer descriptor base address */
u8 rfcr; /* Rx function code */
u8 tfcr; /* Tx function code */
__be16 mrblr; /* Max receive buffer length */
__be32 rstate; /* Internal */
__be32 rdp; /* Internal */
__be16 rbptr; /* Internal */
__be16 rbc; /* Internal */
__be32 rxtmp; /* Internal */
__be32 tstate; /* Internal */
__be32 tdp; /* Internal */
__be16 tbptr; /* Internal */
__be16 tbc; /* Internal */
__be32 txtmp; /* Internal */
__be32 res; /* Tx temp. */
__be16 rpbase; /* Relocation pointer (CPM1 only) */
__be16 res1; /* Reserved */
};
/*
* USB Controller pram common to QE and CPM.
*/
struct usb_ctlr {
u8 usb_usmod;
u8 usb_usadr;
u8 usb_uscom;
u8 res1[1];
__be16 usb_usep[4];
u8 res2[4];
__be16 usb_usber;
u8 res3[2];
__be16 usb_usbmr;
u8 res4[1];
u8 usb_usbs;
/* Fields down below are QE-only */
__be16 usb_ussft;
u8 res5[2];
__be16 usb_usfrn;
u8 res6[0x22];
} __attribute__ ((packed));
/*
* Function code bits, usually generic to devices.
*/
#ifdef CONFIG_CPM1
#define CPMFCR_GBL ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_TC2 ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_DTB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#define CPMFCR_BDB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
#else
#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */
#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */
#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */
#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */
#endif
#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */
/* Opcodes common to CPM1 and CPM2
*/
#define CPM_CR_INIT_TRX ((ushort)0x0000)
#define CPM_CR_INIT_RX ((ushort)0x0001)
#define CPM_CR_INIT_TX ((ushort)0x0002)
#define CPM_CR_HUNT_MODE ((ushort)0x0003)
#define CPM_CR_STOP_TX ((ushort)0x0004)
#define CPM_CR_GRA_STOP_TX ((ushort)0x0005)
#define CPM_CR_RESTART_TX ((ushort)0x0006)
#define CPM_CR_CLOSE_RX_BD ((ushort)0x0007)
#define CPM_CR_SET_GADDR ((ushort)0x0008)
#define CPM_CR_SET_TIMER ((ushort)0x0008)
#define CPM_CR_STOP_IDMA ((ushort)0x000b)
/* Buffer descriptors used by many of the CPM protocols. */
typedef struct cpm_buf_desc {
ushort cbd_sc; /* Status and Control */
ushort cbd_datlen; /* Data length in buffer */
uint cbd_bufaddr; /* Buffer address in host memory */
} cbd_t;
/* Buffer descriptor control/status used by serial
*/
#define BD_SC_EMPTY (0x8000) /* Receive is empty */
#define BD_SC_READY (0x8000) /* Transmit is ready */
#define BD_SC_WRAP (0x2000) /* Last buffer descriptor */
#define BD_SC_INTRPT (0x1000) /* Interrupt on change */
#define BD_SC_LAST (0x0800) /* Last buffer in frame */
#define BD_SC_TC (0x0400) /* Transmit CRC */
#define BD_SC_CM (0x0200) /* Continuous mode */
#define BD_SC_ID (0x0100) /* Rec'd too many idles */
#define BD_SC_P (0x0100) /* xmt preamble */
#define BD_SC_BR (0x0020) /* Break received */
#define BD_SC_FR (0x0010) /* Framing error */
#define BD_SC_PR (0x0008) /* Parity error */
#define BD_SC_NAK (0x0004) /* NAK - did not respond */
#define BD_SC_OV (0x0002) /* Overrun */
#define BD_SC_UN (0x0002) /* Underrun */
#define BD_SC_CD (0x0001) /* */
#define BD_SC_CL (0x0001) /* Collision */
/* Buffer descriptor control/status used by Ethernet receive.
* Common to SCC and FCC.
*/
#define BD_ENET_RX_EMPTY (0x8000)
#define BD_ENET_RX_WRAP (0x2000)
#define BD_ENET_RX_INTR (0x1000)
#define BD_ENET_RX_LAST (0x0800)
#define BD_ENET_RX_FIRST (0x0400)
#define BD_ENET_RX_MISS (0x0100)
#define BD_ENET_RX_BC (0x0080) /* FCC Only */
#define BD_ENET_RX_MC (0x0040) /* FCC Only */
#define BD_ENET_RX_LG (0x0020)
#define BD_ENET_RX_NO (0x0010)
#define BD_ENET_RX_SH (0x0008)
#define BD_ENET_RX_CR (0x0004)
#define BD_ENET_RX_OV (0x0002)
#define BD_ENET_RX_CL (0x0001)
#define BD_ENET_RX_STATS (0x01ff) /* All status bits */
/* Buffer descriptor control/status used by Ethernet transmit.
* Common to SCC and FCC.
*/
#define BD_ENET_TX_READY (0x8000)
#define BD_ENET_TX_PAD (0x4000)
#define BD_ENET_TX_WRAP (0x2000)
#define BD_ENET_TX_INTR (0x1000)
#define BD_ENET_TX_LAST (0x0800)
#define BD_ENET_TX_TC (0x0400)
#define BD_ENET_TX_DEF (0x0200)
#define BD_ENET_TX_HB (0x0100)
#define BD_ENET_TX_LC (0x0080)
#define BD_ENET_TX_RL (0x0040)
#define BD_ENET_TX_RCMASK (0x003c)
#define BD_ENET_TX_UN (0x0002)
#define BD_ENET_TX_CSL (0x0001)
#define BD_ENET_TX_STATS (0x03ff) /* All status bits */
/* Buffer descriptor control/status used by Transparent mode SCC.
*/
#define BD_SCC_TX_LAST (0x0800)
/* Buffer descriptor control/status used by I2C.
*/
#define BD_I2C_START (0x0400)
#ifdef CONFIG_CPM
int cpm_command(u32 command, u8 opcode);
#else
static inline int cpm_command(u32 command, u8 opcode)
{
return -ENOSYS;
}
#endif /* CONFIG_CPM */
int cpm2_gpiochip_add32(struct device *dev);
#endif
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
#include <asm/cpm.h> #include <soc/fsl/cpm.h>
#include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/immap_qe.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -98,26 +98,25 @@ static inline void qe_reset(void) {} ...@@ -98,26 +98,25 @@ static inline void qe_reset(void) {}
int cpm_muram_init(void); int cpm_muram_init(void);
#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) #if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE)
unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); s32 cpm_muram_alloc(unsigned long size, unsigned long align);
int cpm_muram_free(unsigned long offset); void cpm_muram_free(s32 offset);
unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); s32 cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
void __iomem *cpm_muram_addr(unsigned long offset); void __iomem *cpm_muram_addr(unsigned long offset);
unsigned long cpm_muram_offset(void __iomem *addr); unsigned long cpm_muram_offset(void __iomem *addr);
dma_addr_t cpm_muram_dma(void __iomem *addr); dma_addr_t cpm_muram_dma(void __iomem *addr);
#else #else
static inline unsigned long cpm_muram_alloc(unsigned long size, static inline s32 cpm_muram_alloc(unsigned long size,
unsigned long align) unsigned long align)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline int cpm_muram_free(unsigned long offset) static inline void cpm_muram_free(s32 offset)
{ {
return -ENOSYS;
} }
static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, static inline s32 cpm_muram_alloc_fixed(unsigned long offset,
unsigned long size) unsigned long size)
{ {
return -ENOSYS; return -ENOSYS;
} }
...@@ -241,21 +240,37 @@ static inline int qe_alive_during_sleep(void) ...@@ -241,21 +240,37 @@ static inline int qe_alive_during_sleep(void)
#define qe_muram_offset cpm_muram_offset #define qe_muram_offset cpm_muram_offset
#define qe_muram_dma cpm_muram_dma #define qe_muram_dma cpm_muram_dma
#define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr)) #ifdef CONFIG_PPC32
#define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr)) #define qe_iowrite8(val, addr) out_8(addr, val)
#define qe_iowrite16be(val, addr) out_be16(addr, val)
#define qe_iowrite32be(val, addr) out_be32(addr, val)
#define qe_ioread8(addr) in_8(addr)
#define qe_ioread16be(addr) in_be16(addr)
#define qe_ioread32be(addr) in_be32(addr)
#else
#define qe_iowrite8(val, addr) iowrite8(val, addr)
#define qe_iowrite16be(val, addr) iowrite16be(val, addr)
#define qe_iowrite32be(val, addr) iowrite32be(val, addr)
#define qe_ioread8(addr) ioread8(addr)
#define qe_ioread16be(addr) ioread16be(addr)
#define qe_ioread32be(addr) ioread32be(addr)
#endif
#define qe_setbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) | (_v), (_addr))
#define qe_clrbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) & ~(_v), (_addr))
#define qe_setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr)) #define qe_setbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) | (_v), (_addr))
#define qe_clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr)) #define qe_clrbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) & ~(_v), (_addr))
#define qe_setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr)) #define qe_setbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) | (_v), (_addr))
#define qe_clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr)) #define qe_clrbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) & ~(_v), (_addr))
#define qe_clrsetbits32(addr, clear, set) \ #define qe_clrsetbits_be32(addr, clear, set) \
iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr)) qe_iowrite32be((qe_ioread32be(addr) & ~(clear)) | (set), (addr))
#define qe_clrsetbits16(addr, clear, set) \ #define qe_clrsetbits_be16(addr, clear, set) \
iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr)) qe_iowrite16be((qe_ioread16be(addr) & ~(clear)) | (set), (addr))
#define qe_clrsetbits8(addr, clear, set) \ #define qe_clrsetbits_8(addr, clear, set) \
iowrite8((ioread8(addr) & ~(clear)) | (set), (addr)) qe_iowrite8((qe_ioread8(addr) & ~(clear)) | (set), (addr))
/* Structure that defines QE firmware binary files. /* Structure that defines QE firmware binary files.
* *
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
*
* Authors: Shlomi Gridish <gridish@freescale.com>
* Li Yang <leoli@freescale.com>
*
* Description:
* QE IC external definitions and structure.
*/
#ifndef _ASM_POWERPC_QE_IC_H
#define _ASM_POWERPC_QE_IC_H
#include <linux/irq.h>
struct device_node;
struct qe_ic;
#define NUM_OF_QE_IC_GROUPS 6
/* Flags when we init the QE IC */
#define QE_IC_SPREADMODE_GRP_W 0x00000001
#define QE_IC_SPREADMODE_GRP_X 0x00000002
#define QE_IC_SPREADMODE_GRP_Y 0x00000004
#define QE_IC_SPREADMODE_GRP_Z 0x00000008
#define QE_IC_SPREADMODE_GRP_RISCA 0x00000010
#define QE_IC_SPREADMODE_GRP_RISCB 0x00000020
#define QE_IC_LOW_SIGNAL 0x00000100
#define QE_IC_HIGH_SIGNAL 0x00000200
#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH 0x00001000
#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH 0x00002000
#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH 0x00004000
#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH 0x00008000
#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH 0x00010000
#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH 0x00020000
#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH 0x00040000
#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH 0x00080000
#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH 0x00100000
#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH 0x00200000
#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH 0x00400000
#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH 0x00800000
#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT (12)
/* QE interrupt sources groups */
enum qe_ic_grp_id {
QE_IC_GRP_W = 0, /* QE interrupt controller group W */
QE_IC_GRP_X, /* QE interrupt controller group X */
QE_IC_GRP_Y, /* QE interrupt controller group Y */
QE_IC_GRP_Z, /* QE interrupt controller group Z */
QE_IC_GRP_RISCA, /* QE interrupt controller RISC group A */
QE_IC_GRP_RISCB /* QE interrupt controller RISC group B */
};
#ifdef CONFIG_QUICC_ENGINE
void qe_ic_init(struct device_node *node, unsigned int flags,
void (*low_handler)(struct irq_desc *desc),
void (*high_handler)(struct irq_desc *desc));
unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic);
unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic);
#else
static inline void qe_ic_init(struct device_node *node, unsigned int flags,
void (*low_handler)(struct irq_desc *desc),
void (*high_handler)(struct irq_desc *desc))
{}
static inline unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
{ return 0; }
static inline unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
{ return 0; }
#endif /* CONFIG_QUICC_ENGINE */
void qe_ic_set_highest_priority(unsigned int virq, int high);
int qe_ic_set_priority(unsigned int virq, unsigned int priority);
int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
static inline void qe_ic_cascade_low_ipic(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
}
static inline void qe_ic_cascade_high_ipic(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
}
static inline void qe_ic_cascade_low_mpic(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
chip->irq_eoi(&desc->irq_data);
}
static inline void qe_ic_cascade_high_mpic(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
chip->irq_eoi(&desc->irq_data);
}
static inline void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
{
struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq;
struct irq_chip *chip = irq_desc_get_chip(desc);
cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq == NO_IRQ)
cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* _ASM_POWERPC_QE_IC_H */
...@@ -188,9 +188,9 @@ struct ucc_fast_private { ...@@ -188,9 +188,9 @@ struct ucc_fast_private {
int stopped_tx; /* Whether channel has been stopped for Tx int stopped_tx; /* Whether channel has been stopped for Tx
(STOP_TX, etc.) */ (STOP_TX, etc.) */
int stopped_rx; /* Whether channel has been stopped for Rx */ int stopped_rx; /* Whether channel has been stopped for Rx */
u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx s32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
virtual fifo */ virtual fifo */
u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx s32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
virtual fifo */ virtual fifo */
#ifdef STATISTICS #ifdef STATISTICS
u32 tx_frames; /* Transmitted frames counter. */ u32 tx_frames; /* Transmitted frames counter. */
......
...@@ -185,7 +185,7 @@ struct ucc_slow_private { ...@@ -185,7 +185,7 @@ struct ucc_slow_private {
struct ucc_slow_info *us_info; struct ucc_slow_info *us_info;
struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */ struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */ struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */
u32 us_pram_offset; s32 us_pram_offset;
int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
int stopped_tx; /* Whether channel has been stopped for Tx int stopped_tx; /* Whether channel has been stopped for Tx
...@@ -194,8 +194,8 @@ struct ucc_slow_private { ...@@ -194,8 +194,8 @@ struct ucc_slow_private {
struct list_head confQ; /* frames passed to chip waiting for tx */ struct list_head confQ; /* frames passed to chip waiting for tx */
u32 first_tx_bd_mask; /* mask is used in Tx routine to save status u32 first_tx_bd_mask; /* mask is used in Tx routine to save status
and length for first BD in a frame */ and length for first BD in a frame */
u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ s32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */
u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ s32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */
struct qe_bd *confBd; /* next BD for confirm after Tx */ struct qe_bd *confBd; /* next BD for confirm after Tx */
struct qe_bd *tx_bd; /* next BD for new Tx request */ struct qe_bd *tx_bd; /* next BD for new Tx request */
struct qe_bd *rx_bd; /* next BD to collect after Rx */ struct qe_bd *rx_bd; /* next BD to collect after Rx */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment