forked from M-Labs/zynq-rs
sdio: move ADMA2_DESCR32_TABLE into SdCard
This commit is contained in:
parent
1586190712
commit
316ea61702
|
@ -14,10 +14,6 @@ pub struct Adma2Desc32 {
|
||||||
address: VolatileCell<u32>,
|
address: VolatileCell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default::default() cannot be used as it is not a constant function...
|
|
||||||
static mut ADMA2_DESCR32_TABLE: MaybeUninit<[Adma2Desc32; 32]> = MaybeUninit::uninit();
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
const DESC_MAX_LENGTH: u32 = 65536;
|
const DESC_MAX_LENGTH: u32 = 65536;
|
||||||
|
|
||||||
register!(desc32_attribute, Desc32Attribute, VolatileCell, u16);
|
register!(desc32_attribute, Desc32Attribute, VolatileCell, u16);
|
||||||
|
@ -26,45 +22,53 @@ register_bit!(desc32_attribute, int, 2);
|
||||||
register_bit!(desc32_attribute, end, 1);
|
register_bit!(desc32_attribute, end, 1);
|
||||||
register_bit!(desc32_attribute, valid, 0);
|
register_bit!(desc32_attribute, valid, 0);
|
||||||
|
|
||||||
/// Initialize `ADMA2_DESCR32_TABLE` and setup `adma_system_address`
|
pub struct Adma2DescTable(MaybeUninit<[Adma2Desc32; 32]>);
|
||||||
pub fn setup_adma2_descr32(sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) {
|
|
||||||
let descr_table = unsafe { &mut *ADMA2_DESCR32_TABLE.as_mut_ptr() };
|
|
||||||
let blk_size = sdio
|
|
||||||
.regs
|
|
||||||
.block_size_block_count
|
|
||||||
.read()
|
|
||||||
.transfer_block_size() as u32;
|
|
||||||
|
|
||||||
let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH {
|
impl Adma2DescTable {
|
||||||
1
|
pub fn new() -> Self {
|
||||||
} else {
|
Adma2DescTable(MaybeUninit::uninit())
|
||||||
blk_size * blk_cnt / DESC_MAX_LENGTH
|
}
|
||||||
+ if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
} as usize;
|
|
||||||
|
|
||||||
let ptr = buffer.as_ptr() as u32;
|
/// Initialize the table and setup `adma_system_address`
|
||||||
for desc_num in 0..total_desc_lines {
|
pub fn setup(&mut self, sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) {
|
||||||
descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH);
|
let descr_table = unsafe { &mut *self.0.as_mut_ptr() };
|
||||||
descr_table[desc_num].attribute.write(
|
let blk_size = sdio
|
||||||
Desc32Attribute::zeroed()
|
.regs
|
||||||
.trans(true)
|
.block_size_block_count
|
||||||
.valid(true)
|
.read()
|
||||||
|
.transfer_block_size() as u32;
|
||||||
|
|
||||||
|
let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
blk_size * blk_cnt / DESC_MAX_LENGTH
|
||||||
|
+ if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
} as usize;
|
||||||
|
|
||||||
|
let ptr = buffer.as_ptr() as u32;
|
||||||
|
for desc_num in 0..total_desc_lines {
|
||||||
|
descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH);
|
||||||
|
descr_table[desc_num].attribute.write(
|
||||||
|
Desc32Attribute::zeroed()
|
||||||
|
.trans(true)
|
||||||
|
.valid(true)
|
||||||
|
);
|
||||||
|
// 0 is the max length (65536)
|
||||||
|
descr_table[desc_num].length.set(0);
|
||||||
|
}
|
||||||
|
descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true));
|
||||||
|
descr_table[total_desc_lines - 1].length.set(
|
||||||
|
(blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16,
|
||||||
);
|
);
|
||||||
// 0 is the max length (65536)
|
unsafe {
|
||||||
descr_table[desc_num].length.set(0);
|
sdio.regs
|
||||||
|
.adma_system_address
|
||||||
|
.write(descr_table.as_ptr() as u32);
|
||||||
|
}
|
||||||
|
cache::dcci_slice(descr_table);
|
||||||
}
|
}
|
||||||
descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true));
|
|
||||||
descr_table[total_desc_lines - 1].length.set(
|
|
||||||
(blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16,
|
|
||||||
);
|
|
||||||
unsafe {
|
|
||||||
sdio.regs
|
|
||||||
.adma_system_address
|
|
||||||
.write(descr_table.as_ptr() as u32);
|
|
||||||
}
|
|
||||||
cache::dcci_slice(descr_table);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{adma::setup_adma2_descr32, cmd, CardType, CmdTransferError, SDIO};
|
use super::{adma::Adma2DescTable, cmd, CardType, CmdTransferError, SDIO};
|
||||||
use libcortex_a9::cache;
|
use libcortex_a9::cache;
|
||||||
use libregister::{RegisterR, RegisterRW, RegisterW};
|
use libregister::{RegisterR, RegisterRW, RegisterW};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
@ -25,6 +25,7 @@ enum CardVersion {
|
||||||
|
|
||||||
pub struct SdCard {
|
pub struct SdCard {
|
||||||
sdio: SDIO,
|
sdio: SDIO,
|
||||||
|
adma2_desc_table: Adma2DescTable,
|
||||||
card_version: CardVersion,
|
card_version: CardVersion,
|
||||||
hcs: bool,
|
hcs: bool,
|
||||||
card_id: [u32; 4],
|
card_id: [u32; 4],
|
||||||
|
@ -165,6 +166,7 @@ impl SdCard {
|
||||||
};
|
};
|
||||||
let mut _self = SdCard {
|
let mut _self = SdCard {
|
||||||
sdio,
|
sdio,
|
||||||
|
adma2_desc_table: Adma2DescTable::new(),
|
||||||
card_version: CardVersion::SdVer1,
|
card_version: CardVersion::SdVer1,
|
||||||
hcs: false,
|
hcs: false,
|
||||||
card_id: [0, 0, 0, 0],
|
card_id: [0, 0, 0, 0],
|
||||||
|
@ -203,7 +205,7 @@ impl SdCard {
|
||||||
self.sdio.set_block_size(512)?;
|
self.sdio.set_block_size(512)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer);
|
self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer);
|
||||||
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
|
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
|
||||||
cache::dcci_slice(buffer);
|
cache::dcci_slice(buffer);
|
||||||
|
|
||||||
|
@ -256,7 +258,7 @@ impl SdCard {
|
||||||
self.sdio.set_block_size(512)?;
|
self.sdio.set_block_size(512)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer);
|
self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer);
|
||||||
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
|
// invalidate D cache, required for ZC706, not sure for Cora Z7 10
|
||||||
cache::dcci_slice(buffer);
|
cache::dcci_slice(buffer);
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ impl SdCard {
|
||||||
.block_size_block_count
|
.block_size_block_count
|
||||||
.modify(|_, w| w.transfer_block_size(blk_size));
|
.modify(|_, w| w.transfer_block_size(blk_size));
|
||||||
|
|
||||||
setup_adma2_descr32(&mut self.sdio, blk_cnt as u32, buf);
|
self.adma2_desc_table.setup(&mut self.sdio, blk_cnt as u32, buf);
|
||||||
cache::dcci_slice(buf);
|
cache::dcci_slice(buf);
|
||||||
self.sdio.cmd_transfer_with_mode(
|
self.sdio.cmd_transfer_with_mode(
|
||||||
ACMD51,
|
ACMD51,
|
||||||
|
|
Loading…
Reference in New Issue