arm64/pinephone: Add driver for LCD Panel (Xingbangda XBD599)
This PR adds the driver for Xingbangda XBD599 LCD Panel (based on Sitronix ST7703 LCD Controller) on PINE64 PinePhone. This PR also includes: - The driver for X-Powers AXP803 Power Mgmt IC, which calls our driver for Allwinner A64's Reduced Serial Bus. The PMIC Driver is needed to power on the MIPI DSI Interface for the LCD Panel. - A simple Display Driver that renders a Test Pattern on the LCD Display at startup. It calls our Allwinner A64 drivers for Display Engine, Timing Controller TCON0 and MIPI Display Serial Interface. The NuttX Frame Buffer Driver will be implemented in the next PR. `arch/arm64/src/a64/a64_de.c`, `a64_de.h`: Changed the Frame Buffer pointer to `const` for Allwinner A64 Display Engine `arch/arm64/src/a64/hardware/a64_memorymap.h`: Added the Base Address for PWM, for controlling the PWM Backlight `boards/arm64/a64/pinephone/src/pinephone_bringup.c`: Call `fb_register()` to start the Display Driver at startup `boards/arm64/a64/pinephone/src/Makefile`: Added LCD Driver, PMIC Driver and Display Driver to Makefile `boards/arm64/a64/pinephone/Kconfig`: Added the Kconfig option for "PINE64 PinePhone > LCD Display" (`CONFIG_PINEPHONE_LCD`) which enables the LCD Driver, PMIC Driver and Display Driver `boards/arm64/a64/pinephone/src/pinephone_lcd.c`, `pinephone_lcd.h`: Driver for Xingbangda XBD599 LCD Panel `boards/arm64/a64/pinephone/src/pinephone_pmic.c`, `pinephone_pmic.h`: Driver for X-Powers AXP803 Power Mgmt IC `boards/arm64/a64/pinephone/src/pinephone_display.c`: Simple Display Driver that renders a Test Pattern in `up_fbinitialize()` `boards/arm64/a64/pinephone/configs/lcd/defconfig`: New PinePhone Board Configuration `pinephone:lcd` that enables the LCD Driver (`CONFIG_PINEPHONE_LCD`) `platforms/arm/a64/boards/pinephone/index.rst`: Added PinePhone Board Configuration `pinephone:lcd` that enables the LCD Driver
This commit is contained in:
parent
5a0d8fdf49
commit
17639af0a8
@ -12,7 +12,7 @@ Features
|
||||
- **GPU:** ARM Mali400 MP2
|
||||
- **Interrupt Controller:** ARM GIC PL400 (Generic Interrupt Controller v2)
|
||||
- **Display Engine:** Allwinner Display Engine 2.0 (MIPI DSI with DMA)
|
||||
- **Display:** Xingbangda XBD599 HD IPS Capacitive Touchscreen (5.95 inches, 1440x720 resolution, 16M colors)
|
||||
- **Display:** Xingbangda XBD599 HD IPS Capacitive Touchscreen (5.95 inches, 1440x720 resolution, 16M colors, PWM Backlight)
|
||||
- **LCD Controller:** Sitronix ST7703 (MIPI DSI)
|
||||
- **RAM:** 2GB or 3GB LPDDR3 SDRAM
|
||||
- **Internal Storage:** 16GB or 32GB eMMC, extendable up to 2TB via microSD
|
||||
@ -29,6 +29,7 @@ Features
|
||||
- **Privacy Switches:** Modem, WiFi & Bluetooth, Microphone, Cameras, Headphone
|
||||
- **Battery:** Lithium-ion, rated capacity 2800mAh (10.64Wh), typical capacity 3000mAh (11.40Wh)
|
||||
- **I/O:** USB Type-C, USB Host, DisplayPort Alternate Mode output, 15W 5V 3A Quick Charge, follows USB PD specification
|
||||
- **Power Management Integrated Circuit:** X-Powers AXP803 (Reduced Serial Bus)
|
||||
|
||||
Serial Console
|
||||
==============
|
||||
@ -73,7 +74,7 @@ Configure the NuttX project and build the project:
|
||||
.. code:: console
|
||||
|
||||
$ cd nuttx
|
||||
$ tools/configure.sh pinephone:nsh
|
||||
$ tools/configure.sh pinephone:lcd
|
||||
$ make
|
||||
$ cp nuttx.bin Image
|
||||
$ rm -f Image.gz
|
||||
@ -129,6 +130,15 @@ LED3 Blue LED PD20
|
||||
Configurations
|
||||
==============
|
||||
|
||||
lcd
|
||||
___
|
||||
|
||||
Supports LCD Display (XBD599) with LCD Controller (ST7703),
|
||||
Display Engine 2.0, MIPI Display Serial Interface (DSI),
|
||||
Power Management Integrated Circuit (AXP803) and
|
||||
Reduced Serial Bus (RSB).
|
||||
Serial Console is enabled on UART0 at 115.2 kbps.
|
||||
|
||||
nsh
|
||||
---
|
||||
|
||||
@ -142,14 +152,18 @@ Peripheral Support
|
||||
|
||||
NuttX for PinePhone supports these peripherals:
|
||||
|
||||
============== ======= =====
|
||||
Peripheral Support NOTES
|
||||
============== ======= =====
|
||||
Display Engine Yes
|
||||
MIPI D-PHY Yes
|
||||
MIPI DSI Yes
|
||||
PIO Yes
|
||||
RSB Yes
|
||||
TCON0 Yes
|
||||
UART Yes Only UART0 is supported
|
||||
============== ======= =====
|
||||
======================= ======= =====
|
||||
Peripheral Support NOTES
|
||||
======================= ======= =====
|
||||
Backlight Yes
|
||||
Display Engine Yes
|
||||
LCD Controller (ST7703) Yes
|
||||
LCD Panel (XBD599) Yes
|
||||
MIPI D-PHY Yes
|
||||
MIPI DSI Yes
|
||||
PIO Yes
|
||||
PMIC (AXP803) Yes
|
||||
RSB Yes
|
||||
TCON0 Yes
|
||||
UART Yes Only UART0 is supported
|
||||
======================= ======= =====
|
||||
|
@ -735,7 +735,7 @@ int a64_de_blender_init(void)
|
||||
****************************************************************************/
|
||||
|
||||
int a64_de_ui_channel_init(uint8_t channel,
|
||||
void *fbmem,
|
||||
const void *fbmem,
|
||||
size_t fblen,
|
||||
uint16_t xres,
|
||||
uint16_t yres,
|
||||
|
@ -92,7 +92,7 @@ int a64_de_blender_init(void);
|
||||
****************************************************************************/
|
||||
|
||||
int a64_de_ui_channel_init(uint8_t channel,
|
||||
void *fbmem,
|
||||
const void *fbmem,
|
||||
size_t fblen,
|
||||
uint16_t xres,
|
||||
uint16_t yres,
|
||||
|
@ -38,10 +38,12 @@
|
||||
#define A64_TCON0_ADDR 0x01c0c000 /* TCON 0 0x01c0:c000-0x01c0:cfff 4K */
|
||||
#define A64_CCU_ADDR 0x01c20000 /* CCU 0x01c2:0000-0x01c2:03ff 1K */
|
||||
#define A64_PIO_ADDR 0x01c20800 /* PIO 0x01c2:0800-0x01c2:0bff 1K */
|
||||
#define A64_PWM_ADDR 0x01c21400 /* PWM 0x01c2:1400-0x01c2:17ff 1K */
|
||||
#define A64_DSI_ADDR 0x01ca0000 /* MIPI DSI 0x01ca:0000-0x01ca:0fff 4K */
|
||||
#define A64_DPHY_ADDR 0x01ca1000 /* MIPI DSI-PHY 0x01ca:1000-0x01ca:1fff 4K */
|
||||
#define A64_RPIO_ADDR 0x01f02c00 /* R_PIO 0x01f0:2c00-0x01f0:2fff 1K */
|
||||
#define A64_RSB_ADDR 0x01f03400 /* R_RSB 0x01f0:3400-0x01f0:37ff 1K */
|
||||
#define A64_RPWM_ADDR 0x01f03800 /* R_PWM 0x01f0:3800-0x01f0-3bff 1K */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
|
@ -4,4 +4,16 @@
|
||||
#
|
||||
|
||||
if ARCH_BOARD_PINEPHONE
|
||||
endif
|
||||
|
||||
config PINEPHONE_LCD
|
||||
bool "LCD Display"
|
||||
default n
|
||||
select A64_DE
|
||||
select A64_RSB
|
||||
select DRIVERS_VIDEO
|
||||
select VIDEO_FB
|
||||
select FB_OVERLAY
|
||||
---help---
|
||||
Select to enable support for LCD Display.
|
||||
|
||||
endif # ARCH_BOARD_PINEPHONE
|
||||
|
69
boards/arm64/a64/pinephone/configs/lcd/defconfig
Normal file
69
boards/arm64/a64/pinephone/configs/lcd/defconfig
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
CONFIG_A64_UART=y
|
||||
CONFIG_ARCH="arm64"
|
||||
CONFIG_ARCH_ARM64=y
|
||||
CONFIG_ARCH_BOARD="pinephone"
|
||||
CONFIG_ARCH_BOARD_PINEPHONE=y
|
||||
CONFIG_ARCH_CHIP="a64"
|
||||
CONFIG_ARCH_CHIP_A64=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=4096
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=116524
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_ASSERTIONS=y
|
||||
CONFIG_DEBUG_ERROR=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_SCHED=y
|
||||
CONFIG_DEBUG_SCHED_ERROR=y
|
||||
CONFIG_DEBUG_SCHED_WARN=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_WARN=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=8192
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_EXAMPLES_LEDS=y
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=8192
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NSH_ROMFSETC=y
|
||||
CONFIG_PINEPHONE_LCD=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PTHREAD_STACK_MIN=8192
|
||||
CONFIG_RAMLOG=y
|
||||
CONFIG_RAM_SIZE=134217728
|
||||
CONFIG_RAM_START=0x40000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SPINLOCK=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_MONTH=11
|
||||
CONFIG_START_YEAR=2022
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_SYSTEM=y
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART1_SERIAL_CONSOLE=y
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
CONFIG_USERLED=y
|
||||
CONFIG_USERLED_LOWER=y
|
@ -37,4 +37,8 @@ ifeq ($(CONFIG_USERLED),y)
|
||||
CSRCS += pinephone_userleds.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VIDEO_FB),y)
|
||||
CSRCS += pinephone_display.c pinephone_lcd.c pinephone_pmic.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
@ -34,6 +34,10 @@
|
||||
# include <nuttx/leds/userled.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB
|
||||
# include <nuttx/video/fb.h>
|
||||
#endif
|
||||
|
||||
#include "pinephone.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -72,6 +76,16 @@ int pinephone_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB
|
||||
/* Initialize and register the framebuffer driver */
|
||||
|
||||
ret = fb_register(0, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
UNUSED(ret);
|
||||
return OK;
|
||||
}
|
||||
|
633
boards/arm64/a64/pinephone/src/pinephone_display.c
Normal file
633
boards/arm64/a64/pinephone/src/pinephone_display.c
Normal file
@ -0,0 +1,633 @@
|
||||
/****************************************************************************
|
||||
* boards/arm64/a64/pinephone/src/pinephone_display.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Reference:
|
||||
*
|
||||
* "Understanding PinePhone's Display (MIPI DSI)"
|
||||
* https://lupyuen.github.io/articles/dsi
|
||||
*
|
||||
* "NuttX RTOS for PinePhone: Display Driver in Zig"
|
||||
* https://lupyuen.github.io/articles/dsi2
|
||||
*
|
||||
* "Rendering PinePhone's Display (DE and TCON0)"
|
||||
* https://lupyuen.github.io/articles/de
|
||||
*
|
||||
* "NuttX RTOS for PinePhone: Render Graphics in Zig"
|
||||
* https://lupyuen.github.io/articles/de2
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
#include "chip.h"
|
||||
#include "arm64_internal.h"
|
||||
#include "a64_de.h"
|
||||
#include "a64_mipi_dphy.h"
|
||||
#include "a64_mipi_dsi.h"
|
||||
#include "a64_tcon0.h"
|
||||
#include "pinephone_lcd.h"
|
||||
#include "pinephone_pmic.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* LCD Backlight Brightness (percentage) */
|
||||
|
||||
#define BACKLIGHT_BRIGHTNESS_PERCENT 90
|
||||
|
||||
/* Number of UI Channels to render: 1 or 3 */
|
||||
|
||||
#define UI_CHANNELS 3
|
||||
|
||||
/* LCD Panel Width and Height (pixels) */
|
||||
|
||||
#define PANEL_WIDTH PINEPHONE_LCD_PANEL_WIDTH /* 720 pixels */
|
||||
#define PANEL_HEIGHT PINEPHONE_LCD_PANEL_HEIGHT /* 1440 pixels */
|
||||
|
||||
/* Framebuffer 1 Width and Height (pixels) */
|
||||
|
||||
#define FB1_WIDTH 600
|
||||
#define FB1_HEIGHT 600
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Frame Buffers for Display Engine *****************************************/
|
||||
|
||||
/* Frame Buffer 0: (Base UI Channel)
|
||||
* Fullscreen 720 x 1440 (4 bytes per XRGB 8888 pixel)
|
||||
*/
|
||||
|
||||
static uint32_t g_pinephone_fb0[PANEL_WIDTH * PANEL_HEIGHT];
|
||||
|
||||
/* Frame Buffer 1: (First Overlay UI Channel)
|
||||
* Square 600 x 600 (4 bytes per ARGB 8888 pixel)
|
||||
*/
|
||||
|
||||
static uint32_t g_pinephone_fb1[FB1_WIDTH * FB1_HEIGHT];
|
||||
|
||||
/* Frame Buffer 2: (Second Overlay UI Channel)
|
||||
* Fullscreen 720 x 1440 (4 bytes per ARGB 8888 pixel)
|
||||
*/
|
||||
|
||||
static uint32_t g_pinephone_fb2[PANEL_WIDTH * PANEL_HEIGHT];
|
||||
|
||||
/* Video Controller for 3 UI Channels:
|
||||
* Fullscreen 720 x 1440 (4 bytes per ARGB 8888 pixel)
|
||||
*/
|
||||
|
||||
static struct fb_videoinfo_s g_pinephone_video =
|
||||
{
|
||||
.fmt = FB_FMT_RGBA32, /* Pixel format (XRGB 8888) */
|
||||
.xres = PANEL_WIDTH, /* Horizontal resolution in pixel columns */
|
||||
.yres = PANEL_HEIGHT, /* Vertical resolution in pixel rows */
|
||||
.nplanes = 1, /* Color planes: Base UI Channel */
|
||||
.noverlays = 2 /* Overlays: 2 Overlay UI Channels) */
|
||||
};
|
||||
|
||||
/* Color Plane for Base UI Channel:
|
||||
* Fullscreen 720 x 1440 (4 bytes per XRGB 8888 pixel)
|
||||
*/
|
||||
|
||||
static struct fb_planeinfo_s g_pinephone_plane =
|
||||
{
|
||||
.fbmem = &g_pinephone_fb0,
|
||||
.fblen = sizeof(g_pinephone_fb0),
|
||||
.stride = PANEL_WIDTH * 4, /* Length of a line (4-byte pixel) */
|
||||
.display = 0, /* Display number (Unused) */
|
||||
.bpp = 32, /* Bits per pixel (XRGB 8888) */
|
||||
.xres_virtual = PANEL_WIDTH, /* Virtual Horizontal resolution */
|
||||
.yres_virtual = PANEL_HEIGHT, /* Virtual Vertical resolution */
|
||||
.xoffset = 0, /* Offset from virtual to visible */
|
||||
.yoffset = 0 /* Offset from virtual to visible */
|
||||
};
|
||||
|
||||
/* Overlays for 2 Overlay UI Channels */
|
||||
|
||||
static struct fb_overlayinfo_s g_pinephone_overlays[2] =
|
||||
{
|
||||
/* First Overlay UI Channel:
|
||||
* Square 600 x 600 (4 bytes per ARGB 8888 pixel)
|
||||
*/
|
||||
|
||||
{
|
||||
.fbmem = &g_pinephone_fb1,
|
||||
.fblen = sizeof(g_pinephone_fb1),
|
||||
.stride = FB1_WIDTH * 4, /* Length of a line (4-byte pixel) */
|
||||
.overlay = 0, /* Overlay number (First Overlay) */
|
||||
.bpp = 32, /* Bits per pixel (ARGB 8888) */
|
||||
.blank = 0, /* TODO: Blank or unblank */
|
||||
.chromakey = 0, /* TODO: Chroma key argb8888 formatted */
|
||||
.color = 0, /* TODO: Color argb8888 formatted */
|
||||
.transp = /* TODO: Transparency */
|
||||
{
|
||||
.transp = 0,
|
||||
.transp_mode = 0
|
||||
},
|
||||
.sarea = /* Selected area within the overlay */
|
||||
{
|
||||
.x = 52,
|
||||
.y = 52,
|
||||
.w = FB1_WIDTH,
|
||||
.h = FB1_HEIGHT
|
||||
},
|
||||
.accl = 0 /* TODO: Supported hardware acceleration */
|
||||
},
|
||||
|
||||
/* Second Overlay UI Channel:
|
||||
* Fullscreen 720 x 1440 (4 bytes per ARGB 8888 pixel)
|
||||
*/
|
||||
|
||||
{
|
||||
.fbmem = &g_pinephone_fb2,
|
||||
.fblen = sizeof(g_pinephone_fb2),
|
||||
.stride = PANEL_WIDTH * 4, /* Length of a line (4-byte pixel) */
|
||||
.overlay = 1, /* Overlay number (First Overlay) */
|
||||
.bpp = 32, /* Bits per pixel (ARGB 8888) */
|
||||
.blank = 0, /* TODO: Blank or unblank */
|
||||
.chromakey = 0, /* TODO: Chroma key argb8888 formatted */
|
||||
.color = 0, /* TODO: Color argb8888 formatted */
|
||||
.transp = /* TODO: Transparency */
|
||||
{
|
||||
.transp = 0,
|
||||
.transp_mode = 0
|
||||
},
|
||||
.sarea = /* Selected area within the overlay */
|
||||
{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = PANEL_WIDTH,
|
||||
.h = PANEL_HEIGHT
|
||||
},
|
||||
.accl = 0 /* TODO: Supported hardware acceleration */
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_pattern
|
||||
*
|
||||
* Description:
|
||||
* Fill the 3 Frame Buffers with a Test Pattern. Should be called after
|
||||
* Display Engine is Enabled, or the rendered image will have missing
|
||||
* rows.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void test_pattern(void)
|
||||
{
|
||||
int i;
|
||||
int x;
|
||||
int y;
|
||||
const int fb0_len = sizeof(g_pinephone_fb0) / sizeof(g_pinephone_fb0[0]);
|
||||
const int fb1_len = sizeof(g_pinephone_fb1) / sizeof(g_pinephone_fb1[0]);
|
||||
|
||||
/* Zero the Framebuffers */
|
||||
|
||||
memset(g_pinephone_fb0, 0, sizeof(g_pinephone_fb0));
|
||||
memset(g_pinephone_fb1, 0, sizeof(g_pinephone_fb1));
|
||||
memset(g_pinephone_fb2, 0, sizeof(g_pinephone_fb2));
|
||||
|
||||
/* Init Framebuffer 0:
|
||||
* Fill with Blue, Green and Red
|
||||
*/
|
||||
|
||||
for (i = 0; i < fb0_len; i++)
|
||||
{
|
||||
/* Colours are in XRGB 8888 format */
|
||||
|
||||
if (i < fb0_len / 4)
|
||||
{
|
||||
/* Blue for top quarter */
|
||||
|
||||
g_pinephone_fb0[i] = 0x80000080;
|
||||
}
|
||||
else if (i < fb0_len / 2)
|
||||
{
|
||||
/* Green for next quarter */
|
||||
|
||||
g_pinephone_fb0[i] = 0x80008000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Red for lower half */
|
||||
|
||||
g_pinephone_fb0[i] = 0x80800000;
|
||||
}
|
||||
|
||||
/* Fixes missing rows in the rendered image, not sure why */
|
||||
|
||||
ARM64_DMB();
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/* Init Framebuffer 1:
|
||||
* Fill with Semi-Transparent White
|
||||
*/
|
||||
|
||||
for (i = 0; i < fb1_len; i++)
|
||||
{
|
||||
/* Semi-Transparent White in ARGB 8888 format */
|
||||
|
||||
g_pinephone_fb1[i] = 0x40ffffff;
|
||||
|
||||
/* Fixes missing rows in the rendered image, not sure why */
|
||||
|
||||
ARM64_DMB();
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/* Init Framebuffer 2:
|
||||
* Fill with Semi-Transparent Green Circle
|
||||
*/
|
||||
|
||||
for (y = 0; y < PANEL_HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < PANEL_WIDTH; x++)
|
||||
{
|
||||
/* Get pixel index */
|
||||
|
||||
const int p = (y * PANEL_WIDTH) + x;
|
||||
|
||||
/* Shift coordinates so that centre of screen is (0,0) */
|
||||
|
||||
const int half_width = PANEL_WIDTH / 2;
|
||||
const int half_height = PANEL_HEIGHT / 2;
|
||||
const int x_shift = x - half_width;
|
||||
const int y_shift = y - half_height;
|
||||
|
||||
/* If x^2 + y^2 < radius^2, set to Semi-Transparent Green */
|
||||
|
||||
if (x_shift*x_shift + y_shift*y_shift < half_width*half_width)
|
||||
{
|
||||
/* Semi-Transparent Green in ARGB 8888 Format */
|
||||
|
||||
g_pinephone_fb2[p] = 0x80008000;
|
||||
}
|
||||
else /* Otherwise set to Transparent Black */
|
||||
{
|
||||
/* Transparent Black in ARGB 8888 Format */
|
||||
|
||||
g_pinephone_fb2[p] = 0x00000000;
|
||||
}
|
||||
|
||||
/* Fixes missing rows in the rendered image, not sure why */
|
||||
|
||||
ARM64_DMB();
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: render_framebuffers
|
||||
*
|
||||
* Description:
|
||||
* Render the 3 Frame Buffers with the Display Engine.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int render_framebuffers(void)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
const int overlay_len = sizeof(g_pinephone_overlays) /
|
||||
sizeof(g_pinephone_overlays[0]);
|
||||
|
||||
/* Validate the Frame Buffer Sizes */
|
||||
|
||||
DEBUGASSERT(UI_CHANNELS == 1 || UI_CHANNELS == 3);
|
||||
DEBUGASSERT(g_pinephone_plane.xres_virtual == g_pinephone_video.xres);
|
||||
DEBUGASSERT(g_pinephone_plane.yres_virtual == g_pinephone_video.yres);
|
||||
DEBUGASSERT(g_pinephone_plane.fblen ==
|
||||
g_pinephone_plane.xres_virtual *
|
||||
g_pinephone_plane.yres_virtual * 4);
|
||||
DEBUGASSERT(g_pinephone_plane.stride ==
|
||||
g_pinephone_plane.xres_virtual * 4);
|
||||
DEBUGASSERT(g_pinephone_overlays[0].fblen ==
|
||||
(g_pinephone_overlays[0].sarea.w) *
|
||||
g_pinephone_overlays[0].sarea.h * 4);
|
||||
DEBUGASSERT(g_pinephone_overlays[0].stride ==
|
||||
g_pinephone_overlays[0].sarea.w * 4);
|
||||
DEBUGASSERT(g_pinephone_overlays[1].fblen ==
|
||||
(g_pinephone_overlays[1].sarea.w) *
|
||||
g_pinephone_overlays[1].sarea.h * 4);
|
||||
DEBUGASSERT(g_pinephone_overlays[1].stride ==
|
||||
g_pinephone_overlays[1].sarea.w * 4);
|
||||
|
||||
/* Init the UI Blender for Display Engine */
|
||||
|
||||
ret = a64_de_blender_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init UI Blender failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the Base UI Channel. Frame Buffer Address should be 32-bit. */
|
||||
|
||||
ret = a64_de_ui_channel_init(1, /* UI Channel 1 (Base UI Channel) */
|
||||
g_pinephone_plane.fbmem,
|
||||
g_pinephone_plane.fblen,
|
||||
g_pinephone_plane.xres_virtual,
|
||||
g_pinephone_plane.yres_virtual,
|
||||
g_pinephone_plane.xoffset,
|
||||
g_pinephone_plane.yoffset);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init UI Channel 1 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the 2 Overlay UI Channels */
|
||||
|
||||
for (i = 0; i < overlay_len; i++)
|
||||
{
|
||||
const struct fb_overlayinfo_s *ov = &g_pinephone_overlays[i];
|
||||
|
||||
/* Pass Frame Buffer as null if UI Channel should be disabled */
|
||||
|
||||
const void *fb = (UI_CHANNELS == 3) ? ov->fbmem : NULL;
|
||||
|
||||
ret = a64_de_ui_channel_init(i + 2, /* UI Channel 2 or 3 */
|
||||
fb, /* 32-bit address */
|
||||
ov->fblen, /* Frame Buffer length */
|
||||
ov->sarea.w, /* Horiz res */
|
||||
ov->sarea.h, /* Vert res */
|
||||
ov->sarea.x, /* Horiz offset */
|
||||
ov->sarea.y); /* Vert offset */
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init UI Channel %d failed: %d\n", i + 2, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set UI Blender Route, enable Blender Pipes and apply the settings */
|
||||
|
||||
ret = a64_de_enable(UI_CHANNELS);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Enable Display Engine failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Fill Frame Buffers with Test Pattern. Should be called after
|
||||
* Display Engine is Enabled, or the rendered image will have
|
||||
* missing rows.
|
||||
*/
|
||||
|
||||
test_pattern();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the framebuffer video hardware associated with the display.
|
||||
*
|
||||
* There are multiple logic paths that may call up_fbinitialize() so any
|
||||
* implementation of up_fbinitialize() should be tolerant of being called
|
||||
* multiple times.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success; a negated errno value is returned on any
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_fbinitialize(int display)
|
||||
{
|
||||
int ret;
|
||||
static bool initialized = false;
|
||||
|
||||
/* Allow multiple calls */
|
||||
|
||||
DEBUGASSERT(display == 0);
|
||||
if (initialized)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
|
||||
/* Turn on Display Backlight */
|
||||
|
||||
ret = pinephone_lcd_backlight_enable(BACKLIGHT_BRIGHTNESS_PERCENT);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Enable Backlight failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init Timing Controller TCON0 */
|
||||
|
||||
ret = a64_tcon0_init(PANEL_WIDTH, PANEL_HEIGHT);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init Timing Controller TCON0 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset LCD Panel to Low */
|
||||
|
||||
ret = pinephone_lcd_panel_reset(false);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Reset LCD Panel failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init PMIC */
|
||||
|
||||
ret = pinephone_pmic_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init PMIC failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait 15 milliseconds for power supply and power-on init */
|
||||
|
||||
up_mdelay(15);
|
||||
|
||||
/* Enable MIPI DSI */
|
||||
|
||||
ret = a64_mipi_dsi_enable();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Enable MIPI DSI failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable MIPI D-PHY */
|
||||
|
||||
ret = a64_mipi_dphy_enable();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Enable MIPI D-PHY failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset LCD Panel to High */
|
||||
|
||||
ret = pinephone_lcd_panel_reset(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Reset LCD Panel failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait 15 milliseconds for LCD Panel */
|
||||
|
||||
up_mdelay(15);
|
||||
|
||||
/* Initialise ST7703 LCD Controller */
|
||||
|
||||
ret = pinephone_lcd_panel_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init ST7703 LCD Controller failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start MIPI DSI Bus in HSC and HSD modes */
|
||||
|
||||
ret = a64_mipi_dsi_start();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Start MIPI DSI failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init Display Engine */
|
||||
|
||||
ret = a64_de_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Init Display Engine failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait 160 milliseconds for Display Engine */
|
||||
|
||||
up_mdelay(160);
|
||||
|
||||
/* Render Frame Buffers with Display Engine */
|
||||
|
||||
ret = render_framebuffers();
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("Display Engine Frame Buffers failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbgetvplane
|
||||
*
|
||||
* Description:
|
||||
* Return a a reference to the framebuffer object for the specified video
|
||||
* plane of the specified plane. Many OSDs support multiple planes of
|
||||
* video.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
* vplane - Identifies the plane being queried.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL pointer to the frame buffer access structure is returned on
|
||||
* success; NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
{
|
||||
/* TODO: Implement up_fbgetvplane */
|
||||
|
||||
DEBUGASSERT(display == 0);
|
||||
_err("up_fbgetvplane not implemented\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize the framebuffer support for the specified display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_fbuninitialize(int display)
|
||||
{
|
||||
/* Uninitialize is not supported */
|
||||
|
||||
UNUSED(display);
|
||||
}
|
1017
boards/arm64/a64/pinephone/src/pinephone_lcd.c
Normal file
1017
boards/arm64/a64/pinephone/src/pinephone_lcd.c
Normal file
File diff suppressed because it is too large
Load Diff
98
boards/arm64/a64/pinephone/src/pinephone_lcd.h
Normal file
98
boards/arm64/a64/pinephone/src/pinephone_lcd.h
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* boards/arm64/a64/pinephone/src/pinephone_lcd.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_LCD_H
|
||||
#define __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_LCD_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Xingbangda XBD599 LCD Panel Width and Height (pixels) */
|
||||
|
||||
#define PINEPHONE_LCD_PANEL_WIDTH 720
|
||||
#define PINEPHONE_LCD_PANEL_HEIGHT 1440
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pinephone_lcd_backlight_enable
|
||||
*
|
||||
* Description:
|
||||
* Turn on the Backlight in Xingbangda XBD599 LCD Panel.
|
||||
*
|
||||
* Input Parameters:
|
||||
* percent - Percent Brightness
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pinephone_lcd_backlight_enable(uint32_t percent);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pinephone_lcd_panel_reset
|
||||
*
|
||||
* Description:
|
||||
* Reset the Xingbangda XBD599 LCD Panel.
|
||||
*
|
||||
* Input Parameters:
|
||||
* val - True if Reset should be set to High; False if Reset should be
|
||||
* set to Low
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pinephone_lcd_panel_reset(bool val);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pinephone_lcd_panel_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize the Sitronix ST7703 LCD Controller in Xingbangda XBD599
|
||||
* LCD Panel. Send 20 Initialization Commands to ST7703 over MIPI DSI.
|
||||
* Assumes that the LCD Panel has been powered on (via AXP803 PMIC),
|
||||
* MIPI DSI and D-PHY have been enabled on the SoC, and LCD Panel has
|
||||
* been Reset (to Low then High). After the LCD Panel has been
|
||||
* initialized, we may start MIPI DSI (in HSC and HSD modes) and
|
||||
* Display Engine.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pinephone_lcd_panel_init(void);
|
||||
|
||||
#endif /* __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_LCD_H */
|
282
boards/arm64/a64/pinephone/src/pinephone_pmic.c
Normal file
282
boards/arm64/a64/pinephone/src/pinephone_pmic.c
Normal file
@ -0,0 +1,282 @@
|
||||
/****************************************************************************
|
||||
* boards/arm64/a64/pinephone/src/pinephone_pmic.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Reference:
|
||||
*
|
||||
* "Rendering PinePhone's Display (DE and TCON0)"
|
||||
* https://lupyuen.github.io/articles/de
|
||||
*
|
||||
* "NuttX RTOS for PinePhone: Render Graphics in Zig"
|
||||
* https://lupyuen.github.io/articles/de2
|
||||
*
|
||||
* "AXP803 Page" refers to X-Powers AXP803 Data Sheet
|
||||
* https://lupyuen.github.io/images/AXP803_Datasheet_V1.0.pdf
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include "chip.h"
|
||||
#include "arm64_internal.h"
|
||||
#include "a64_rsb.h"
|
||||
#include "pinephone_pmic.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Address of AXP803 PMIC on Reduced Serial Bus */
|
||||
|
||||
#define AXP803_RT_ADDR 0x2d
|
||||
|
||||
/* AXP803 PMIC Registers and Bit Definitions ********************************/
|
||||
|
||||
/* DLDO1 Voltage Control (AXP803 Page 52) */
|
||||
|
||||
#define DLDO1_VOLTAGE_CONTROL 0x15
|
||||
#define DLDO1_VOLTAGE(n) ((n) << 0)
|
||||
|
||||
/* Output Power On-Off Control 2 (AXP803 Page 51) */
|
||||
|
||||
#define OUTPUT_POWER_ON_OFF_CONTROL2 0x12
|
||||
#define DLDO1_ON_OFF_CONTROL (1 << 3)
|
||||
#define DLDO2_ON_OFF_CONTROL (1 << 4)
|
||||
|
||||
/* GPIO0LDO and GPIO0 High Level Voltage Setting (AXP803 Page 77) */
|
||||
|
||||
#define GPIO0LDO_HIGH_LEVEL_VOLTAGE_SETTING 0x91
|
||||
#define GPIO0LDO_HIGH_LEVEL_VOLTAGE(n) ((n) << 0)
|
||||
|
||||
/* GPIO0 (GPADC) Control (AXP803 Page 76) */
|
||||
|
||||
#define GPIO0_CONTROL 0x90
|
||||
#define GPIO0_PIN_FUNCTION(n) ((n) << 0)
|
||||
|
||||
/* DLDO2 Voltage Control (AXP803 Page 52) */
|
||||
|
||||
#define DLDO2_VOLTAGE_CONTROL 0x16
|
||||
#define DLDO2_VOLTAGE(n) ((n) << 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmic_write
|
||||
*
|
||||
* Description:
|
||||
* Write a byte to an AXP803 PMIC Register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* reg - AXP803 Register ID
|
||||
* val - Byte to be written
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pmic_write(uint8_t reg, uint8_t val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Write to AXP803 PMIC on Reduced Serial Bus */
|
||||
|
||||
batinfo("reg=0x%x, val=0x%x\n", reg, val);
|
||||
ret = a64_rsb_write(AXP803_RT_ADDR, reg, val);
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("PMIC Write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmic_clrsetbits
|
||||
*
|
||||
* Description:
|
||||
* Clear and set the bits in an AXP803 PMIC Register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* reg - AXP803 Register ID
|
||||
* clr_mask - Bits to be masked
|
||||
* set_mask - Bits to be set
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pmic_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
|
||||
{
|
||||
int ret;
|
||||
uint8_t regval;
|
||||
|
||||
/* Read from AXP803 PMIC on Reduced Serial Bus */
|
||||
|
||||
batinfo("reg=0x%x, clr_mask=0x%x, set_mask=0x%x\n",
|
||||
reg, clr_mask, set_mask);
|
||||
ret = a64_rsb_read(AXP803_RT_ADDR, reg);
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("PMIC Read failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write to AXP803 PMIC on Reduced Serial Bus */
|
||||
|
||||
regval = (ret & ~clr_mask) | set_mask;
|
||||
ret = a64_rsb_write(AXP803_RT_ADDR, reg, regval);
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("PMIC Write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pinephone_pmic_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize the X-Powers AXP803 Power Management Integrated Circuit,
|
||||
* connected on Reduced Serial Bus. Power on the MIPI DSI Interface of
|
||||
* Xingbangda XBD599 LCD Panel. Doesn't switch on the LCD Panel
|
||||
* Backlight, which is controlled by PIO and PWM.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pinephone_pmic_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Set DLDO1 Voltage to 3.3V. DLDO1 powers the Front Camera / USB HSIC /
|
||||
* I2C Sensors.
|
||||
*/
|
||||
|
||||
/* DLDO1 Voltage Control (AXP803 Page 52)
|
||||
* Set Voltage (Bits 0 to 4) to 26 (2.6V + 0.7V = 3.3V)
|
||||
*/
|
||||
|
||||
batinfo("Set DLDO1 Voltage to 3.3V\n");
|
||||
ret = pmic_write(DLDO1_VOLTAGE_CONTROL, DLDO1_VOLTAGE(26));
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Set DLDO1 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Power on DLDO1 */
|
||||
|
||||
/* Output Power On-Off Control 2 (AXP803 Page 51)
|
||||
* Set DLDO1 On-Off Control (Bit 3) to 1 (Power On)
|
||||
*/
|
||||
|
||||
ret = pmic_clrsetbits(OUTPUT_POWER_ON_OFF_CONTROL2, 0,
|
||||
DLDO1_ON_OFF_CONTROL);
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Power on DLDO1 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set LDO Voltage to 3.3V. GPIO0LDO powers the Capacitive Touch Panel. */
|
||||
|
||||
/* 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)
|
||||
*/
|
||||
|
||||
batinfo("Set LDO Voltage to 3.3V\n");
|
||||
ret = pmic_write(GPIO0LDO_HIGH_LEVEL_VOLTAGE_SETTING,
|
||||
GPIO0LDO_HIGH_LEVEL_VOLTAGE(26));
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Set LDO failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable LDO Mode on GPIO0 */
|
||||
|
||||
/* GPIO0 (GPADC) Control (AXP803 Page 76)
|
||||
* Set GPIO0 Pin Function Control (Bits 0 to 2) to 0b11 (Low Noise LDO on)
|
||||
*/
|
||||
|
||||
batinfo("Enable LDO mode on GPIO0\n");
|
||||
ret = pmic_write(GPIO0_CONTROL, GPIO0_PIN_FUNCTION(0b11));
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Enable LDO failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set DLDO2 Voltage to 1.8V. DLDO2 powers the MIPI DSI Interface of
|
||||
* Xingbangda XBD599 LCD Panel.
|
||||
*/
|
||||
|
||||
/* DLDO2 Voltage Control (AXP803 Page 52)
|
||||
* Set Voltage (Bits 0 to 4) to 11 (1.1V + 0.7V = 1.8V)
|
||||
*/
|
||||
|
||||
batinfo("Set DLDO2 Voltage to 1.8V\n");
|
||||
ret = pmic_write(DLDO2_VOLTAGE_CONTROL, DLDO2_VOLTAGE(11));
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Set DLDO2 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Power on DLDO2 */
|
||||
|
||||
/* Output Power On-Off Control 2 (AXP803 Page 51)
|
||||
* Set DLDO2 On-Off Control (Bit 4) to 1 (Power On)
|
||||
*/
|
||||
|
||||
ret = pmic_clrsetbits(OUTPUT_POWER_ON_OFF_CONTROL2, 0,
|
||||
DLDO2_ON_OFF_CONTROL);
|
||||
if (ret < 0)
|
||||
{
|
||||
baterr("Power on DLDO2 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
53
boards/arm64/a64/pinephone/src/pinephone_pmic.h
Normal file
53
boards/arm64/a64/pinephone/src/pinephone_pmic.h
Normal file
@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
* boards/arm64/a64/pinephone/src/pinephone_pmic.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_PMIC_H
|
||||
#define __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_PMIC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pinephone_pmic_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize the X-Powers AXP803 Power Management Integrated Circuit,
|
||||
* connected on Reduced Serial Bus. Power on the MIPI DSI Interface of
|
||||
* Xingbangda XBD599 LCD Panel. Doesn't switch on the LCD Panel
|
||||
* Backlight, which is controlled by PIO and PWM.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pinephone_pmic_init(void);
|
||||
|
||||
#endif /* __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_PMIC_H */
|
Loading…
Reference in New Issue
Block a user