mirror of
https://github.com/lupyuen/pinephone-nuttx.git
synced 2025-01-13 05:08:32 +08:00
158 lines
5.3 KiB
C
158 lines
5.3 KiB
C
// Test Code for Allwinner A64 Display Engine
|
|
// Add `#include "../../pinephone-nuttx/test/test_a64_rsb.c"` to the end of this file:
|
|
// https://github.com/apache/nuttx/blob/master/arch/arm64/src/a64/a64_rsb.c
|
|
|
|
/// PIO Base Address (CPUx-PORT) (A64 Page 376)
|
|
#define PIO_BASE_ADDRESS 0x01C20800
|
|
|
|
/// Address of AXP803 PMIC on Reduced Serial Bus
|
|
#define AXP803_RT_ADDR 0x2d
|
|
|
|
static int pmic_write(
|
|
uint8_t reg,
|
|
uint8_t val
|
|
);
|
|
static int pmic_clrsetbits(
|
|
uint8_t reg,
|
|
uint8_t clr_mask,
|
|
uint8_t set_mask
|
|
);
|
|
|
|
/// Init PMIC.
|
|
/// Based on https://lupyuen.github.io/articles/de#appendix-power-management-integrated-circuit
|
|
int pinephone_pmic_init(void)
|
|
{
|
|
// Reset LCD Panel at PD23 (Active Low)
|
|
// assert reset: GPD(23), 0 // PD23 - LCD-RST (active low)
|
|
|
|
// Configure PD23 for Output
|
|
// Register PD_CFG2_REG (PD Configure Register 2)
|
|
// At PIO Offset 0x74 (A64 Page 387)
|
|
// Set PD23_SELECT (Bits 28 to 30) to 1 (Output)
|
|
// sunxi_gpio_set_cfgpin: pin=0x77, val=1
|
|
// sunxi_gpio_set_cfgbank: bank_offset=119, val=1
|
|
// clrsetbits 0x1c20874, 0xf0000000, 0x10000000
|
|
// TODO: Should 0xf0000000 be 0x70000000 instead?
|
|
ginfo("Configure PD23 for Output\n");
|
|
#define PD_CFG2_REG (PIO_BASE_ADDRESS + 0x74)
|
|
DEBUGASSERT(PD_CFG2_REG == 0x1c20874);
|
|
#define PD23_SELECT (0b001 << 28)
|
|
#define PD23_MASK (0b111 << 28)
|
|
DEBUGASSERT(PD23_SELECT == 0x10000000);
|
|
DEBUGASSERT(PD23_MASK == 0x70000000);
|
|
modreg32(PD23_SELECT, PD23_MASK, PD_CFG2_REG); // TODO: DMB
|
|
|
|
// Set PD23 to Low
|
|
// Register PD_DATA_REG (PD Data Register)
|
|
// At PIO Offset 0x7C (A64 Page 388)
|
|
// Set PD23 (Bit 23) to 0 (Low)
|
|
// sunxi_gpio_output: pin=0x77, val=0
|
|
// before: 0x1c2087c = 0x1c0000
|
|
// after: 0x1c2087c = 0x1c0000 (DMB)
|
|
ginfo("Set PD23 to Low\n");
|
|
#define PD_DATA_REG (PIO_BASE_ADDRESS + 0x7C)
|
|
DEBUGASSERT(PD_DATA_REG == 0x1c2087c);
|
|
#define PD23 (1 << 23)
|
|
modreg32(0, PD23, PD_DATA_REG); // TODO: DMB
|
|
|
|
// Set DLDO1 Voltage to 3.3V
|
|
// DLDO1 powers the Front Camera / USB HSIC / I2C Sensors
|
|
// Register 0x15: DLDO1 Voltage Control (AXP803 Page 52)
|
|
// Set Voltage (Bits 0 to 4) to 26 (2.6V + 0.7V = 3.3V)
|
|
ginfo("Set DLDO1 Voltage to 3.3V\n");
|
|
#define DLDO1_Voltage_Control 0x15
|
|
#define DLDO1_Voltage (26 << 0)
|
|
int ret1 = pmic_write(DLDO1_Voltage_Control, DLDO1_Voltage);
|
|
assert(ret1 == 0);
|
|
|
|
// Power on DLDO1
|
|
// Register 0x12: Output Power On-Off Control 2 (AXP803 Page 51)
|
|
// Set DLDO1 On-Off Control (Bit 3) to 1 (Power On)
|
|
#define Output_Power_On_Off_Control2 0x12
|
|
#define DLDO1_On_Off_Control (1 << 3)
|
|
int ret2 = pmic_clrsetbits(Output_Power_On_Off_Control2, 0, DLDO1_On_Off_Control);
|
|
assert(ret2 == 0);
|
|
|
|
// Set LDO Voltage to 3.3V
|
|
// GPIO0LDO powers the Capacitive Touch Panel
|
|
// Register 0x91: GPIO0LDO and GPIO0 High Level Voltage Setting (AXP803 Page 77)
|
|
// Set GPIO0LDO and GPIO0 High Level Voltage (Bits 0 to 4) to 26 (2.6V + 0.7V = 3.3V)
|
|
ginfo("Set LDO Voltage to 3.3V\n");
|
|
#define GPIO0LDO_High_Level_Voltage_Setting 0x91
|
|
#define GPIO0LDO_High_Level_Voltage (26 << 0)
|
|
int ret3 = pmic_write(GPIO0LDO_High_Level_Voltage_Setting, GPIO0LDO_High_Level_Voltage);
|
|
assert(ret3 == 0);
|
|
|
|
// Enable LDO Mode on GPIO0
|
|
// Register 0x90: GPIO0 (GPADC) Control (AXP803 Page 76)
|
|
// Set GPIO0 Pin Function Control (Bits 0 to 2) to 0b11 (Low Noise LDO on)
|
|
ginfo("Enable LDO mode on GPIO0\n");
|
|
#define GPIO0_Control 0x90
|
|
#define GPIO0_Pin_Function (0b11 << 0)
|
|
int ret4 = pmic_write(GPIO0_Control, GPIO0_Pin_Function);
|
|
assert(ret4 == 0);
|
|
|
|
// Set DLDO2 Voltage to 1.8V
|
|
// DLDO2 powers the MIPI DSI Connector
|
|
// Register 0x16: DLDO2 Voltage Control (AXP803 Page 52)
|
|
// Set Voltage (Bits 0 to 4) to 11 (1.1V + 0.7V = 1.8V)
|
|
ginfo("Set DLDO2 Voltage to 1.8V\n");
|
|
#define DLDO2_Voltage_Control 0x16
|
|
#define DLDO2_Voltage (11 << 0)
|
|
int ret5 = pmic_write(DLDO2_Voltage_Control, DLDO2_Voltage);
|
|
assert(ret5 == 0);
|
|
|
|
// Power on DLDO2
|
|
// Register 0x12: Output Power On-Off Control 2 (AXP803 Page 51)
|
|
// Set DLDO2 On-Off Control (Bit 4) to 1 (Power On)
|
|
DEBUGASSERT(Output_Power_On_Off_Control2 == 0x12);
|
|
#define DLDO2 (1 << 4)
|
|
int ret6 = pmic_clrsetbits(Output_Power_On_Off_Control2, 0x0, DLDO2);
|
|
assert(ret6 == 0);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/// Write value to PMIC Register
|
|
static int pmic_write(
|
|
uint8_t reg,
|
|
uint8_t val
|
|
)
|
|
{
|
|
// Write to AXP803 PMIC on Reduced Serial Bus
|
|
ginfo(" pmic_write: reg=0x%x, val=0x%x\n", reg, val);
|
|
int ret = a64_rsb_write(AXP803_RT_ADDR, reg, val);
|
|
if (ret != 0) { gerr(" pmic_write Error: ret=%d\n", ret); }
|
|
return ret;
|
|
}
|
|
|
|
#ifdef NOTUSED
|
|
/// Read value from PMIC Register
|
|
static int pmic_read(
|
|
uint8_t reg_addr
|
|
)
|
|
{
|
|
// Read from AXP803 PMIC on Reduced Serial Bus
|
|
ginfo(" pmic_read: reg_addr=0x%x\n", reg_addr);
|
|
int ret = a64_rsb_read(AXP803_RT_ADDR, reg_addr);
|
|
if (ret < 0) { gerr(" pmic_read Error: ret=%d\n", ret); }
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
/// Clear and Set the PMIC Register Bits
|
|
static int pmic_clrsetbits(
|
|
uint8_t reg,
|
|
uint8_t clr_mask,
|
|
uint8_t set_mask
|
|
)
|
|
{
|
|
// Read from AXP803 PMIC on Reduced Serial Bus
|
|
ginfo(" pmic_clrsetbits: reg=0x%x, clr_mask=0x%x, set_mask=0x%x\n", reg, clr_mask, set_mask);
|
|
int ret = a64_rsb_read(AXP803_RT_ADDR, reg);
|
|
if (ret < 0) { return ret; }
|
|
|
|
// Write to AXP803 PMIC on Reduced Serial Bus
|
|
uint8_t regval = (ret & ~clr_mask) | set_mask;
|
|
return a64_rsb_write(AXP803_RT_ADDR, reg, regval);
|
|
}
|