OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [drivers/] [ata.c] - Blame information for rev 175

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcus.erl
/*
2
    ata.c -- ATA driver
3
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
4
 
5
    This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
#include <string.h>
23
 
24
/* get prototype for 'printf'
25
   get IN_CLOCK (from 'board.h')
26
*/
27
#include "common.h"
28
#include "ata.h"
29
 
30
 
31
/*
32
  static constants (yuck, yuck, yuck)
33
*/
34
static int usage[2] = {0, 0};
35
static int hardsect_size[2] = {512, 512};
36
static int current_pio_mode = 9999;
37
 
38
/*
39
  local defines
40
*/
41
#define TYPE(devid) (devid >> 4)
42
#define REV(devid)  (devid & 0xf)
43
 
44
#define BASE(inode)    ( (unsigned long) (MAJOR(inode->i_rdev) << 24) )
45
#define DEVICE(inode)  ( MINOR(inode->i_rdev) )
46
 
47
#define IN_CLK_MHZ (IN_CLK / 1000000)
48
#define TO_TICKS(time) ( ((time + (IN_CLK_MHZ >> 1)) / IN_CLK_MHZ) -1 )
49
 
50
 
51
/*
52
       A T A _ O P E N
53
 
54
       opens ata device;
55
       - identifies ata-device-id
56
       - programs ata-host
57
 
58
       MAJOR: atahost identification (base address)
59
       MINOR: atadevice identification (MSB=0: device0, MSB=1: device1)
60
*/
61
int ata_open(struct inode *inode, struct file *filp)
62
{
63
  unsigned int atahost, device;
64
  unsigned short buf[256];
65
  unsigned short dev_pio;
66
  unsigned long sectors;
67
 
68
  char txt[41];
69
 
70
printf( "Checking device-id\n" );
71
  /* check device-id (MINOR number)                                   */
72
  if ( (device = DEVICE(inode)) > 1 )
73
      return EOPENIDEV;
74
 
75
printf( "Searching for hostcontroller: " );
76
  /* get atahost id                                                   */
77
  atahost = ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0);
78
  if (atahost)
79
  {
80
    printf( "OCIDEC-%1d, revision 0x%02X found at 0x%08lX.\n", TYPE(atahost), REV(atahost), BASE(inode) );
81
  }
82
  else
83
  {
84
    printf( "No OCIDEC device found.\n" );
85
    return EOPENIHOST;
86
  }
87
 
88
 
89
  /* check if the host has been opened already                        */
90
  if (!usage[device]++)
91
  {
92
printf( "Opening device for the first time\n" );
93
      /* no, take device out of reset                                 */
94
      ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST);
95
      ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_SW_RST);
96
 
97
      /* program PIO timing registers (set to PIO mode 0)             */
98
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO0);
99
 
100
      /* enable host controller (for old OCIDEC cores)                */
101
      ata_ioctl(inode, filp, ATA_IOCTL_ENABLE_HOST, 0);
102
  }
103
 
104
  /* select requested device                                          */
105
  ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, 0);
106
 
107
printf( "Executing IdentifyDevice command\n" );
108
  /* identify requested ata-devices                                   */
109
  ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
110
 
111
  /* read block from ata-device                                 */
112
  buf[0] = 256;
113
  ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
114
 
115
  /* check if a valid device was found                                */
116
  /* bit 15 in identify_device word0 must be '0',
117
     or be equal to 0x848a (CFA feature set)                          */
118
  if ( (buf[0] & 0x8000) && (buf[0] != 0x848a) )
119
  {
120
    ata_release(inode, filp);
121
    return EOPENNODEV;
122
  }
123
 
124
  /* Then check specific configuration word                           */
125
  if (buf[0] == 0x848a)
126
    printf( "Found CompactFLASH device.\n" );
127
  else
128
    switch(buf[2]) {
129
       case 0x37c8:
130
           /* device does require SET_FEATURES
131
              IDENTIFY_DEVICE response is incomplete                  */
132
       case 0x738c:
133
           /* device does require SET_FEATURES
134
              IDENTIFY_DEVICE response is complete                    */
135
           ata_ioctl(inode, filp, ATA_IOCTL_SET_FEATURES, 0); //FIXME
136
           break;
137
       case 0x8c73:
138
           /* device does not require SET_FEATURES
139
              IDENTIFY_DEVICE response is incomplete                  */
140
       case 0xc837:
141
           /* device does not require SET_FEATURES
142
              IDENTIFY_DEVICE response is complete                    */
143
           break;
144
 
145
       default:
146
           ata_release(inode, filp);
147
           return EOPENNODEV;
148
     }
149
 
150
  /* checks ok                                                        */
151
 
152
  /* display device model, serialnumber, and firmware revision        */
153
  memcpy(txt, &buf[27], 40);
154
  txt[40] = '\0';
155
  printf( "Model       : %s\n", txt );
156
 
157
  memcpy(txt, &buf[10], 20);
158
  txt[20] = '\0';
159
  printf( "Serial      : %s\n", txt );
160
 
161
  memcpy( txt, &buf[23], 8);
162
  txt[8] = '\0';
163
  printf( "Firmware rev: %s\n", txt );
164
 
165
  /* display size in MBytes                                           */
166
  sectors = (buf[61] << 16) | buf[60];
167
  printf( "              %ld MBytes ", sectors >> 11 ); /* assuming 512bytes per sector */
168
 
169
  /* get supported pio modes                                          */
170
  dev_pio = buf[64];
171
 
172
  /* program ocidec timing registers to highest possible pio mode     */
173
  if (dev_pio & PIO4)
174
  {
175
      printf("PIO-4 supported\n");
176
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO4);
177
  }
178
  else if (dev_pio & PIO3)
179
  {
180
      printf("PIO-3 supported\n");
181
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO3);
182
  }
183
  else
184
  {
185
      printf("PIO-2 supported\n");
186
      ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO2);
187
  }
188
 
189
  return 0;
190
}
191
 
192
 
193
/*
194
       A T A _ R E L E A S E
195
 
196
       closes ata device;
197
*/
198
int ata_release(struct inode *inode, struct file *filp)
199
{
200
  /* decrease usage count */
201
  if (!--usage[DEVICE(inode)])
202
  {
203
    /* reset atahost */
204
    ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | ARG_HW_RST);
205
  }
206
 
207
  return 0;
208
}
209
 
210
 
211
/*
212
       A T A _ R E A D _ D P O R T
213
 
214
       closes ata device;
215
*/
216
int ata_read_dport(unsigned long base)
217
{
218
  /* device ready to transfer data ?? */
219
  while ( !ata_dev_datrdy(base) );
220
 
221
  return REG32(base + ATA_DR);
222
}
223
 
224
 
225
/*
226
        A T A _ I O C T L
227
*/
228
int ata_ioctl(struct inode *inode, struct file *filp, unsigned command, unsigned long argument)
229
{
230
    unsigned long base = BASE(inode);
231
 
232
    switch (command)
233
    {
234
        case ATA_IOCTL_ENABLE_HOST:
235
        /* enables the ATA host controller (sets IDE_EN bit)          */
236
        {
237
            REG32(base + ATA_CTRL) |= ATA_IDE_EN;
238
            return 0;
239
        }
240
 
241
 
242
        case ATA_IOCTL_EXEC_CMD:
243
        /* sends a command to the ATA device                          */
244
        {
245
          while( ata_dev_busy(base) ); // wait for device ready
246
          ata_cmd(base) = argument & 0xff;
247
          return 0;
248
        }
249
 
250
 
251
        case ATA_IOCTL_READ:
252
        {
253
          unsigned short *buf_ptr = (short *)argument;
254
          int n, cnt;
255
 
256
          cnt = buf_ptr[0];
257
          for (n=0; n < cnt; n++)
258
          {
259
            while( !ata_dev_datrdy(base) );     // wait for data
260
            *buf_ptr++ = ata_read_dport(base);  // read data
261
          }
262
 
263
          return 0;
264
        }
265
 
266
 
267
        case ATA_IOCTL_IDENTIFY_HOST:
268
        /* reads OCIDEC status register configuration bits            */
269
            return (REG32(base + ATA_STAT) >> 24);
270
 
271
 
272
        case ATA_IOCTL_SELECT_DEVICE:
273
        /* selects ATA device                                         */
274
        {
275
          while( ata_dev_busy(base) ); // wait for device ready
276
 
277
          /* sets the DEV bit in the device/head register             */
278
          if ( DEVICE(inode) )
279
            REG32(base + ATA_DHR) |= ATA_DHR_DEV;  /* select device1  */
280
          else
281
            REG32(base + ATA_DHR) &= ~ATA_DHR_DEV; /* select device0  */
282
 
283
          return 0;
284
        }
285
 
286
 
287
        case ATA_IOCTL_SET_FTE:
288
        {
289
          /* set FTE bits                                             */
290
          if ( MINOR(inode->i_rdev) )
291
            if (argument)
292
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE0;
293
              else
294
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE0;
295
          else
296
            if (argument)
297
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
298
              else
299
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
300
 
301
          return 0;
302
        }
303
 
304
 
305
        case ATA_IOCTL_SET_PIO:
306
        /* programs the PIO timing registers                          */
307
        {
308
          unsigned long timing;
309
          unsigned short buf[256];
310
 
311
          /* do we need to read the identify_device block ??          */
312
          if (argument & (ARG_PIO4 | ARG_PIO3) )
313
          {
314
            /* identify requested ata-devices                         */
315
            ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
316
 
317
            /* read block from ata-device                             */
318
            buf[0] = 256;
319
            ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
320
          }
321
 
322
          /* program register transfer timing registers               */
323
          /* set the slowest pio mode for register transfers          */
324
          if (argument < current_pio_mode)
325
          {
326
            switch (argument)
327
            {
328
              case ARG_PIO4:
329
                if ( (buf[53] & 0x01) && buf[68] )
330
                  timing = ata_calc_pio_timing(buf[68], PIO4_RT1, PIO4_RT2, PIO4_RT4, PIO4_RT2I, PIO4_RT9);
331
                else
332
                  timing = ata_calc_pio_timing(PIO4_RT0, PIO4_RT1, PIO4_RT2, PIO4_RT4, PIO4_RT2I, PIO4_RT9);
333
                break;
334
 
335
              case ARG_PIO3:
336
                if ( (buf[53] & 0x01) && buf[68] )
337
                  timing = ata_calc_pio_timing(buf[68], PIO3_RT1, PIO3_RT2, PIO3_RT4, PIO3_RT2I, PIO3_RT9);
338
                else
339
                  timing = ata_calc_pio_timing(PIO3_RT0, PIO3_RT1, PIO3_RT2, PIO3_RT4, PIO3_RT2I, PIO3_RT9);
340
                break;
341
 
342
              case ARG_PIO2:
343
                timing = ata_calc_pio_timing(PIO2_RT0, PIO2_RT1, PIO2_RT2, PIO2_RT4, PIO2_RT2I, PIO2_RT9);
344
                break;
345
 
346
              case ARG_PIO1:
347
                timing = ata_calc_pio_timing(PIO1_RT0, PIO1_RT1, PIO1_RT2, PIO1_RT4, PIO1_RT2I, PIO1_RT9);
348
                break;
349
 
350
              default: /* PIO mode 0 */
351
                timing = ata_calc_pio_timing(PIO0_RT0, PIO0_RT1, PIO0_RT2, PIO0_RT4, PIO0_RT2I, PIO0_RT9);
352
                break;
353
            }
354
 
355
            /* program IORDY bit                                      */
356
            if (argument & (ARG_PIO4 | ARG_PIO3) )
357
                REG32(base + ATA_CTRL) |= ATA_IORDY;
358
            else
359
                REG32(base + ATA_CTRL) &= ~ATA_IORDY;
360
 
361
            /* program register transfer timing registers             */
362
            REG32(base + ATA_PCTR) = timing;
363
 
364
            current_pio_mode = argument;
365
          }
366
 
367
          /* Program data transfer timing registers                   */
368
          if ( TYPE(ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0)) > 1 )
369
          {
370
            switch (argument)
371
            {
372
              case ARG_PIO4:
373
                if ( (buf[53] & 0x01) && buf[68] )
374
                  timing = ata_calc_pio_timing(buf[68], PIO4_DT1, PIO4_DT2, PIO4_DT4, PIO4_DT2I, PIO4_DT9);
375
                else
376
                  timing = ata_calc_pio_timing(PIO4_DT0, PIO4_DT1, PIO4_DT2, PIO4_DT4, PIO4_DT2I, PIO4_DT9);
377
                break;
378
 
379
              case ARG_PIO3:
380
                if ( (buf[53] & 0x01) && buf[68] )
381
                  timing = ata_calc_pio_timing(buf[68], PIO3_DT1, PIO3_DT2, PIO3_DT4, PIO3_DT2I, PIO3_DT9);
382
                else
383
                  timing = ata_calc_pio_timing(PIO3_DT0, PIO3_DT1, PIO3_DT2, PIO3_DT4, PIO3_DT2I, PIO3_DT9);
384
                break;
385
 
386
              case ARG_PIO2:
387
                timing = ata_calc_pio_timing(PIO2_DT0, PIO2_DT1, PIO2_DT2, PIO2_DT4, PIO2_DT2I, PIO2_DT9);
388
                break;
389
 
390
              case ARG_PIO1:
391
                timing = ata_calc_pio_timing(PIO1_DT0, PIO1_DT1, PIO1_DT2, PIO1_DT4, PIO1_DT2I, PIO1_DT9);
392
                break;
393
 
394
              default: /* PIO mode 0 */
395
                timing = ata_calc_pio_timing(PIO0_DT0, PIO0_DT1, PIO0_DT2, PIO0_DT4, PIO0_DT2I, PIO0_DT9);
396
                break;
397
            }
398
 
399
            /* program data transfer timing registers, set IORDY bit  */
400
            if ( MINOR(inode->i_rdev) )
401
            {
402
              REG32(base + ATA_PFTR1) = timing;
403
 
404
              /* program IORDY bit                                    */
405
              if ( argument & (ARG_PIO4 | ARG_PIO3) )
406
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
407
              else
408
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
409
            }
410
            else
411
            {
412
              REG32(base + ATA_PFTR0) = timing;
413
 
414
              /* program IORDY bit                                    */
415
              if ( argument & (ARG_PIO4 | ARG_PIO3) )
416
                REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
417
              else
418
                REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
419
            }
420
 
421
            /* enable data transfer timing                            */
422
            ata_ioctl(inode, filp, ATA_IOCTL_SET_FTE, 1);
423
          }
424
 
425
          return 0;
426
        }
427
 
428
 
429
        case ATA_IOCTL_SET_RST:
430
        /* sets or clears reset bits                                  */
431
          if (argument & SET)
432
            switch (argument & ~SET) {
433
                case ARG_HW_RST:  /* ata hardware reset               */
434
                    REG32(base + ATA_CTRL) |= ATA_RST;
435
                    return 0;
436
 
437
                case ARG_SW_RST:  /* ata software reset               */
438
                    REG32(base + ATA_DCR) |= ATA_DCR_RST;
439
                    return 0;
440
 
441
                case ARG_DEV_RST: /* ata device reset                 */
442
                    REG32(base + ATA_CR) = DEVICE_RESET;
443
                    return 0;
444
 
445
                default:
446
                    return EIOCTLIARG;
447
            }
448
          else
449
          {
450
            switch(argument & ~SET) {
451
                case ARG_HW_RST:  /* ata hardware reset               */
452
                    REG32(base + ATA_CTRL) &= ~ATA_RST;
453
                    return 0;
454
 
455
                case ARG_SW_RST:  /* ata software reset               */
456
                    REG32(base + ATA_DCR) &= ~ATA_DCR_RST;
457
                    return 0;
458
 
459
                case ARG_DEV_RST: /* ata device reset                 */
460
                    return 0;
461
 
462
                default:
463
                    return EIOCTLIARG;
464
            }
465
          }
466
 
467
 
468
        default:
469
            printf( "FIXME: Unsupported IOCTL call %1d\n", command );
470
            return EINVAL;
471
    }
472
}
473
 
474
 
475
unsigned long ata_calc_pio_timing(short t0, short t1, short t2, short t4, short t2i, short t9)
476
{
477
    int teoc;
478
 
479
    teoc = t0 - t1 - t2;
480
 
481
    if (teoc < 0)
482
      teoc = 0;
483
 
484
    if (t9 > teoc)
485
      teoc = t9;
486
 
487
    if (t2i > teoc)
488
      teoc = t2i;
489
 
490
    t1   = TO_TICKS(t1);
491
    t2   = TO_TICKS(t2);
492
    t4   = TO_TICKS(t4);
493
    teoc = TO_TICKS(teoc);
494
 
495
    return (teoc << ATA_TEOC) | (t4 << ATA_T4) | (t2 << ATA_T2) | (t1 << ATA_T1);
496
}
497
 
498
 
499
/*
500
        A T A _ R E Q U E S T
501
*/
502
int ata_request(struct inode *inode, struct file *filp, struct request *request)
503
{
504
  unsigned int device = MINOR(inode->i_rdev);
505
  unsigned long base = BASE(inode);
506
  unsigned int sector_size;
507
 
508
  /* get the sector size for the current device                       */
509
  sector_size = hardsect_size[device] >> 1;
510
 
511
  /* set the device                                                   */
512
  ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, device);
513
 
514
  /* get the base address                                             */
515
  base = BASE(inode);
516
 
517
  switch (request->cmd) {
518
    case READ:
519
        {
520
            register unsigned long i, n;
521
            register unsigned short rd_data;
522
            register char *buf_ptr;
523
 
524
            /* program ata-device registers                           */
525
            REG32(base + ATA_DHR) = ((request->sector >> 24) & ATA_DHR_H) | ATA_DHR_LBA;
526
            REG32(base + ATA_CHR) = (request->sector >> 16) & 0xff;
527
            REG32(base + ATA_CLR) = (request->sector >> 8) & 0xff;
528
            REG32(base + ATA_SNR) = request->sector & 0xff;
529
 
530
            REG32(base + ATA_SCR) = request->nr_sectors;
531
 
532
            /* send 'read_sector(s)' command                          */
533
            REG32(base + ATA_CR) = READ_SECTORS;
534
 
535
            /* check status & error registers                         */
536
            if ( ata_astatus(base) & ATA_SR_ERR)
537
                return -1;
538
 
539
            /* read data from devices and store it in the buffer      */
540
            buf_ptr = request->buffer;
541
 
542
            for (n=0; n < request->nr_sectors; n++)
543
            for (i=0; i < sector_size; i++)
544
            {
545
                rd_data = ata_read_dport(base);
546
 
547
                /* the data is byte reversed, swap high & low bytes   */
548
                *buf_ptr++ = rd_data;
549
                *buf_ptr++ = rd_data >> 8;
550
            }
551
 
552
            return 0;
553
    }
554
 
555
 
556
    case WRITE:
557
        /* check if device may be written to                          */
558
        if (filp->f_mode & FMODE_WRITE)
559
        {
560
          /* do the write stuff */
561
        }
562
        else
563
          return EINVAL;
564
 
565
 
566
    default:
567
       return EINVAL;
568
  }
569
 
570
  return 0;
571
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.