This commit is contained in:
刘可亮
2024-10-30 16:50:31 +08:00
parent 0ef85b55da
commit 661e71562d
458 changed files with 46555 additions and 12133 deletions

View File

@@ -225,3 +225,26 @@ endif
config AIC_PANEL_SPI_EMULATION
bool
default n
config AIC_SCREEN_CROP
bool "Enable screen crop"
default n
help
Some LCD screen need to be cropped, the effective area displayed is less
than the timing signal.
If unsure select "N".
if AIC_SCREEN_CROP
config AIC_SCREEN_CROP_POS_X
int "screen crop x position of pixels"
default 0
config AIC_SCREEN_CROP_POS_Y
int "screen crop y position of pixels"
default 0
config AIC_SCREEN_CROP_WIDTH
int "screen crop width"
default 0
config AIC_SCREEN_CROP_HEIGHT
int "screen crop height"
default 0
endif

View File

@@ -21,17 +21,42 @@
/**
* lvds channel output order
*
* default D3 CK D2 D1 D0
* 4 3 2 1 0
* link 0 default D3 CK D2 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
*
* link 1 default D3 CK D2 D1 D0
* PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
*
*
* link 0 example:
* D2 CK D3 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
*
* AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D2, LVDS_CK, LVDS_D3, LVDS_D1, LVDS_D0)
* link1 example is the same as link0
*/
#define AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
#define AIC_LVDS_LINK1_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
/**
* lvds channel polarities
*
* link 0 default PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
* N/P N/P N/P N/P N/P
*
* link 1 default PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
* N/P N/P N/P N/P N/P
*
*
* link 0 example:
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
* N/P P/N N/P P/N N/P
*
* AIC_LVDS_LINK0_POL 0b01010
* link1 example is the same as link0
*/
#define AIC_LVDS_LINK0_POL 0x0
#define AIC_LVDS_LINK1_POL 0x0
#define AIC_LVDS_LINK0_POL 0b00000
#define AIC_LVDS_LINK1_POL 0b00000
/**
* lvds channel phy config
@@ -43,13 +68,41 @@
* MIPI-DSI options
*/
/* data line assignments */
/**
* data lane assignments
*
* default D3 D2 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
*
* example D0 D1 D2 D3
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
*
* LANE_ASSIGNMENTS 0x0123
*/
#define LANE_ASSIGNMENTS 0x3210
/* data line polarities */
/**
* data lane polarities
*
* default PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
* N/P N/P N/P N/P
*
* example PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
* P/N N/P P/N N/P
*
* LANE_POLARITIES 0b1010
*/
#define LANE_POLARITIES 0b0000
/* data clk inverse */
/**
* data clk inverse
*
* default PD24/PD25
* N/P
*
* CLK_INVERSE 1 PD24/PD25
* P/N
*/
#define CLK_INVERSE 0
/* virtual channel id */

View File

@@ -17,9 +17,11 @@
#define DE_TIMEOUT_MS 100
static unsigned int vsync_flag = 0;
static struct aic_de_comp *g_aic_de_comp;
static int aic_de_set_gamma_config(struct aicfb_gamma_config *gamma);
static int aic_de_set_ccm_config(struct aicfb_ccm_config *ccm);
static struct aic_de_comp *aic_de_request_drvdata(void)
{
return g_aic_de_comp;
@@ -38,10 +40,8 @@ static irqreturn_t aic_de_handler(int irq, void *ctx)
status = de_timing_interrupt_status(comp->regs);
de_timing_interrupt_clean_status(comp->regs, status);
if ((status & TIMING_INIT_V_BLANK_FLAG) && vsync_flag) {
vsync_flag = 0;
if (status & TIMING_INIT_V_BLANK_FLAG)
aicos_wqueue_wakeup(comp->vsync_queue);
}
if (comp->scaler_active & SCALER0_CTRL_ACTIVE) {
comp->scaler_active = comp->scaler_active & 0xF;
@@ -237,6 +237,9 @@ static int aic_de_timing_enable(void)
de_timing_enable_interrupt(comp->regs, true, TIMING_INIT_UNDERFLOW_FLAG);
#endif
aic_de_set_gamma_config(&comp->gamma);
aic_de_set_ccm_config(&comp->ccm);
de_timing_enable(comp->regs, 1);
aic_de_release_drvdata();
@@ -257,7 +260,6 @@ static int aic_de_wait_for_vsync(void)
struct aic_de_comp *comp = aic_de_request_drvdata();
int ret = 0;
vsync_flag = 1;
ret = aicos_wqueue_wait(comp->vsync_queue, DE_TIMEOUT_MS);
if (ret < 0) {
hal_log_err("DE wait vsync irq failed, ret: %d\n", ret);

View File

@@ -208,6 +208,11 @@ int config_ui_layer_rect(struct aic_de_comp *comp,
de_ui_layer_enable(comp->regs, 1);
}
#ifdef AIC_SCREEN_CROP
x_offset += AIC_SCREEN_CROP_POS_X;
y_offset += AIC_SCREEN_CROP_POS_Y;
#endif
de_ui_layer_set_rect(comp->regs, in_w, in_h, x_offset, y_offset,
stride0, addr0, layer_data->rect_id);
de_ui_layer_rect_enable(comp->regs, layer_data->rect_id, 1);

View File

@@ -746,6 +746,18 @@ static int de_vi_layer_config_format(struct aic_de_comp *comp,
return -EINVAL;
}
static void de_vi_layer_config_crop_pos(struct aic_de_comp *comp,
struct aicfb_layer_data *layer_data)
{
#ifdef AIC_SCREEN_CROP
u32 x_offset = layer_data->pos.x + AIC_SCREEN_CROP_POS_X;
u32 y_offset = layer_data->pos.y + AIC_SCREEN_CROP_POS_Y;
reg_write(comp->regs + VIDEO_LAYER_OFFSET,
VIDEO_LAYER_OFFSET_SET(x_offset, y_offset));
#endif
}
int config_video_layer(struct aic_de_comp *comp,
struct aicfb_layer_data *layer_data)
{
@@ -766,6 +778,7 @@ int config_video_layer(struct aic_de_comp *comp,
}
de_vi_layer_config_format(comp, format_info, layer_data);
de_vi_layer_config_crop_pos(comp, layer_data);
return 0;
}

View File

@@ -688,15 +688,20 @@ static void aicfb_fb_info_setup(struct aicfb_info *fbi)
fbi->fb_rotate = 0;
#endif
#ifdef AIC_SCREEN_CROP
active_w = AIC_SCREEN_CROP_WIDTH;
active_h = AIC_SCREEN_CROP_HEIGHT;
#else
active_w = fbi->panel->timings->hactive;
active_h = fbi->panel->timings->vactive;
#endif
if (fbi->fb_rotate == 90 || fbi->fb_rotate == 270)
{
active_w = fbi->panel->timings->vactive;
active_h = fbi->panel->timings->hactive;
}
else
{
active_w = fbi->panel->timings->hactive;
active_h = fbi->panel->timings->vactive;
u32 tmp = active_w;
active_w = active_h;
active_h = tmp;
}
stride = ALIGN_8B(active_w * bpp / 8);
@@ -724,8 +729,8 @@ static void fb_color_block(struct aicfb_info *fbi)
};
unsigned char *pos = (unsigned char *)fbi->fb_start;
width = fbi->panel->timings->hactive;
height = fbi->panel->timings->vactive;
width = fbi->width;
height = fbi->height;
switch (fbi->bits_per_pixel) {
#if defined(AICFB_ARGB8888) || defined(AICFB_ABGR8888) || defined(AICFB_XRGB8888)
@@ -818,7 +823,6 @@ static void aicfb_update_alpha(struct aicfb_info *fbi)
static void aicfb_update_layer(struct aicfb_info *fbi)
{
struct platform_driver *de = fbi->de;
struct aic_panel *panel = fbi->panel;
struct aicfb_layer_data layer = {0};
layer.layer_id = AICFB_LAYER_TYPE_UI;
@@ -830,11 +834,10 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
switch (fbi->fb_rotate)
{
case 0:
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->width;
layer.buf.size.height = fbi->height;
layer.buf.stride[0] = fbi->stride;
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start;
layer.buf.format = AICFB_FORMAT;
break;
#ifdef AIC_FB_ROTATE_EN
case 90:
@@ -843,16 +846,15 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
unsigned int stride = ALIGN_8B(fbi->height * fbi->bits_per_pixel / 8);
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->height;
layer.buf.size.height = fbi->width;
layer.buf.stride[0] = stride;
break;
}
case 180:
pr_info("rotate 180\n");
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->width;
layer.buf.size.height = fbi->height;
layer.buf.stride[0] = fbi->stride;
break;
#endif