Files
E3/e3_176_ref-补丁/drivers/source/dispss/sdrv_lvds_drv.c
2026-01-09 16:48:24 +08:00

196 lines
5.1 KiB
C

/**
* @file sdrv_lvds_drv.c
* @brief sdrv lvds driver source.
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#include <board.h>
#include <dispss/disp.h>
#include <dispss/disp_reg_rw.h>
#include <dispss/dispss_log.h>
#include <dispss/lvds_reg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>
#include <udelay/udelay.h>
enum LVDS_CHANNEL { LVDS_CH0 = 0, LVDS_CH_MAX_NUM };
enum { LVDS_SEPARATE_MODE = 0, LVDS_MODE_MAX_NUM };
enum {
LVDS_PIXEL_BPP_NC = -1,
LVDS_PIXEL_BPP_16,
LVDS_PIXEL_BPP_24,
LVDS_PIXEL_BPP_30,
};
enum { SOFT_RESET_CH0 = 0, SOFT_RESET_CH_MAX_NUM };
typedef enum {
PIXEL_FORMAT_18_BIT = 0x0,
PIXEL_FORMAT_24_BIT = 0x1,
PIXEL_FORMAT_30_BIT = 0x2
} LVDS_PIXEL_FORMAT;
enum { DUALLODD_ODD = 0x0, DUALLODD_EVEN = 0x1 };
struct lvds_chx_info {
uint32_t ch_idx;
uint32_t ch_mode;
uint32_t pixel_fmt;
uint32_t map_format;
uint32_t vsync_pol;
};
static unsigned int lvds_get_reg_base(void)
{
static unsigned int base = 0;
if (base == 0)
base = LVDS_BASE;
return base;
}
static int get_lvds_pixel_bpp(int pixel_bpp)
{
switch (pixel_bpp) {
case 16:
return LVDS_PIXEL_BPP_16;
case 24:
return LVDS_PIXEL_BPP_24;
case 30:
return LVDS_PIXEL_BPP_30;
default:
return LVDS_PIXEL_BPP_NC;
}
}
status_t lvds_soft_reset(void)
{
unsigned int val = 0;
addr_t base = lvds_get_reg_base();
/*set to high*/
val = disp_read(base, LVDS_SOFT_RESET);
val = reg_value(1, val, CH0_SOFT_RESET_SHIFT, CH0_SOFT_RESET_MASK);
disp_write(base, LVDS_SOFT_RESET, val);
udelay(10);
/*set to low*/
val = reg_value(0, val, CH0_SOFT_RESET_SHIFT, CH0_SOFT_RESET_MASK);
disp_write(base, LVDS_SOFT_RESET, val);
return SDRV_DISPSS_STATUS_OK;
}
static void lvds_channel_config(addr_t base, struct lvds_chx_info *info)
{
unsigned int val = 0;
int i = 0;
val = disp_read(base, DC1_MUX_CTRL);
val = reg_value(1, val, PARAL_TO_LVDS_EN_SHIFT, PARAL_TO_LVDS_EN_MASK);
disp_write(base, DC1_MUX_CTRL, val);
val = disp_read(base, LVDS_CH0_CTRL);
val = reg_value(0, val, CH0_DUALMODE_SHIFT, CH0_DUALMODE_MASK);
val = reg_value(info->pixel_fmt, val, CH0_BPP_SHIFT, CH0_BPP_MASK);
val = reg_value(info->map_format, val, CH0_FORMAT_SHIFT, CH0_FORMAT_MASK);
val = reg_value(info->vsync_pol, val, CH0_VSYNC_POL_SHIFT,
CH0_VSYNC_POL_MASK);
val = reg_value(0, val, CH0_MUX_SHIFT, CH0_MUX_MASK);
val = reg_value(1, val, CH0_EN_SHIFT, CH0_EN_MASK);
disp_write(base, LVDS_CH0_CTRL, val);
val = disp_read(base, LVDS_CH0_PAD_COM_SET);
val = reg_value(1, val, CH0_TEST_RXEN_SHIFT, CH0_TEST_RXEN_MASK);
val = reg_value(1, val, CH0_TEST_PULLDN_SHIFT, CH0_TEST_PULLDN_MASK);
disp_write(base, LVDS_CH0_PAD_COM_SET, val);
for (i = 0; i < 5; i++) {
val = disp_read(base, LVDS_CH0_PAD_SET_(i));
val = reg_value(1, val, CH0_TXEN_SHIFT, CH0_TXEN_MASK);
val = reg_value(1, val, CH0_RTERM_EN_SHIFT, CH0_RTERM_EN_MASK);
disp_write(base, LVDS_CH0_PAD_SET_(i), val);
}
}
/**
* @brief lvds channel enable.
*
* This function control the lvds channel output.
*
* @param [in] enable false->disable; true->enable.
*/
void sdrv_lvds_channel_enable(bool enable)
{
int val = 0;
int i = 0;
addr_t base = lvds_get_reg_base();
DISPSS_LOG_FUNC();
val = disp_read(base, LVDS_CH0_PAD_COM_SET);
if (enable) {
val = reg_value(1, val, CH0_TEST_RXEN_SHIFT, CH0_TEST_RXEN_MASK);
val = reg_value(1, val, CH0_TEST_PULLDN_SHIFT, CH0_TEST_PULLDN_MASK);
} else {
val = reg_value(0, val, CH0_TEST_RXEN_SHIFT, CH0_TEST_RXEN_MASK);
val = reg_value(0, val, CH0_TEST_PULLDN_SHIFT, CH0_TEST_PULLDN_MASK);
}
disp_write(base, LVDS_CH0_PAD_COM_SET, val);
for (i = 0; i < 5; i++) {
val = disp_read(base, LVDS_CH0_PAD_SET_(i));
if (enable) {
val = reg_value(1, val, CH0_TXEN_SHIFT, CH0_TXEN_MASK);
val = reg_value(1, val, CH0_RTERM_EN_SHIFT, CH0_RTERM_EN_MASK);
} else {
val = reg_value(0, val, CH0_TXEN_SHIFT, CH0_TXEN_MASK);
val = reg_value(0, val, CH0_RTERM_EN_SHIFT, CH0_RTERM_EN_MASK);
}
disp_write(base, LVDS_CH0_PAD_SET_(i), val);
}
}
status_t sdrv_lvds_init(struct sdrv_panel *panel)
{
status_t ret = SDRV_DISPSS_STATUS_OK;
if (panel != NULL) {
int lvds_pixel_bpp;
addr_t base = lvds_get_reg_base();
struct lvds_chx_info chx_info;
DISPSS_LOG_FUNC();
memset(&chx_info, 0, sizeof(struct lvds_chx_info));
lvds_pixel_bpp = get_lvds_pixel_bpp(panel->pixel_bpp);
chx_info.map_format = panel->timing->map_format;
chx_info.vsync_pol = panel->timing->vsync_pol;
chx_info.pixel_fmt = lvds_pixel_bpp;
chx_info.ch_mode = LVDS_SEPARATE_MODE;
chx_info.ch_idx = LVDS_CH0;
lvds_channel_config(base, &chx_info);
} else {
DISPSS_LOG_INFO("sdrv_panel arg err");
ret = SDRV_DISPSS_STATUS_INVALID_PARAM;
}
return ret;
}