Add FrameBuffer configuration
This commit is contained in:
		
							parent
							
								
									082a1c29e7
								
							
						
					
					
						commit
						e19177da52
					
				| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					use {
 | 
				
			||||||
 | 
					    super::{
 | 
				
			||||||
 | 
					        mailbox::{channel, read, write, MailboxOps, RegisterBlock, Result},
 | 
				
			||||||
 | 
					        BcmHost,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    core::ops::Deref,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// FrameBuffer channel supported structure - use with mailbox::channel::FrameBuffer
 | 
				
			||||||
 | 
					/// Must have the same alignment as the mailbox buffers.
 | 
				
			||||||
 | 
					#[repr(C)]
 | 
				
			||||||
 | 
					#[repr(align(16))]
 | 
				
			||||||
 | 
					pub struct FrameBuffer {
 | 
				
			||||||
 | 
					    pub width: u32,
 | 
				
			||||||
 | 
					    pub height: u32,
 | 
				
			||||||
 | 
					    pub vwidth: u32,
 | 
				
			||||||
 | 
					    pub vheight: u32,
 | 
				
			||||||
 | 
					    pub pitch: u32,
 | 
				
			||||||
 | 
					    pub depth: u32,
 | 
				
			||||||
 | 
					    pub x_offset: u32,
 | 
				
			||||||
 | 
					    pub y_offset: u32,
 | 
				
			||||||
 | 
					    pub pointer: u32,
 | 
				
			||||||
 | 
					    pub size: u32,
 | 
				
			||||||
 | 
					    // Must be after HW-dictated fields to not break structure alignment.
 | 
				
			||||||
 | 
					    base_addr: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// @todo rewrite in terms of using the Mailbox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Deref to RegisterBlock
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Allows writing
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					/// self.STATUS.read()
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					/// instead of something along the lines of
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					/// unsafe { (*FrameBuffer::ptr()).STATUS.read() }
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					impl Deref for FrameBuffer {
 | 
				
			||||||
 | 
					    type Target = RegisterBlock; // mailbox RegisterBlock reused here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn deref(&self) -> &Self::Target {
 | 
				
			||||||
 | 
					        unsafe { &*self.ptr() }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl core::fmt::Debug for FrameBuffer {
 | 
				
			||||||
 | 
					    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
 | 
				
			||||||
 | 
					        write!(
 | 
				
			||||||
 | 
					            f,
 | 
				
			||||||
 | 
					            "\n\n\n#### FrameBuffer({}x{}, {}x{}, d{}, --{}--, +{}x{}, {}@{:x})\n\n\n",
 | 
				
			||||||
 | 
					            self.width,
 | 
				
			||||||
 | 
					            self.height,
 | 
				
			||||||
 | 
					            self.vwidth,
 | 
				
			||||||
 | 
					            self.vheight,
 | 
				
			||||||
 | 
					            self.depth,
 | 
				
			||||||
 | 
					            self.pitch,
 | 
				
			||||||
 | 
					            self.x_offset,
 | 
				
			||||||
 | 
					            self.y_offset,
 | 
				
			||||||
 | 
					            self.size,
 | 
				
			||||||
 | 
					            self.pointer,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl FrameBuffer {
 | 
				
			||||||
 | 
					    pub fn new(reg_base: usize, width: u32, height: u32, depth: u32) -> FrameBuffer {
 | 
				
			||||||
 | 
					        FrameBuffer {
 | 
				
			||||||
 | 
					            width,
 | 
				
			||||||
 | 
					            height,
 | 
				
			||||||
 | 
					            vwidth: width,
 | 
				
			||||||
 | 
					            vheight: height,
 | 
				
			||||||
 | 
					            pitch: 0,
 | 
				
			||||||
 | 
					            depth,
 | 
				
			||||||
 | 
					            x_offset: 0,
 | 
				
			||||||
 | 
					            y_offset: 0,
 | 
				
			||||||
 | 
					            pointer: 0, // could be 4096 for the alignment?
 | 
				
			||||||
 | 
					            size: 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            base_addr: reg_base,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl MailboxOps for FrameBuffer {
 | 
				
			||||||
 | 
					    /// Returns a pointer to the register block
 | 
				
			||||||
 | 
					    fn ptr(&self) -> *const RegisterBlock {
 | 
				
			||||||
 | 
					        self.base_addr as *const _
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes says:
 | 
				
			||||||
 | 
					    /// **With the exception of the property tags mailbox channel,**
 | 
				
			||||||
 | 
					    /// when passing memory addresses as the data part of a mailbox message,
 | 
				
			||||||
 | 
					    /// the addresses should be **bus addresses as seen from the VC.**
 | 
				
			||||||
 | 
					    fn write(&self, _channel: u32) -> Result<()> {
 | 
				
			||||||
 | 
					        write(
 | 
				
			||||||
 | 
					            self,
 | 
				
			||||||
 | 
					            BcmHost::phys2bus(&self as *const _ as usize) as *const _,
 | 
				
			||||||
 | 
					            channel::FrameBuffer,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn read(&self, _channel: u32) -> Result<()> {
 | 
				
			||||||
 | 
					        read(self, 0, channel::FrameBuffer)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -125,6 +125,9 @@ pub mod channel {
 | 
				
			||||||
    // Count = 7,
 | 
					    // Count = 7,
 | 
				
			||||||
    pub const PropertyTagsArmToVc: u32 = 8;
 | 
					    pub const PropertyTagsArmToVc: u32 = 8;
 | 
				
			||||||
    pub const PropertyTagsVcToArm: u32 = 9;
 | 
					    pub const PropertyTagsVcToArm: u32 = 9;
 | 
				
			||||||
 | 
					    /// Channel number is ignored. Use for implementations of MailboxOps that use hardcoded
 | 
				
			||||||
 | 
					    /// channel number.
 | 
				
			||||||
 | 
					    pub const Ignored: u32 = !0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Single code indicating request
 | 
					// Single code indicating request
 | 
				
			||||||
| 
						 | 
					@ -236,7 +239,7 @@ pub mod alpha_mode {
 | 
				
			||||||
    pub const IGNORED: u32 = 2;
 | 
					    pub const IGNORED: u32 = 2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
 | 
					pub fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
 | 
				
			||||||
    let mut count: u32 = 0;
 | 
					    let mut count: u32 = 0;
 | 
				
			||||||
    let buf_ptr: u32 = buf as u32;
 | 
					    let buf_ptr: u32 = buf as u32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,7 +268,7 @@ fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn read(regs: &RegisterBlock, expected: u32, channel: u32) -> Result<()> {
 | 
					pub fn read(regs: &RegisterBlock, expected: u32, channel: u32) -> Result<()> {
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        let mut count: u32 = 0;
 | 
					        let mut count: u32 = 0;
 | 
				
			||||||
        while regs.STATUS.is_set(STATUS::EMPTY) {
 | 
					        while regs.STATUS.is_set(STATUS::EMPTY) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#![allow(dead_code)]
 | 
					#![allow(dead_code)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod fb;
 | 
				
			||||||
pub mod mailbox;
 | 
					pub mod mailbox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// See BCM2835-ARM-Peripherals.pdf
 | 
					/// See BCM2835-ARM-Peripherals.pdf
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue