blob: 98363f04d405ccc7cb67a7f6f2244328e0e53ae3 [file] [log] [blame]
Marcoen Hirschbergdd754882006-08-12 08:01:54 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Michael Sevakis25413022008-03-31 04:53:03 +00008 * $Id$
Marcoen Hirschbergdd754882006-08-12 08:01:54 +00009 *
Greg White6eb81e22007-01-04 11:35:09 +000010 * Copyright (C) 2006,2007 by Marcoen Hirschberg
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000011 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000023#include "kernel.h"
Michael Sevakisa05bb262007-04-30 12:54:05 +000024#include "thread.h"
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000025#include "system.h"
26#include "power.h"
Greg White6eb81e22007-01-04 11:35:09 +000027#include "panic.h"
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000028#include "pcf50606.h"
Greg White6eb81e22007-01-04 11:35:09 +000029#include "ata-target.h"
Steve Gotthardtc07814f2007-01-07 06:38:57 +000030#include "backlight-target.h"
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000031
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000032/* ARESET on C7C68300 and RESET on ATA interface (Active Low) */
33#define ATA_RESET_ENABLE GPGDAT &= ~(1 << 10)
34#define ATA_RESET_DISABLE GPGDAT |= (1 << 10)
35
36/* ATA_EN on C7C68300 */
37#define USB_ATA_ENABLE GPBDAT |= (1 << 5)
38#define USB_ATA_DISABLE GPBDAT &= ~(1 << 5)
39
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000040void ata_reset(void)
41{
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000042 ATA_RESET_ENABLE;
Marcoen Hirschberg29536762006-12-29 02:49:12 +000043 sleep(1); /* > 25us */
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000044 ATA_RESET_DISABLE;
Marcoen Hirschberg29536762006-12-29 02:49:12 +000045 sleep(1); /* > 2ms */
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000046}
47
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000048/* This function is called before enabling the USB bus */
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000049void ata_enable(bool on)
50{
Karl Kurbjun173b6112007-05-07 19:34:34 +000051 GPBCON=( GPBCON&~(1<<11) ) | (1<<10); /* Make the pin an output */
52 GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */
Marcoen Hirschberg29536762006-12-29 02:49:12 +000053 if(on)
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000054 USB_ATA_DISABLE;
Marcoen Hirschberg29536762006-12-29 02:49:12 +000055 else
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000056 USB_ATA_ENABLE;
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000057}
58
59bool ata_is_coldstart(void)
60{
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000061 /* Check the pin configuration - return true when pin is unconfigured */
62 return (GPGCON & 0x00300000) == 0;
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000063}
64
65void ata_device_init(void)
66{
Karl Kurbjun60fed9a2007-04-11 05:30:15 +000067 GPGCON=( GPGCON&~(1<<21) ) | (1<<20); /* Make the pin an output */
68 GPGUP |= 1<<10; /* Disable pullup in SOC as we are now driving */
Karl Kurbjun173b6112007-05-07 19:34:34 +000069 /* ATA reset */
70 ATA_RESET_DISABLE; /* Set the pin to disable an active low reset */
Marcoen Hirschbergdd754882006-08-12 08:01:54 +000071}
Greg White6eb81e22007-01-04 11:35:09 +000072
Greg White355be502007-01-13 02:24:15 +000073#if !defined(BOOTLOADER)
Greg White6eb81e22007-01-04 11:35:09 +000074void copy_read_sectors(unsigned char* buf, int wordcount)
75{
Steve Gotthardt93b047f2007-01-08 08:53:36 +000076 __buttonlight_trigger();
Greg White355be502007-01-13 02:24:15 +000077
Greg Whiteebcd7622007-01-06 01:26:36 +000078 /* Unaligned transfer - slow copy */
79 if ( (unsigned long)buf & 1)
80 { /* not 16-bit aligned, copy byte by byte */
81 unsigned short tmp = 0;
82 unsigned char* bufend = buf + wordcount*2;
83 do
84 {
85 tmp = ATA_DATA;
86 *buf++ = tmp & 0xff; /* I assume big endian */
87 *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */
88 } while (buf < bufend); /* tail loop is faster */
89 return;
90 }
Greg White6eb81e22007-01-04 11:35:09 +000091 /* This should never happen, but worth watching for */
92 if(wordcount > (1 << 18))
93 panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!");
Greg White56685052007-01-05 04:17:25 +000094
95//#define GIGABEAT_DEBUG_ATA
Greg White6eb81e22007-01-04 11:35:09 +000096#ifdef GIGABEAT_DEBUG_ATA
Greg Whiteebcd7622007-01-06 01:26:36 +000097 static int line = 0;
98 static char str[256];
99 snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount);
100 lcd_puts(10, line, str);
101 line = (line+1) % 32;
102 lcd_update();
Greg White6eb81e22007-01-04 11:35:09 +0000103#endif
104 /* Reset the channel */
105 DMASKTRIG0 |= 4;
106 /* Wait for DMA controller to be ready */
107 while(DMASKTRIG0 & 0x2)
108 ;
109 while(DSTAT0 & (1 << 20))
110 ;
111 /* Source is ATA_DATA, on AHB Bus, Fixed */
112 DISRC0 = (int) 0x18000000;
113 DISRCC0 = 0x1;
114 /* Dest mapped to physical address, on AHB bus, increment */
Greg White355be502007-01-13 02:24:15 +0000115 DIDST0 = (int) buf;
116 if(DIDST0 < 0x30000000)
117 DIDST0 += 0x30000000;
Greg White6eb81e22007-01-04 11:35:09 +0000118 DIDSTC0 = 0;
119
Michael Sevakisa05bb262007-04-30 12:54:05 +0000120 /* DACK/DREQ Sync to AHB, Whole service, No reload, 16-bit transfers */
121 DCON0 = ((1 << 30) | (1<<27) | (1<<22) | (1<<20)) | wordcount;
Greg White6eb81e22007-01-04 11:35:09 +0000122
123 /* Activate the channel */
124 DMASKTRIG0 = 0x2;
125
Greg Whiteebcd7622007-01-06 01:26:36 +0000126 invalidate_dcache_range((void *)buf, wordcount*2);
Greg White6eb81e22007-01-04 11:35:09 +0000127
128 /* Start DMA */
129 DMASKTRIG0 |= 0x1;
130
131 /* Wait for transfer to complete */
132 while((DSTAT0 & 0x000fffff))
Michael Sevakis27cf6772008-03-25 02:34:12 +0000133 yield();
Greg Whiteebcd7622007-01-06 01:26:36 +0000134 /* Dump cache for the buffer */
Greg White56685052007-01-05 04:17:25 +0000135}
Greg White355be502007-01-13 02:24:15 +0000136#endif