Add preliminary support for the Routerboard 153 CF slot (#2550)
[openwrt/svn-archive/archive.git] / target / linux / adm5120 / files / drivers / block / rb1xx / ata.h
1 /* CF-mips driver
2 This is a block driver for the direct (mmaped) interface to the CF-slot,
3 found in Routerboard.com's RB532 board
4 See SDK provided from routerboard.com.
5
6 Module adapted By P.Christeas <p_christeas@yahoo.com>, 2005-6.
7 Cleaned up and adapted to platform_device by Felix Fietkau <nbd@openwrt.org>
8
9 This work is redistributed under the terms of the GNU General Public License.
10 */
11
12 #ifndef __CFMIPS_ATA_H__
13 #define __CFMIPS_ATA_H__
14
15 #include <linux/interrupt.h>
16
17 #define CFG_DC_DEV1 (void*)0xb8010010
18 #define CFG_DC_DEVBASE 0x0
19 #define CFG_DC_DEVMASK 0x4
20 #define CFG_DC_DEVC 0x8
21 #define CFG_DC_DEVTC 0xC
22
23 #define CFDEV_BUF_SIZE 0x1000
24 #define ATA_CIS_OFFSET 0x200
25 #define ATA_REG_OFFSET 0x800
26 #define ATA_DBUF_OFFSET 0xC00
27
28 #define ATA_REG_FEAT 0x1
29 #define ATA_REG_SC 0x2
30 #define ATA_REG_SN 0x3
31 #define ATA_REG_CL 0x4
32 #define ATA_REG_CH 0x5
33 #define ATA_REG_DH 0x6
34 #define ATA_REG_DH_BASE 0xa0
35 #define ATA_REG_DH_LBA 0x40
36 #define ATA_REG_DH_DRV 0x10
37 #define ATA_REG_CMD 0x7
38 #define ATA_REG_ST 0x7
39 #define ATA_REG_ST_BUSY 0x80
40 #define ATA_REG_ST_RDY 0x40
41 #define ATA_REG_ST_DWF 0x20
42 #define ATA_REG_ST_DSC 0x10
43 #define ATA_REG_ST_DRQ 0x08
44 #define ATA_REG_ST_CORR 0x04
45 #define ATA_REG_ST_ERR 0x01
46 #define ATA_REG_ERR 0xd
47 #define ATA_REG_DC 0xe
48 #define ATA_REG_DC_IEN 0x02
49 #define ATA_REG_DC_SRST 0x04
50
51 #define ATA_CMD_READ_SECTORS 0x20
52 #define ATA_CMD_WRITE_SECTORS 0x30
53 #define ATA_CMD_EXEC_DRIVE_DIAG 0x90
54 #define ATA_CMD_READ_MULTIPLE 0xC4
55 #define ATA_CMD_WRITE_MULTIPLE 0xC5
56 #define ATA_CMD_SET_MULTIPLE 0xC6
57 #define ATA_CMD_IDENTIFY_DRIVE 0xEC
58 #define ATA_CMD_SET_FEATURES 0xEF
59
60 #define ATA_FEATURE_ENABLE_APM 0x05
61 #define ATA_FEATURE_DISABLE_APM 0x85
62 #define ATA_APM_DISABLED 0x00
63 #define ATA_APM_MIN_POWER 0x01
64 #define ATA_APM_WITH_STANDBY 0x7f
65 #define ATA_APM_WITHOUT_STANDBY 0x80
66 #define ATA_APM_MAX_PERFORMANCE 0xfe
67
68 #define CF_SECT_SIZE 0x200
69 /* That is the ratio CF_SECT_SIZE/512 (the kernel sector size) */
70 #define CF_KERNEL_MUL 1
71 #define ATA_MAX_SECT_PER_CMD 0x100
72
73 #define CF_TRANS_FAILED 0
74 #define CF_TRANS_OK 1
75 #define CF_TRANS_IN_PROGRESS 2
76
77
78 enum trans_state {
79 TS_IDLE = 0,
80 TS_AFTER_RESET,
81 TS_READY,
82 TS_CMD,
83 TS_TRANS
84 };
85
86 //
87 // #if DEBUG
88 // static unsigned long busy_time;
89 // #endif
90
91 /** Struct to hold the cfdev
92 Actually, all the data here only has one instance. However, for
93 reasons of programming conformity, it is passed around as a pointer
94 */
95 struct cf_mips_dev {
96 void *base; /* base address for I/O */
97 void *baddr; /* remapped address */
98
99 int pin; /* gpio pin */
100 int irq; /* gpio irq */
101
102 unsigned head;
103 unsigned cyl;
104 unsigned spt;
105 unsigned sectors;
106
107 unsigned short block_size;
108 unsigned dtype ; // ATA or CF
109 struct request_queue *queue;
110 struct gendisk *gd;
111
112 /* Transaction state */
113 enum trans_state tstate;
114 char *tbuf;
115 unsigned long tbuf_size;
116 sector_t tsect_start;
117 unsigned tsector_count;
118 unsigned tsectors_left;
119 int tread;
120 unsigned tcmd;
121 int async_mode;
122 unsigned long irq_enable_time;
123
124 struct request *active_req; /* A request is being carried out. Is that different from tstate? */
125 int users;
126 struct timer_list to_timer;
127 struct tasklet_struct tasklet;
128
129 /** This lock ensures that the requests to this device are all done
130 atomically. Transfers can run in parallel, requests are all queued
131 one-by-one */
132 spinlock_t lock;
133 };
134
135 int cf_do_transfer(struct cf_mips_dev* dev,sector_t sector, unsigned long nsect,
136 char* buffer, int is_write);
137 int cf_init(struct cf_mips_dev* dev);
138 void cf_cleanup(struct cf_mips_dev* dev);
139
140 void cf_async_trans_done(struct cf_mips_dev* dev, int result);
141 // void *cf_get_next_buf(unsigned long *buf_size);
142
143 #endif