rockbox/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c
Nicolas Pennequin e2f5f21e5b Give the Gigabeat S bootloader the ability to untar a tarball.
To test a build, use 'make tar' and send the tar to the unit. The bootloader will unarchive it and delete it before loading the main binary.
This is a temporary hack to make testing possible until we have a better way of sending a complete build.
Also enable writing to the disk by disabling the optimised write stubs.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16338 a1c6a512-1295-4272-9138-f99709370657
2008-02-17 23:17:08 +00:00

138 lines
3.5 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Will Robertson
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "kernel.h"
#include "thread.h"
#include "system.h"
#include "power.h"
#include "panic.h"
#include "pcf50606.h"
#include "ata-target.h"
void ata_reset(void)
{
ATA_INTF_CONTROL &= ~ATA_ATA_RST;
sleep(1);
ATA_INTF_CONTROL |= ATA_ATA_RST;
sleep(1);
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
}
/* This function is called before enabling the USB bus */
void ata_enable(bool on)
{
(void)on;
}
bool ata_is_coldstart(void)
{
return true;
}
unsigned long get_pll(bool serial) {
unsigned long mfi, mfn, mfd, pdf, ref_clk;
unsigned long reg = 0, ccmr;
unsigned long long temp;
unsigned int prcs;
ccmr = CLKCTL_CCMR;
prcs = (ccmr & 0x6) >> 1;
if(prcs == 0x1) {
ref_clk = 32768 * 1024;
} else {
ref_clk = 27000000;
}
if(serial) {
reg = CLKCTL_SPCTL;
} else {
if((ccmr & 0x8) == 0)
return ref_clk;
if((ccmr & 0x80) != 0)
return ref_clk;
reg = CLKCTL_MPCTL;
}
pdf = (reg & (0x7 << 26)) >> 26;
mfd = (reg & (0x3FF << 16)) >> 16;
mfi = (reg & (0xF << 10)) >> 10;
mfi = (mfi <= 5) ? 5 : mfi;
mfn = (reg & 0x3FF);
if(mfn < 0x200) {
temp = (unsigned long long)2 *ref_clk * mfn;
temp /= (mfd + 1);
temp = (unsigned long long)2 *ref_clk * mfi + temp;
temp /= (pdf + 1);
} else {
temp = (unsigned long long)2 *ref_clk * (0x400 - mfn);
temp /= (mfd + 1);
temp = (unsigned long long)2 *ref_clk * mfi - temp;
temp /= (pdf + 1);
}
return (unsigned long)temp;
}
unsigned long get_ata_clock(void) {
unsigned long pll, ret_val, hclk, max_pdf, ipg_pdf, mcu_pdf;
max_pdf = (CLKCTL_PDR0 & (0x7 << 3)) >> 3;
ipg_pdf = (CLKCTL_PDR0 & (0x3 << 6)) >> 6;
mcu_pdf = (CLKCTL_PDR0 & 0x7);
if((CLKCTL_PMCR0 & 0xC0000000 ) == 0) {
pll = get_pll(true);
} else {
pll = get_pll(false);
}
hclk = pll/(max_pdf + 1);
ret_val = hclk / (ipg_pdf + 1);
return ret_val;
}
void ata_device_init(void)
{
ATA_INTF_CONTROL |= ATA_ATA_RST; /* Make sure we're not in reset mode */
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
/* Setup the timing for PIO mode */
int T = 1000 * 1000 * 1000 / get_ata_clock();
ATA_TIME_OFF = 3;
ATA_TIME_ON = 3;
ATA_TIME_1 = (T + 70)/T;
ATA_TIME_2W = (T + 290)/T;
ATA_TIME_2R = (T + 290)/T;
ATA_TIME_AX = (T + 50)/T;
ATA_TIME_PIO_RDX = 1;
ATA_TIME_4 = (T + 30)/T;
ATA_TIME_9 = (T + 20)/T;
}
#if 0
#if !defined(BOOTLOADER)
void copy_write_sectors(const unsigned char* buf, int wordcount)
{
(void)buf; (void)wordcount;
}
#endif
#endif