mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
add rk29xx vmac driver
This commit is contained in:
@@ -574,7 +574,46 @@ CONFIG_NETDEVICES=y
|
||||
# CONFIG_EQUALIZER is not set
|
||||
# CONFIG_TUN is not set
|
||||
# CONFIG_VETH is not set
|
||||
# CONFIG_NET_ETHERNET is not set
|
||||
CONFIG_PHYLIB=y
|
||||
|
||||
#
|
||||
# MII PHY device drivers
|
||||
#
|
||||
# CONFIG_MARVELL_PHY is not set
|
||||
# CONFIG_DAVICOM_PHY is not set
|
||||
# CONFIG_QSEMI_PHY is not set
|
||||
# CONFIG_LXT_PHY is not set
|
||||
# CONFIG_CICADA_PHY is not set
|
||||
# CONFIG_VITESSE_PHY is not set
|
||||
# CONFIG_SMSC_PHY is not set
|
||||
# CONFIG_BROADCOM_PHY is not set
|
||||
# CONFIG_ICPLUS_PHY is not set
|
||||
# CONFIG_REALTEK_PHY is not set
|
||||
# CONFIG_NATIONAL_PHY is not set
|
||||
# CONFIG_STE10XP is not set
|
||||
# CONFIG_LSI_ET1011C_PHY is not set
|
||||
# CONFIG_FIXED_PHY is not set
|
||||
# CONFIG_MDIO_BITBANG is not set
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_MII=y
|
||||
# CONFIG_AX88796 is not set
|
||||
CONFIG_RK29_VMAC=y
|
||||
# CONFIG_SMC91X is not set
|
||||
# CONFIG_DM9000 is not set
|
||||
# CONFIG_ETHOC is not set
|
||||
# CONFIG_SMC911X is not set
|
||||
# CONFIG_SMSC911X is not set
|
||||
# CONFIG_DNET is not set
|
||||
# CONFIG_IBM_NEW_EMAC_ZMII is not set
|
||||
# CONFIG_IBM_NEW_EMAC_RGMII is not set
|
||||
# CONFIG_IBM_NEW_EMAC_TAH is not set
|
||||
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
|
||||
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
|
||||
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
|
||||
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
|
||||
# CONFIG_B44 is not set
|
||||
# CONFIG_KS8842 is not set
|
||||
# CONFIG_KS8851_MLL is not set
|
||||
# CONFIG_NETDEV_1000 is not set
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
CONFIG_WLAN=y
|
||||
|
||||
@@ -1044,6 +1044,19 @@ static void __init rk29_board_iomux_init(void)
|
||||
rk29_mux_api_set(GPIO2C6_SPI1TXD_NAME, GPIO2H_SPI1_TXD);
|
||||
rk29_mux_api_set(GPIO2C7_SPI1RXD_NAME, GPIO2H_SPI1_RXD);
|
||||
#endif
|
||||
#ifdef CONFIG_RK29_VMAC
|
||||
rk29_mux_api_set(GPIO4C0_RMIICLKOUT_RMIICLKIN_NAME, GPIO4H_RMII_CLKOUT);
|
||||
rk29_mux_api_set(GPIO4C1_RMIITXEN_MIITXEN_NAME, GPIO4H_RMII_TX_EN);
|
||||
rk29_mux_api_set(GPIO4C2_RMIITXD1_MIITXD1_NAME, GPIO4H_RMII_TXD1);
|
||||
rk29_mux_api_set(GPIO4C3_RMIITXD0_MIITXD0_NAME, GPIO4H_RMII_TXD0);
|
||||
rk29_mux_api_set(GPIO4C4_RMIIRXERR_MIIRXERR_NAME, GPIO4H_RMII_RX_ERR);
|
||||
rk29_mux_api_set(GPIO4C5_RMIICSRDVALID_MIIRXDVALID_NAME, GPIO4H_RMII_CSR_DVALID);
|
||||
rk29_mux_api_set(GPIO4C6_RMIIRXD1_MIIRXD1_NAME, GPIO4H_RMII_RXD1);
|
||||
rk29_mux_api_set(GPIO4C7_RMIIRXD0_MIIRXD0_NAME, GPIO4H_RMII_RXD0);
|
||||
|
||||
rk29_mux_api_set(GPIO0A7_MIIMDCLK_NAME, GPIO0L_MII_MDCLK);
|
||||
rk29_mux_api_set(GPIO0A6_MIIMD_NAME, GPIO0L_MII_MD);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
@@ -1106,6 +1119,9 @@ static struct platform_device *devices[] __initdata = {
|
||||
#ifdef CONFIG_BACKLIGHT_RK29_BL
|
||||
&rk29_device_backlight,
|
||||
#endif
|
||||
#ifdef CONFIG_RK29_VMAC
|
||||
&rk29_device_vmac,
|
||||
#endif
|
||||
#ifdef CONFIG_VIVANTE
|
||||
&rk29_device_gpu,
|
||||
#endif
|
||||
@@ -1126,6 +1142,74 @@ static struct platform_device *devices[] __initdata = {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* spi devices
|
||||
* author: cmc@rock-chips.com
|
||||
*****************************************************************************************/
|
||||
static int rk29_vmac_register_set(void)
|
||||
{
|
||||
//config rk29 vmac as rmii, 100MHz
|
||||
u32 value= readl(RK29_GRF_BASE + 0xbc);
|
||||
value = (value & 0xfff7ff) | (0x400);
|
||||
writel(value, RK29_GRF_BASE + 0xbc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk29_rmii_io_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
//set dm9161 rmii
|
||||
rk29_mux_api_set(GPIO2D3_I2S0SDI_MIICOL_NAME, GPIO2H_GPIO2D3);
|
||||
err = gpio_request(RK29_PIN2_PD3, "rmii");
|
||||
if (err) {
|
||||
gpio_free(RK29_PIN2_PD3);
|
||||
printk("-------request RK29_PIN2_PD3 fail--------\n");
|
||||
return -1;
|
||||
}
|
||||
gpio_direction_output(RK29_PIN2_PD3, GPIO_HIGH);
|
||||
gpio_set_value(RK29_PIN2_PD3, GPIO_HIGH);
|
||||
|
||||
//rmii power on
|
||||
err = gpio_request(RK29_PIN6_PB0, "rmii_power_en");
|
||||
if (err) {
|
||||
gpio_free(RK29_PIN6_PB0);
|
||||
gpio_free(RK29_PIN2_PD3);
|
||||
printk("-------request RK29_PIN6_PB0 fail--------\n");
|
||||
return -1;
|
||||
}
|
||||
gpio_direction_output(RK29_PIN6_PB0, GPIO_HIGH);
|
||||
gpio_set_value(RK29_PIN6_PB0, GPIO_HIGH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk29_rmii_power_control(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
//set dm9161 as rmii
|
||||
gpio_direction_output(RK29_PIN2_PD3, GPIO_HIGH);
|
||||
gpio_set_value(RK29_PIN2_PD3, GPIO_HIGH);
|
||||
|
||||
//enable rmii power
|
||||
gpio_direction_output(RK29_PIN6_PB0, GPIO_HIGH);
|
||||
gpio_set_value(RK29_PIN6_PB0, GPIO_HIGH);
|
||||
|
||||
}
|
||||
else {
|
||||
gpio_direction_output(RK29_PIN6_PB0, GPIO_LOW);
|
||||
gpio_set_value(RK29_PIN6_PB0, GPIO_LOW);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rk29_vmac_platform_data rk29_vmac_pdata = {
|
||||
.vmac_register_set = rk29_vmac_register_set,
|
||||
.rmii_io_init = rk29_rmii_io_init,
|
||||
.rmii_power_control = rk29_rmii_power_control,
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* spi devices
|
||||
* author: cmc@rock-chips.com
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/android_composite.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/rk29_iomap.h>
|
||||
#include <mach/rk29-dma-pl330.h>
|
||||
@@ -46,6 +47,36 @@ struct platform_device rk29_device_adc = {
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RK29_VMAC
|
||||
static u64 eth_dmamask = DMA_BIT_MASK(32);
|
||||
static struct resource rk29_vmac_resource[] = {
|
||||
[0] = {
|
||||
.start = RK29_MAC_PHYS,
|
||||
.end = RK29_MAC_PHYS + RK29_MAC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_MAC,
|
||||
.end = IRQ_MAC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct platform_device rk29_device_vmac = {
|
||||
.name = "rk29 vmac",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = ð_dmamask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = &rk29_vmac_pdata,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(rk29_vmac_resource),
|
||||
.resource = rk29_vmac_resource,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_RK29
|
||||
static struct resource resources_i2c0[] = {
|
||||
{
|
||||
|
||||
@@ -47,11 +47,13 @@ extern struct rk29_sdmmc_platform_data default_sdmmc1_data;
|
||||
extern struct platform_device rk29_device_sdmmc0;
|
||||
extern struct platform_device rk29_device_sdmmc1;
|
||||
extern struct platform_device rk29_device_adc;
|
||||
extern struct platform_device rk29_device_vmac;
|
||||
extern struct rk29_bl_info rk29_bl_info;
|
||||
extern struct platform_device rk29_device_backlight;
|
||||
extern struct platform_device rk29_device_dwc_otg;
|
||||
extern struct platform_device android_usb_device;
|
||||
extern struct usb_mass_storage_platform_data mass_storage_pdata;
|
||||
extern struct platform_device usb_mass_storage_device;
|
||||
|
||||
extern struct platform_device rk29_device_vmac;
|
||||
extern struct rk29_vmac_platform_data rk29_vmac_pdata;
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,13 @@ struct rk29xx_spi_platform_data {
|
||||
u16 num_chipselect;
|
||||
};
|
||||
|
||||
/*vmac*/
|
||||
struct rk29_vmac_platform_data {
|
||||
int (*vmac_register_set)(void);
|
||||
int (*rmii_io_init)(void);
|
||||
int (*rmii_power_control)(int enable);
|
||||
};
|
||||
|
||||
#define INVALID_GPIO -1
|
||||
|
||||
struct rk29lcd_info{
|
||||
|
||||
@@ -236,6 +236,16 @@ config AX88796_93CX6
|
||||
help
|
||||
Select this if your platform comes with an external 93CX6 eeprom.
|
||||
|
||||
config RK29_VMAC
|
||||
tristate "RK29 VMAC ethernet support"
|
||||
depends on HAS_DMA
|
||||
select MII
|
||||
select PHYLIB
|
||||
select CRC32
|
||||
help
|
||||
MAC device present on rockchip rk29xx
|
||||
|
||||
|
||||
config MACE
|
||||
tristate "MACE (Power Mac ethernet) support"
|
||||
depends on PPC_PMAC && PPC32
|
||||
|
||||
@@ -132,6 +132,7 @@ obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
|
||||
obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
|
||||
obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
|
||||
obj-$(CONFIG_E2100) += e2100.o 8390.o
|
||||
obj-$(CONFIG_RK29_VMAC) += rk29_vmac.o
|
||||
obj-$(CONFIG_ES3210) += es3210.o 8390.o
|
||||
obj-$(CONFIG_LNE390) += lne390.o 8390.o
|
||||
obj-$(CONFIG_NE3210) += ne3210.o 8390.o
|
||||
|
||||
1464
drivers/net/rk29_vmac.c
Executable file
1464
drivers/net/rk29_vmac.c
Executable file
File diff suppressed because it is too large
Load Diff
268
drivers/net/rk29_vmac.h
Executable file
268
drivers/net/rk29_vmac.h
Executable file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* linux/arch/arc/drivers/arcvmac.h
|
||||
*
|
||||
* Copyright (C) 2003-2006 Codito Technologies, for linux-2.4 port
|
||||
* Copyright (C) 2006-2007 Celunite Inc, for linux-2.6 port
|
||||
* Copyright (C) 2007-2008 Sagem Communications, Fehmi HAFSI
|
||||
* Copyright (C) 2009 Sagem Communications, Andreas Fenkart
|
||||
* All Rights Reserved.
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
* Authors: amit.bhor@celunite.com, sameer.dhavale@celunite.com
|
||||
*/
|
||||
|
||||
#ifndef _ARCVMAC_H
|
||||
#define _ARCVMAC_H
|
||||
|
||||
#define VMAC_NAME "rk29 vmac"
|
||||
#define VMAC_VERSION "1.0"
|
||||
|
||||
/* Buffer descriptors */
|
||||
#define TX_BDT_LEN 16 /* Number of receive BD's */
|
||||
#define RX_BDT_LEN 255 /* Number of transmit BD's */
|
||||
|
||||
/* BD poll rate, in 1024 cycles. @100Mhz: x * 1024 cy * 10ns = 1ms */
|
||||
#define POLLRATE_TIME 200
|
||||
|
||||
/* next power of two, bigger than ETH_FRAME_LEN + VLAN */
|
||||
#define MAX_RX_BUFFER_LEN 0x800 /* 2^11 = 2048 = 0x800 */
|
||||
#define MAX_TX_BUFFER_LEN 0x800 /* 2^11 = 2048 = 0x800 */
|
||||
|
||||
/* 14 bytes of ethernet header, 4 bytes VLAN, FCS,
|
||||
* plus extra pad to prevent buffer chaining of
|
||||
* maximum sized ethernet packets (1514 bytes) */
|
||||
#define VMAC_BUFFER_PAD (ETH_HLEN + 4 + ETH_FCS_LEN + 4)
|
||||
|
||||
/* VMAC register definitions, offsets in the ref manual are in bytes */
|
||||
#define ID_OFFSET (0x00/0x4)
|
||||
#define STAT_OFFSET (0x04/0x4)
|
||||
#define ENABLE_OFFSET (0x08/0x4)
|
||||
#define CONTROL_OFFSET (0x0c/0x4)
|
||||
#define POLLRATE_OFFSET (0x10/0x4)
|
||||
#define RXERR_OFFSET (0x14/0x4)
|
||||
#define MISS_OFFSET (0x18/0x4)
|
||||
#define TXRINGPTR_OFFSET (0x1c/0x4)
|
||||
#define RXRINGPTR_OFFSET (0x20/0x4)
|
||||
#define ADDRL_OFFSET (0x24/0x4)
|
||||
#define ADDRH_OFFSET (0x28/0x4)
|
||||
#define LAFL_OFFSET (0x2c/0x4)
|
||||
#define LAFH_OFFSET (0x30/0x4)
|
||||
#define MDIO_DATA_OFFSET (0x34/0x4)
|
||||
#define MAC_TXRING_HEAD_OFFSET (0x38/0x4)
|
||||
#define MAC_RXRING_HEAD_OFFSET (0x3C/0x4)
|
||||
|
||||
/* STATUS and ENABLE register bit masks */
|
||||
#define TXINT_MASK (1<<0) /* Transmit interrupt */
|
||||
#define RXINT_MASK (1<<1) /* Receive interrupt */
|
||||
#define ERR_MASK (1<<2) /* Error interrupt */
|
||||
#define TXCH_MASK (1<<3) /* Transmit chaining error interrupt */
|
||||
#define MSER_MASK (1<<4) /* Missed packet counter error */
|
||||
#define RXCR_MASK (1<<8) /* RXCRCERR counter rolled over */
|
||||
#define RXFR_MASK (1<<9) /* RXFRAMEERR counter rolled over */
|
||||
#define RXFL_MASK (1<<10) /* RXOFLOWERR counter rolled over */
|
||||
#define MDIO_MASK (1<<12) /* MDIO complete */
|
||||
#define TXPL_MASK (1<<31) /* TXPOLL */
|
||||
|
||||
/* CONTROL register bitmasks */
|
||||
#define EN_MASK (1<<0) /* VMAC enable */
|
||||
#define TXRN_MASK (1<<3) /* TX enable */
|
||||
#define RXRN_MASK (1<<4) /* RX enable */
|
||||
#define DSBC_MASK (1<<8) /* Disable receive broadcast */
|
||||
#define ENFL_MASK (1<<10) /* Enable Full Duplex */ ///////
|
||||
#define PROM_MASK (1<<11) /* Promiscuous mode */
|
||||
|
||||
/* RXERR register bitmasks */
|
||||
#define RXERR_CRC 0x000000ff
|
||||
#define RXERR_FRM 0x0000ff00
|
||||
#define RXERR_OFLO 0x00ff0000 /* fifo overflow */
|
||||
|
||||
/* MDIO data register bit masks */
|
||||
#define MDIO_SFD 0xC0000000
|
||||
#define MDIO_OP 0x30000000
|
||||
#define MDIO_ID_MASK 0x0F800000
|
||||
#define MDIO_REG_MASK 0x007C0000
|
||||
#define MDIO_TA 0x00030000
|
||||
#define MDIO_DATA_MASK 0x0000FFFF
|
||||
|
||||
#define MDIO_BASE 0x40020000
|
||||
#define MDIO_OP_READ 0x20000000
|
||||
#define MDIO_OP_WRITE 0x10000000
|
||||
|
||||
/* Buffer descriptor INFO bit masks */
|
||||
#define OWN_MASK (1<<31) /* ownership of buffer, 0 CPU, 1 DMA */
|
||||
#define BUFF (1<<30) /* buffer invalid, rx */
|
||||
#define UFLO (1<<29) /* underflow, tx */
|
||||
#define LTCL (1<<28) /* late collision, tx */
|
||||
#define RETRY_CT (0xf<<24) /* tx */
|
||||
#define DROP (1<<23) /* drop, more than 16 retries, tx */
|
||||
#define DEFER (1<<22) /* traffic on the wire, tx */
|
||||
#define CARLOSS (1<<21) /* carrier loss while transmission, tx, rx? */
|
||||
/* 20:19 reserved */
|
||||
#define ADCR (1<<18) /* add crc, ignored if not disaddcrc */
|
||||
#define LAST_MASK (1<<17) /* Last buffer in chain */
|
||||
#define FRST_MASK (1<<16) /* First buffer in chain */
|
||||
/* 15:11 reserved */
|
||||
#define LEN_MASK 0x000007FF
|
||||
|
||||
#define ERR_MSK_TX 0x3fe00000 /* UFLO | LTCL | RTRY | DROP | DEFER | CRLS */
|
||||
|
||||
|
||||
/* arcvmac private data structures */
|
||||
struct vmac_buffer_desc {
|
||||
unsigned int info;
|
||||
dma_addr_t data;
|
||||
};
|
||||
|
||||
struct dma_fifo {
|
||||
int head; /* head */
|
||||
int tail; /* tail */
|
||||
int size;
|
||||
};
|
||||
|
||||
struct vmac_priv {
|
||||
struct net_device *dev;
|
||||
struct platform_device *pdev;
|
||||
struct net_device_stats stats;
|
||||
|
||||
spinlock_t lock; /* TODO revisit */
|
||||
struct completion mdio_complete;
|
||||
|
||||
/* base address of register set */
|
||||
int *regs;
|
||||
unsigned int mem_base;
|
||||
|
||||
/* DMA ring buffers */
|
||||
struct vmac_buffer_desc *rxbd;
|
||||
dma_addr_t rxbd_dma;
|
||||
|
||||
struct vmac_buffer_desc *txbd;
|
||||
dma_addr_t txbd_dma;
|
||||
|
||||
/* socket buffers */
|
||||
struct sk_buff *rx_skbuff[RX_BDT_LEN];
|
||||
struct sk_buff *tx_skbuff[TX_BDT_LEN];
|
||||
int rx_skb_size;
|
||||
|
||||
/* skb / dma desc managing */
|
||||
struct dma_fifo rx_ring;
|
||||
struct dma_fifo tx_ring;
|
||||
|
||||
/* descriptor last polled/processed by the VMAC */
|
||||
unsigned long mac_rxring_head;
|
||||
/* used when rx skb allocation failed, so we defer rx queue
|
||||
* refill */
|
||||
struct timer_list rx_timeout;
|
||||
|
||||
/* lock rx_timeout against rx normal operation */
|
||||
spinlock_t rx_lock;
|
||||
|
||||
struct napi_struct napi;
|
||||
|
||||
/* rx buffer chaining */
|
||||
int rx_merge_error;
|
||||
int tx_timeout_error;
|
||||
|
||||
/* PHY stuff */
|
||||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phy_dev;
|
||||
|
||||
int link;
|
||||
int speed;
|
||||
int duplex;
|
||||
|
||||
/* debug */
|
||||
int shutdown;
|
||||
};
|
||||
|
||||
/* DMA ring management */
|
||||
|
||||
/* for a fifo with size n,
|
||||
* - [0..n] fill levels are n + 1 states
|
||||
* - there are only n different deltas (head - tail) values
|
||||
* => not all fill levels can be represented with head, tail
|
||||
* pointers only
|
||||
* we give up the n fill level, aka fifo full */
|
||||
|
||||
/* sacrifice one elt as a sentinel */
|
||||
static inline int fifo_used(struct dma_fifo *f);
|
||||
static inline int fifo_inc_ct(int ct, int size);
|
||||
static inline void fifo_dump(struct dma_fifo *fifo);
|
||||
|
||||
static inline int fifo_empty(struct dma_fifo *f)
|
||||
{
|
||||
return (f->head == f->tail);
|
||||
}
|
||||
|
||||
static inline int fifo_free(struct dma_fifo *f)
|
||||
{
|
||||
int free;
|
||||
|
||||
free = f->tail - f->head;
|
||||
if (free <= 0)
|
||||
free += f->size;
|
||||
|
||||
return free;
|
||||
}
|
||||
|
||||
static inline int fifo_used(struct dma_fifo *f)
|
||||
{
|
||||
int used;
|
||||
|
||||
used = f->head - f->tail;
|
||||
if (used < 0)
|
||||
used += f->size;
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
static inline int fifo_full(struct dma_fifo *f)
|
||||
{
|
||||
return (fifo_used(f) + 1) == f->size;
|
||||
}
|
||||
|
||||
/* manipulate */
|
||||
static inline void fifo_init(struct dma_fifo *fifo, int size)
|
||||
{
|
||||
fifo->size = size;
|
||||
fifo->head = fifo->tail = 0; /* empty */
|
||||
}
|
||||
|
||||
static inline void fifo_inc_head(struct dma_fifo *fifo)
|
||||
{
|
||||
BUG_ON(fifo_full(fifo));
|
||||
fifo->head = fifo_inc_ct(fifo->head, fifo->size);
|
||||
}
|
||||
|
||||
static inline void fifo_inc_tail(struct dma_fifo *fifo)
|
||||
{
|
||||
BUG_ON(fifo_empty(fifo));
|
||||
fifo->tail = fifo_inc_ct(fifo->tail, fifo->size);
|
||||
}
|
||||
|
||||
/* internal funcs */
|
||||
static inline void fifo_dump(struct dma_fifo *fifo)
|
||||
{
|
||||
printk(KERN_INFO "fifo: head %d, tail %d, size %d\n", fifo->head,
|
||||
fifo->tail,
|
||||
fifo->size);
|
||||
}
|
||||
|
||||
static inline int fifo_inc_ct(int ct, int size)
|
||||
{
|
||||
return (++ct == size) ? 0 : ct;
|
||||
}
|
||||
|
||||
#endif /* _ARCVMAC_H */
|
||||
Reference in New Issue
Block a user