RASCSI/cpp/hal/systimer_allwinner.h

107 lines
3.8 KiB
C++

//---------------------------------------------------------------------------
//
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Copyright (C) 2022 akuker
//
// [ High resolution timer ]
//
//---------------------------------------------------------------------------
#pragma once
#include "systimer.h"
#include <stdint.h>
#include <string>
//===========================================================================
//
// System timer
//
//===========================================================================
class SysTimer_AllWinner : public PlatformSpecificTimer
{
public:
// Default constructor
SysTimer_AllWinner() = default;
// Default destructor
~SysTimer_AllWinner() override = default;
// Initialization
void Init() override;
// Get system timer low byte
uint32_t GetTimerLow() override;
// Get system timer high byte
uint32_t GetTimerHigh() override;
// Sleep for N nanoseconds
void SleepNsec(uint32_t nsec) override;
// Sleep for N microseconds
void SleepUsec(uint32_t usec) override;
private:
void enable_hs_timer();
void disable_hs_timer();
static const std::string dev_mem_filename;
/* Reference: Allwinner H3 Datasheet, section 4.9.3 */
static const uint32_t hs_timer_base_address = 0x01C60000;
/* Note: Currently the high speed timer is NOT in the armbian
* device tree. If it is ever added, this should be pulled
* from there */
using sun8i_hsitimer_registers = struct {
/* 0x00 HS Timer IRQ Enabled Register */
uint32_t hs_tmr_irq_en_reg;
/* 0x04 HS Timer Status Register */
uint32_t hs_tmr_irq_stat_reg;
/* 0x08 Unused */
uint32_t unused_08;
/* 0x0C Unused */
uint32_t unused_0C;
/* 0x10 HS Timer Control Register */
uint32_t hs_tmr_ctrl_reg;
/* 0x14 HS Timer Interval Value Low Reg */
uint32_t hs_tmr_intv_lo_reg;
/* 0x18 HS Timer Interval Value High Register */
uint32_t hs_tmr_intv_hi_reg;
/* 0x1C HS Timer Current Value Low Register */
uint32_t hs_tmr_curnt_lo_reg;
/* 0x20 HS Timer Current Value High Register */
uint32_t hs_tmr_curnt_hi_reg;
};
/* Constants for the HS Timer IRQ enable Register (section 4.9.4.1) */
static const uint32_t HS_TMR_INTERUPT_ENB = (1 << 0);
/* Constants for the HS Timer Control Register (section 4.9.4.3) */
static const uint32_t HS_TMR_EN = (1 << 0);
static const uint32_t HS_TMR_RELOAD = (1 << 1);
static const uint32_t HS_TMR_CLK_PRE_SCALE_1 = (0 << 4);
static const uint32_t HS_TMR_CLK_PRE_SCALE_2 = (1 << 4);
static const uint32_t HS_TMR_CLK_PRE_SCALE_4 = (2 << 4);
static const uint32_t HS_TMR_CLK_PRE_SCALE_8 = (3 << 4);
static const uint32_t HS_TMR_CLK_PRE_SCALE_16 = (4 << 4); // NOSONAR This matches the datasheet
static const uint32_t HS_TMR_MODE_SINGLE = (1 << 7);
static const uint32_t HS_TMR_TEST_MODE = (1 << 31);
volatile sun8i_hsitimer_registers *hsitimer_regs;
/* Reference: Allwinner H3 Datasheet, section 4.3.4 */
static const uint32_t system_bus_base_address = 0x01C20000;
struct sun8i_sysbus_registers {
uint32_t pad_00_5C[(0x60 / sizeof(uint32_t))]; // NOSONAR c-style array used for padding
/* 0x0060 Bus Clock Gating Register 0 */
uint32_t bus_clk_gating_reg0;
uint32_t pad_64_2C0[((0x2C0 - 0x64) / sizeof(uint32_t))]; // NOSONAR c-style array used for padding
/* 0x2C0 Bus Software Reset Register 0 */
uint32_t bus_soft_rst_reg0;
};
/* Bit associated with the HS Timer */
static const uint32_t BUS_CLK_GATING_REG0_HSTMR = 19;
static const uint32_t BUS_SOFT_RST_REG0_HSTMR = 19;
struct sun8i_sysbus_registers *sysbus_regs;
};