399 lines
10 KiB
C
399 lines
10 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
*/
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/string.h>
|
|
|
|
#include "extd_log.h"
|
|
#include "extd_factory.h"
|
|
#include "extd_info.h"
|
|
#include "external_display.h"
|
|
|
|
#include "dpi_dvt_test.h"
|
|
|
|
#if defined(CONFIG_MTK_HDMI_SUPPORT)
|
|
static struct HDMI_DRIVER *hdmi_tx_drv;
|
|
static int is_context_inited;
|
|
|
|
struct disp_ddp_path_config hdmi_factory_dpi_params;
|
|
struct DPI_PARAM_CONTEXT DPI_Params_Context;
|
|
|
|
struct _hdmi_factory_context {
|
|
bool hdmi_factory_inited;
|
|
bool hdmi_callback_returned;
|
|
};
|
|
|
|
static struct _hdmi_factory_context *_get_context(void)
|
|
{
|
|
static struct _hdmi_factory_context g_context;
|
|
|
|
if (!is_context_inited) {
|
|
memset((void *)&g_context, 0, sizeof(g_context));
|
|
is_context_inited = 1;
|
|
EXTD_FACTORY_LOG("[hdmi]%s set is_context_inited\n", __func__);
|
|
}
|
|
|
|
return &g_context;
|
|
}
|
|
|
|
#define pgc _get_context()
|
|
|
|
static void hdmi_factory_callback(enum HDMI_STATE state)
|
|
{
|
|
EXTD_FACTORY_LOG("[hdmi]%s, state: %d\n", __func__, state);
|
|
pgc->hdmi_callback_returned = state;
|
|
}
|
|
|
|
int hdmi_factory_mode_init(void)
|
|
{
|
|
EXTD_FACTORY_LOG("%s+\n", __func__);
|
|
|
|
hdmi_tx_drv = (struct HDMI_DRIVER *)HDMI_GetDriver();
|
|
if (!hdmi_tx_drv) {
|
|
EXTD_FACTORY_ERR("[hdmi]%s, hdmi_init fail, no hdmi driver\n",
|
|
__func__);
|
|
return -1;
|
|
}
|
|
hdmi_tx_drv->register_callback(hdmi_factory_callback);
|
|
|
|
pgc->hdmi_factory_inited = true;
|
|
EXTD_FACTORY_LOG("%s-\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
void hdmi_factory_dpi_parameters(int arg, int io_driving)
|
|
{
|
|
enum HDMI_POLARITY clk_pol = HDMI_POLARITY_RISING,
|
|
de_pol = HDMI_POLARITY_RISING,
|
|
hsync_pol = HDMI_POLARITY_RISING,
|
|
vsync_pol = HDMI_POLARITY_RISING;
|
|
unsigned int dpi_clock = 0;
|
|
unsigned int dpi_clk_div = 0, hsync_pulse_width = 0,
|
|
hsync_back_porch = 0, hsync_front_porch = 0;
|
|
unsigned int vsync_pulse_width = 0, vsync_back_porch = 0,
|
|
vsync_front_porch = 0;
|
|
|
|
switch (arg) {
|
|
case HDMI_VIDEO_720x480p_60Hz:
|
|
{
|
|
clk_pol = HDMI_POLARITY_FALLING;
|
|
de_pol = HDMI_POLARITY_RISING;
|
|
hsync_pol = HDMI_POLARITY_RISING;
|
|
vsync_pol = HDMI_POLARITY_RISING;
|
|
|
|
dpi_clk_div = 2;
|
|
|
|
hsync_pulse_width = 62;
|
|
hsync_back_porch = 60;
|
|
hsync_front_porch = 16;
|
|
|
|
vsync_pulse_width = 6;
|
|
vsync_back_porch = 30;
|
|
vsync_front_porch = 9;
|
|
|
|
DPI_Params_Context.bg_height =
|
|
((480 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.bg_width =
|
|
((720 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.hdmi_width =
|
|
720 - DPI_Params_Context.bg_width;
|
|
DPI_Params_Context.hdmi_height =
|
|
480 - DPI_Params_Context.bg_height;
|
|
DPI_Params_Context.output_video_resolution =
|
|
HDMI_VIDEO_720x480p_60Hz;
|
|
dpi_clock = HDMI_VIDEO_720x480p_60Hz;
|
|
break;
|
|
}
|
|
case HDMI_VIDEO_1280x720p_60Hz:
|
|
{
|
|
if (strncmp(CONFIG_CUSTOM_KERNEL_HDMI, "ANX7625", 7) == 0)
|
|
clk_pol = HDMI_POLARITY_RISING;
|
|
else
|
|
clk_pol = HDMI_POLARITY_FALLING;
|
|
|
|
de_pol = HDMI_POLARITY_RISING;
|
|
hsync_pol = HDMI_POLARITY_FALLING;
|
|
vsync_pol = HDMI_POLARITY_FALLING;
|
|
|
|
dpi_clk_div = 2;
|
|
|
|
hsync_pulse_width = 40;
|
|
hsync_back_porch = 220;
|
|
hsync_front_porch = 110;
|
|
|
|
vsync_pulse_width = 5;
|
|
vsync_back_porch = 20;
|
|
vsync_front_porch = 5;
|
|
dpi_clock = HDMI_VIDEO_1280x720p_60Hz;
|
|
|
|
DPI_Params_Context.bg_height =
|
|
((720 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.bg_width =
|
|
((1280 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.hdmi_width =
|
|
1280 - DPI_Params_Context.bg_width;
|
|
DPI_Params_Context.hdmi_height =
|
|
720 - DPI_Params_Context.bg_height;
|
|
|
|
DPI_Params_Context.output_video_resolution =
|
|
HDMI_VIDEO_1280x720p_60Hz;
|
|
break;
|
|
}
|
|
case HDMI_VIDEO_1920x1080p_30Hz:
|
|
{
|
|
clk_pol = HDMI_POLARITY_FALLING;
|
|
de_pol = HDMI_POLARITY_RISING;
|
|
hsync_pol = HDMI_POLARITY_FALLING;
|
|
vsync_pol = HDMI_POLARITY_FALLING;
|
|
|
|
dpi_clk_div = 2;
|
|
|
|
hsync_pulse_width = 44;
|
|
hsync_back_porch = 148;
|
|
hsync_front_porch = 88;
|
|
|
|
vsync_pulse_width = 5;
|
|
vsync_back_porch = 36;
|
|
vsync_front_porch = 4;
|
|
|
|
DPI_Params_Context.bg_height =
|
|
((1080 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.bg_width =
|
|
((1920 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.hdmi_width =
|
|
1920 - DPI_Params_Context.bg_width;
|
|
DPI_Params_Context.hdmi_height =
|
|
1080 - DPI_Params_Context.bg_height;
|
|
|
|
DPI_Params_Context.output_video_resolution =
|
|
HDMI_VIDEO_1920x1080p_30Hz;
|
|
dpi_clock = HDMI_VIDEO_1920x1080p_30Hz;
|
|
break;
|
|
}
|
|
case HDMI_VIDEO_1920x1080p_60Hz:
|
|
{
|
|
clk_pol = HDMI_POLARITY_FALLING;
|
|
de_pol = HDMI_POLARITY_RISING;
|
|
hsync_pol = HDMI_POLARITY_FALLING;
|
|
vsync_pol = HDMI_POLARITY_FALLING;
|
|
|
|
dpi_clk_div = 2;
|
|
|
|
hsync_pulse_width = 44;
|
|
hsync_back_porch = 148;
|
|
hsync_front_porch = 88;
|
|
|
|
vsync_pulse_width = 5;
|
|
vsync_back_porch = 36;
|
|
vsync_front_porch = 4;
|
|
|
|
DPI_Params_Context.bg_height =
|
|
((1080 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.bg_width =
|
|
((1920 * DPI_Params_Context.scaling_factor) /
|
|
100 >> 2) << 2;
|
|
DPI_Params_Context.hdmi_width =
|
|
1920 - DPI_Params_Context.bg_width;
|
|
DPI_Params_Context.hdmi_height =
|
|
1080 - DPI_Params_Context.bg_height;
|
|
|
|
DPI_Params_Context.output_video_resolution =
|
|
HDMI_VIDEO_1920x1080p_60Hz;
|
|
dpi_clock = HDMI_VIDEO_1920x1080p_60Hz;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
hdmi_factory_dpi_params.dispif_config.dpi.width =
|
|
DPI_Params_Context.hdmi_width;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.height =
|
|
DPI_Params_Context.hdmi_height;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.bg_width =
|
|
DPI_Params_Context.bg_width;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.bg_height =
|
|
DPI_Params_Context.bg_height;
|
|
|
|
hdmi_factory_dpi_params.dispif_config.dpi.clk_pol = clk_pol;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.de_pol = de_pol;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.vsync_pol = vsync_pol;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.hsync_pol = hsync_pol;
|
|
|
|
hdmi_factory_dpi_params.dispif_config.dpi.hsync_pulse_width =
|
|
hsync_pulse_width;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.hsync_back_porch =
|
|
hsync_back_porch;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.hsync_front_porch =
|
|
hsync_front_porch;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.vsync_pulse_width =
|
|
vsync_pulse_width;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.vsync_back_porch =
|
|
vsync_back_porch;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.vsync_front_porch =
|
|
vsync_front_porch;
|
|
|
|
hdmi_factory_dpi_params.dispif_config.dpi.format = 0;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.rgb_order = 0;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.i2x_en = true;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.i2x_edge = 2;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.embsync = false;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.io_driving_current =
|
|
(enum LCM_DRIVING_CURRENT)io_driving;
|
|
hdmi_factory_dpi_params.dispif_config.dpi.dpi_clock = dpi_clock;
|
|
|
|
EXTD_FACTORY_LOG("[hdmi]%s:%d\n", __func__, arg);
|
|
}
|
|
|
|
int hdmi_factory_mode_test(enum HDMI_FACTORY_TEST test_step, void *info)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!pgc->hdmi_factory_inited)
|
|
hdmi_factory_mode_init();
|
|
|
|
switch (test_step) {
|
|
case STEP1_CHIP_INIT:
|
|
{
|
|
EXTD_FACTORY_LOG("[hdmi] STEP1_CHIP_INIT\n");
|
|
hdmi_tx_drv->power_on();
|
|
hdmi_tx_drv->audio_enable(1);
|
|
break;
|
|
}
|
|
case STEP2_JUDGE_CALLBACK:
|
|
{
|
|
int hdmi_status = (int)pgc->hdmi_callback_returned;
|
|
|
|
EXTD_FACTORY_LOG("[hdmi] STEP2_JUDGE_CALLBACK: %d\n",
|
|
pgc->hdmi_callback_returned);
|
|
if (copy_to_user(info, &hdmi_status, sizeof(hdmi_status))) {
|
|
EXTD_FACTORY_ERR("[HDMI]copy_to_user failed! line:%d\n",
|
|
__LINE__);
|
|
ret = -1;
|
|
}
|
|
break;
|
|
}
|
|
case STEP3_START_DPI_AND_CONFIG:
|
|
{
|
|
/*
|
|
* test_type(24bit-31bit): resolution
|
|
* test_case(16bit-23bit):
|
|
* hsync/vsync/de/clk io drivint(8bit-15bit),
|
|
* data io driving(0bit-7bit)
|
|
* test_type(factory:0, HQA:1, DVT:2)
|
|
*/
|
|
int test_type = ((long int)info >> 24);
|
|
int resolution = (((long int)info >> 16) & 0xFF);
|
|
int test_case = resolution;
|
|
int io_driving = ((long int)info & 0xFFFF);
|
|
|
|
EXTD_FACTORY_LOG("STEP3_START_DPI_AND_CONFIG +\n");
|
|
EXTD_FACTORY_LOG("resolution/test case:%d, driving:0x%x\n",
|
|
resolution, io_driving);
|
|
|
|
if (test_type == 0) { /* Factory mode */
|
|
hdmi_factory_dpi_parameters(resolution, io_driving);
|
|
ext_disp_factory_test(0, (void *)
|
|
&hdmi_factory_dpi_params);
|
|
|
|
msleep(100);
|
|
hdmi_tx_drv->video_config(resolution,
|
|
HDMI_VIN_FORMAT_RGB888,
|
|
HDMI_VOUT_FORMAT_RGB888);
|
|
} else if (test_type == 1) { /* HQA */
|
|
hdmi_factory_dpi_parameters(resolution, io_driving);
|
|
ext_disp_factory_test(0, (void *)
|
|
&hdmi_factory_dpi_params);
|
|
|
|
EXTD_FACTORY_LOG("[hdmi] Not need video config\n");
|
|
} else if (test_type == 2) { /* DVT */
|
|
EXTD_FACTORY_LOG("[hdmi] Start DPI DVT Test\n");
|
|
dpi_dvt_ioctl(test_case);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case STEP4_DPI_STOP_AND_POWER_OFF:
|
|
{
|
|
int test_type = ((long int)info >> 24);
|
|
|
|
EXTD_FACTORY_LOG("[hdmi] STEP4_DPI_STOP_AND_POWER_OFF\n");
|
|
hdmi_tx_drv->power_off();
|
|
if (test_type == 0)
|
|
ext_disp_factory_test(1, (void *)
|
|
&hdmi_factory_dpi_params);
|
|
|
|
pgc->hdmi_factory_inited = false;
|
|
is_context_inited = false;
|
|
|
|
hdmi_tx_drv->unregister_callback(hdmi_factory_callback);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_MTK_HDMI_SUPPORT */
|
|
|
|
const struct EXTD_DRIVER *EXTD_Factory_HDMI_Driver(void)
|
|
{
|
|
static const struct EXTD_DRIVER extd_factory_hdmi = {
|
|
#if defined(CONFIG_MTK_HDMI_SUPPORT)
|
|
.init = hdmi_factory_mode_init,
|
|
.deinit = NULL,
|
|
.enable = NULL,
|
|
.power_enable = NULL,
|
|
.set_audio_enable = NULL,
|
|
.set_resolution = NULL,
|
|
.get_dev_info = NULL,
|
|
.get_capability = NULL,
|
|
.get_edid = NULL,
|
|
.wait_vsync = NULL,
|
|
.fake_connect = NULL,
|
|
.factory_mode_test = hdmi_factory_mode_test,
|
|
.ioctl = NULL
|
|
#else
|
|
.init = 0
|
|
#endif
|
|
};
|
|
|
|
return &extd_factory_hdmi;
|
|
}
|
|
|
|
const struct EXTD_DRIVER *EXTD_Factory_EPD_Driver(void)
|
|
{
|
|
static const struct EXTD_DRIVER extd_factory_epd = {
|
|
#if defined(CONFIG_MTK_EPD_SUPPORT)
|
|
.init = NULL,
|
|
.deinit = NULL,
|
|
.enable = NULL,
|
|
.power_enable = NULL,
|
|
.set_audio_enable = NULL,
|
|
.set_resolution = NULL,
|
|
.get_dev_info = NULL,
|
|
.get_capability = NULL,
|
|
.get_edid = NULL,
|
|
.wait_vsync = NULL,
|
|
.fake_connect = NULL,
|
|
.factory_mode_test = epd_factory_mode_test,
|
|
.ioctl = NULL
|
|
#else
|
|
.init = 0
|
|
#endif
|
|
};
|
|
|
|
return &extd_factory_epd;
|
|
}
|