15d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda/*
25d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * R8A66597 HCD (Host Controller Driver)
35d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
45d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Copyright (C) 2006-2007 Renesas Solutions Corp.
55d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Portions Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
65d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Portions Copyright (C) 2004-2005 David Brownell
75d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Portions Copyright (C) 1999 Roman Weissgaerber
85d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
95d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
105d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
115d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * This program is free software; you can redistribute it and/or modify
125d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * it under the terms of the GNU General Public License as published by
135d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * the Free Software Foundation; version 2 of the License.
145d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
155d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * This program is distributed in the hope that it will be useful,
165d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * but WITHOUT ANY WARRANTY; without even the implied warranty of
175d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
185d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * GNU General Public License for more details.
195d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
205d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * You should have received a copy of the GNU General Public License
215d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * along with this program; if not, write to the Free Software
225d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
235d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda *
245d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda */
255d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
265d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#ifndef __R8A66597_H__
275d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define __R8A66597_H__
285d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
29765786e0aead7faf6c333176d22948c6f155fff1Magnus Damm#include <linux/clk.h>
305effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda#include <linux/usb/r8a66597.h>
315effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda
325d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_MAX_NUM_PIPE		10
335d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_BUF_BSIZE		8
345d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_MAX_DEVICE		10
355d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_MAX_ROOT_HUB		2
3629fab0cd897519be9009ba8c898410ab83b378e9Yoshihiro Shimoda#define R8A66597_MAX_SAMPLING		5
3729fab0cd897519be9009ba8c898410ab83b378e9Yoshihiro Shimoda#define R8A66597_RH_POLL_TIME		10
385d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_MAX_DMA_CHANNEL	2
395d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define R8A66597_PIPE_NO_DMA		R8A66597_MAX_DMA_CHANNEL
405d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define check_bulk_or_isoc(pipenum)	((pipenum >= 1 && pipenum <= 5))
415d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define check_interrupt(pipenum)	((pipenum >= 6 && pipenum <= 9))
425d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define make_devsel(addr)		(addr << 12)
435d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
445d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597_pipe_info {
456d8791076c7742c65dd796ae0ac260ab22e85517Yoshihiro Shimoda	unsigned long timer_interval;
46e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 pipenum;
47dc0d5c1e5c7532e800fff6e313cd4af44af99976Joe Perches	u16 address;	/* R8A66597 HCD usb address */
48e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 epnum;
49e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 maxpacket;
50e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 type;
51e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 bufnum;
52e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 buf_bsize;
53e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 interval;
54e294531dc9f2c1f5291373dcdd5013c0cdcbdee2Yoshihiro Shimoda	u16 dir_in;
555d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
565d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
575d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597_pipe {
585d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_pipe_info info;
595d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
605d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long fifoaddr;
615d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long fifosel;
625d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long fifoctr;
635d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long pipectr;
645d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long pipetre;
655d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long pipetrn;
665d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
675d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
685d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597_td {
695d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_pipe *pipe;
705d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct urb *urb;
715d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct list_head queue;
725d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
735d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16 type;
745d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16 pipenum;
755d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	int iso_cnt;
765d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
775d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16 address;		/* R8A66597's USB address */
785d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16 maxpacket;
795d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
805d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned zero_packet:1;
815d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned short_packet:1;
825d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned set_address:1;
835d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
845d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
855d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597_device {
865d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16	address;	/* R8A66597's USB address */
875d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16	hub_port;
885d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16	root_port;
895d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
905d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned short ep_in_toggle;
915d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned short ep_out_toggle;
925d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
935d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned char dma_map;
945d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
955d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	enum usb_device_state state;
965d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
975d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct usb_device *udev;
985d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	int usb_address;
995d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct list_head device_list;
1005d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
1015d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1025d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597_root_hub {
1035d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u32 port;
1045d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	u16 old_syssts;
1055d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	int scount;
1065d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1075d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_device	*dev;
1085d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
1095d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1105d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastruct r8a66597 {
1115d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	spinlock_t lock;
1121c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt	void __iomem *reg;
113765786e0aead7faf6c333176d22948c6f155fff1Magnus Damm	struct clk *clk;
1145effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	struct r8a66597_platdata	*pdata;
1155d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_device		device0;
1165d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_root_hub	root_hub[R8A66597_MAX_ROOT_HUB];
1175d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct list_head		pipe_queue[R8A66597_MAX_NUM_PIPE];
1185d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1195d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct timer_list rh_timer;
1205d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct timer_list td_timer[R8A66597_MAX_NUM_PIPE];
1216d8791076c7742c65dd796ae0ac260ab22e85517Yoshihiro Shimoda	struct timer_list interval_timer[R8A66597_MAX_NUM_PIPE];
1225d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1235d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned short address_map;
1245d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned short timeout_map;
1256d8791076c7742c65dd796ae0ac260ab22e85517Yoshihiro Shimoda	unsigned short interval_map;
1265d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
1275d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned char dma_map;
128719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm	unsigned int max_root_hub;
1295d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1305d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct list_head child_device;
1315d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long child_connect_map[4];
132e1e609be49c9d345e8b67a122a7cdae48ad27c7eYoshihiro Shimoda
133e1e609be49c9d345e8b67a122a7cdae48ad27c7eYoshihiro Shimoda	unsigned bus_suspended:1;
1345effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	unsigned irq_sense_low:1;
1355d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda};
1365d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1375d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd)
1385d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1395d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return (struct r8a66597 *)(hcd->hcd_priv);
1405d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1415d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1425d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline struct usb_hcd *r8a66597_to_hcd(struct r8a66597 *r8a66597)
1435d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1445d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return container_of((void *)r8a66597, struct usb_hcd, hcd_priv);
1455d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1465d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1475d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline struct r8a66597_td *r8a66597_get_td(struct r8a66597 *r8a66597,
1485d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda						  u16 pipenum)
1495d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1505d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	if (unlikely(list_empty(&r8a66597->pipe_queue[pipenum])))
1515d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda		return NULL;
1525d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1535d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return list_entry(r8a66597->pipe_queue[pipenum].next,
1545d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda			  struct r8a66597_td, queue);
1555d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1565d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1575d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline struct urb *r8a66597_get_urb(struct r8a66597 *r8a66597,
1585d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda					   u16 pipenum)
1595d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1605d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	struct r8a66597_td *td;
1615d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1625d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	td = r8a66597_get_td(r8a66597, pipenum);
1635d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return (td ? td->urb : NULL);
1645d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1655d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1665d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
1675d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1681c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt	return ioread16(r8a66597->reg + offset);
1695d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1705d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1715d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
1725d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda				      unsigned long offset, u16 *buf,
1735d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda				      int len)
1745d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1751c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt	void __iomem *fifoaddr = r8a66597->reg + offset;
1769424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	unsigned long count;
1779424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda
178719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm	if (r8a66597->pdata->on_chip) {
179719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		count = len / 4;
1801c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt		ioread32_rep(fifoaddr, buf, count);
1819424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda
182719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		if (len & 0x00000003) {
1831c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt			unsigned long tmp = ioread32(fifoaddr);
184719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			memcpy((unsigned char *)buf + count * 4, &tmp,
185719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			       len & 0x03);
186719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		}
187719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm	} else {
188719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		len = (len + 1) / 2;
1891c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt		ioread16_rep(fifoaddr, buf, len);
1909424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	}
1915d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1925d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
1935d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
1945d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda				  unsigned long offset)
1955d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
1961c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt	iowrite16(val, r8a66597->reg + offset);
1975d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
1985d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
199f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimodastatic inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
200f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda				 u16 val, u16 pat, unsigned long offset)
201f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda{
202f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	u16 tmp;
203f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	tmp = r8a66597_read(r8a66597, offset);
204f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	tmp = tmp & (~pat);
205f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	tmp = tmp | val;
206f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	r8a66597_write(r8a66597, tmp, offset);
207f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda}
208f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda
209f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda#define r8a66597_bclr(r8a66597, val, offset)	\
210f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda			r8a66597_mdfy(r8a66597, 0, val, offset)
211f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda#define r8a66597_bset(r8a66597, val, offset)	\
212f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda			r8a66597_mdfy(r8a66597, val, 0, offset)
213f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda
2145d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
215f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda				       struct r8a66597_pipe *pipe, u16 *buf,
2165d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda				       int len)
2175d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
218f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda	void __iomem *fifoaddr = r8a66597->reg + pipe->fifoaddr;
2199424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	unsigned long count;
2209424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	unsigned char *pb;
2219424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	int i;
2229424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda
223719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm	if (r8a66597->pdata->on_chip) {
224719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		count = len / 4;
2251c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt		iowrite32_rep(fifoaddr, buf, count);
226719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm
227719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		if (len & 0x00000003) {
228719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			pb = (unsigned char *)buf + count * 4;
229719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			for (i = 0; i < (len & 0x00000003); i++) {
230719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm				if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
2311c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt					iowrite8(pb[i], fifoaddr + i);
232719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm				else
2331c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt					iowrite8(pb[i], fifoaddr + 3 - i);
234719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			}
235719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		}
236719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm	} else {
237719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		int odd = len & 0x0001;
238719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm
239719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		len = len / 2;
240ac9dfe9cdda4eb42ecaa9f13b0fee518e0b6518eNobuhiro Iwamatsu		iowrite16_rep(fifoaddr, buf, len);
241719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm		if (unlikely(odd)) {
242719a72b7c75bb239ca6184190ab994b71a31c6dcMagnus Damm			buf = &buf[len];
243f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda			if (r8a66597->pdata->wr0_shorted_to_wr1)
244f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda				r8a66597_bclr(r8a66597, MBW_16, pipe->fifosel);
2451c98347e613bf17ea2f18c9766ce0ab77f65a96dPaul Mundt			iowrite8((unsigned char)*buf, fifoaddr);
246f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda			if (r8a66597->pdata->wr0_shorted_to_wr1)
247f2e9039a43b01f01cab9dfaea2cad5f304fb3343Yoshihiro Shimoda				r8a66597_bset(r8a66597, MBW_16, pipe->fifosel);
2489424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda		}
2499424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	}
2505d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2515d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2525d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline unsigned long get_syscfg_reg(int port)
2535d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2545d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return port == 0 ? SYSCFG0 : SYSCFG1;
2555d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2565d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2575d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline unsigned long get_syssts_reg(int port)
2585d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2595d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return port == 0 ? SYSSTS0 : SYSSTS1;
2605d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2615d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2625d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline unsigned long get_dvstctr_reg(int port)
2635d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2645d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return port == 0 ? DVSTCTR0 : DVSTCTR1;
2655d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2665d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2679424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimodastatic inline unsigned long get_dmacfg_reg(int port)
2689424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda{
2699424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda	return port == 0 ? DMA0CFG : DMA1CFG;
2709424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda}
2719424ea29658ce5bcdcf527ddf9617b9507ddf1aaYoshihiro Shimoda
2725d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline unsigned long get_intenb_reg(int port)
2735d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2745d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return port == 0 ? INTENB1 : INTENB2;
2755d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2765d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2775d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline unsigned long get_intsts_reg(int port)
2785d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2795d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return port == 0 ? INTSTS1 : INTSTS2;
2805d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2815d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2825d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline u16 get_rh_usb_speed(struct r8a66597 *r8a66597, int port)
2835d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2845d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long dvstctr_reg = get_dvstctr_reg(port);
2855d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2865d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	return r8a66597_read(r8a66597, dvstctr_reg) & RHST;
2875d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
2885d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2895d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimodastatic inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port,
2905d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda				       int power)
2915d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda{
2925d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	unsigned long dvstctr_reg = get_dvstctr_reg(port);
2935d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
2945effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	if (r8a66597->pdata->port_power) {
2955effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		r8a66597->pdata->port_power(port, power);
2965effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	} else {
2975effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		if (power)
2985effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda			r8a66597_bset(r8a66597, VBOUT, dvstctr_reg);
2995effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		else
3005effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda			r8a66597_bclr(r8a66597, VBOUT, dvstctr_reg);
3015effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	}
3025effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda}
3035effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda
3045effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimodastatic inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
3055effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda{
3065effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	u16 clock = 0;
3075effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda
3085effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	switch (pdata->xtal) {
3095effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_12MHZ:
3105effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		clock = XTAL12;
3115effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		break;
3125effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_24MHZ:
3135effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		clock = XTAL24;
3145effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		break;
3155effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_48MHZ:
3165effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		clock = XTAL48;
3175effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		break;
3185effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	default:
3195effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
3205effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda		break;
3215effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	}
3225effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda
3235effabbe9e6e0089f7afdde35cb51e8c8b4cf6bcYoshihiro Shimoda	return clock;
3245d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda}
3255d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
3265d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define get_pipectr_addr(pipenum)	(PIPE1CTR + (pipenum - 1) * 2)
3275d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define get_pipetre_addr(pipenum)	(PIPE1TRE + (pipenum - 1) * 4)
3285d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define get_pipetrn_addr(pipenum)	(PIPE1TRN + (pipenum - 1) * 4)
3295d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define get_devadd_addr(address)	(DEVADD0 + address * 2)
3305d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
3315d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define enable_irq_ready(r8a66597, pipenum)	\
3325d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, BRDYENB)
3335d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define disable_irq_ready(r8a66597, pipenum)	\
3345d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, BRDYENB)
3355d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define enable_irq_empty(r8a66597, pipenum)	\
3365d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, BEMPENB)
3375d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define disable_irq_empty(r8a66597, pipenum)	\
3385d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, BEMPENB)
3395d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define enable_irq_nrdy(r8a66597, pipenum)	\
3405d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, NRDYENB)
3415d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#define disable_irq_nrdy(r8a66597, pipenum)	\
3425d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, NRDYENB)
3435d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
3445d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda#endif	/* __R8A66597_H__ */
3455d3043586db428b5b4b3df89fa0c2db9731e934cYoshihiro Shimoda
346