unplugged-kernel/drivers/misc/mediatek/ext_disp/mt6765/extd_factory.c

411 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(struct _hdmi_factory_context));
is_context_inited = 1;
EXTDINFO("[hdmi]%s set is_context_inited\n",
__func__);
}
return &g_context;
}
#define pgc _get_context()
static void hdmi_factory_callback(enum HDMI_STATE state)
{
EXTDINFO("[hdmi]%s, state: %d\n", __func__, state);
pgc->hdmi_callback_returned = state;
}
int hdmi_factory_mode_init(void)
{
EXTDFUNC();
hdmi_tx_drv = (struct HDMI_DRIVER *) HDMI_GetDriver();
if (hdmi_tx_drv == NULL) {
EXTDERR
("[hdmi]%s, hdmi_init fail, can't get hdmi driver\n",
__func__);
return -1;
}
hdmi_tx_drv->register_callback(hdmi_factory_callback);
pgc->hdmi_factory_inited = true;
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 =
(LCM_DRIVING_CURRENT) io_driving;
hdmi_factory_dpi_params.dispif_config.dpi.dpi_clock = dpi_clock;
EXTDMSG("[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 == false)
hdmi_factory_mode_init();
switch (test_step) {
case STEP1_CHIP_INIT:
{
EXTDMSG("[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;
EXTDMSG("[hdmi] STEP2_JUDGE_CALLBACK: %d\n",
pgc->hdmi_callback_returned);
if (copy_to_user
(info, &hdmi_status, sizeof(hdmi_status))) {
EXTDERR
("[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 = ((int)info >> 24);
int resolution = (((int)info >> 16) & 0xFF);
int test_case = resolution;
int io_driving = ((int)info & 0xFFFF);
EXTDMSG("STEP3_START_DPI_AND_CONFIG +\n");
EXTDMSG
("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);
EXTDMSG
("[hdmi] Not need video config\n");
} else if (test_type == 2) { /* DVT */
EXTDMSG("[hdmi] Start DPI DVT Test\n");
dpi_dvt_ioctl(test_case);
}
break;
}
case STEP4_DPI_STOP_AND_POWER_OFF:
{
int test_type = ((int)info >> 24);
EXTDMSG("[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;
}