sdio: move ADMA2_DESCR32_TABLE into SdCard

pull/36/head
Astro 2020-06-10 00:38:59 +02:00 committed by Gitea
parent 1586190712
commit 316ea61702
2 changed files with 51 additions and 45 deletions

View File

@ -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);
} }

View File

@ -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,