summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorOtavio Salvador <otavio@ossystems.com.br>2017-06-17 10:36:40 -0300
committerOtavio Salvador <otavio@ossystems.com.br>2017-06-17 10:36:40 -0300
commit683b9eda58bdc48ad6606f22ca318f1d2200934d (patch)
tree7acde2eff67256e06cae0419b03af38c5503e5c1 /drivers/video
parenta4418c438de6ad397fd17f006ca86257fb9ec5a6 (diff)
parent30278abfe0977b1d2f065271ce1ea23c0e2d1b6e (diff)
Merge remote-tracking branch 'imx/imx_4.1.15_2.0.0_ga' into 4.1-2.0.x-imx
* imx/imx_4.1.15_2.0.0_ga: (157 commits) MLK-14762 ARM: dts: imx6sll-evk: correct gpio pin for lcd power control MLK-14285-3 usb: phy: mxs: optimize disconnect line condition MLK-14285-2 usb: chipidea: set mode for usb phy driver MLK-14285-1 usb: phy: add usb mode for usb_phy MLK-14747 driver: cpufreq: Correct dc regulator voltage on imx6ull MLK-14720 epdc: correct WFE setting when bypass legacy process MLK-13801-02 ARM: dts: Correct the gpt timer clock source on imx6ul/ull/sll MLK-13801-01 ARM: imx: add gpt_3m clock on imx6sll MLK-14680 pxp/epdc: add LUT cancellation feature MLK-14518-2 pxp: set data path for pxp after reset MLK-14518-1 pxp: initialize pxp according to recommended flow MLK-14516 epdc: bypass pxp legacy process when there's no transformation MLK-14369 epdc: sync LUT status to PXP before enable collision detection MLK-13198 pxp: imx7d: fix error histogram status report issue MLK-13917 pxp: fix build error for pxp library in user space MLK-13862-2 epdc/pxp: imx6ull/imx6sll: enhance the LUT cleanup flow to avoid stalling display MLK-13862-1 epdc/pxp: imx7d: enhance the LUT cleanup flow to avoid stalling display MLK-14697 ARM: dts: imx: update the setpoint data of imx6sll MXSCM-266 arm: dts: increase lpddr2 voltage to 1.25V MXSCM-265: dts: place imx6sxscm dtb files under CONFIG_SOC_IMX6SX ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c201
1 files changed, 125 insertions, 76 deletions
diff --git a/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c b/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
index 7db2503ee38b..a25a66186148 100644
--- a/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
+++ b/drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
*
+ * Copyright 2017 NXP
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -211,6 +213,7 @@ struct mxc_epdc_fb_data {
u32 *lut_update_order; /* Array size = number of luts */
u64 epdc_colliding_luts;
u64 luts_complete_wb;
+ u64 luts_complete;
struct completion updates_done;
struct delayed_work epdc_done_work;
struct workqueue_struct *epdc_submit_workqueue;
@@ -245,6 +248,7 @@ struct mxc_epdc_fb_data {
int epdc_wb_mode;
struct pxp_collision_info col_info;
u32 hist_status;
+ u32 pixel_nums;
struct regmap *gpr;
u8 req_gpr;
@@ -462,9 +466,10 @@ static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
struct update_data_list *upd_data_list);
static int pxp_wfe_b_process_update(struct mxc_epdc_fb_data *fb_data,
struct mxcfb_rect *update_region);
-static int pxp_wfe_b_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
+static int pxp_wfe_a_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
u32 src_width, u32 src_height);
-static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat);
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat,
+ u32 *pixel_nums);
static void draw_mode0(struct mxc_epdc_fb_data *fb_data);
static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data);
@@ -1000,7 +1005,6 @@ static inline bool epdc_any_luts_real_available(void)
return false;
}
-
static inline bool epdc_any_luts_available(void)
{
#ifdef EPDC_STANDARD_MODE
@@ -1036,20 +1040,23 @@ static inline void epdc_reset_used_lut(void)
#ifdef EPDC_STANDARD_MODE
/*
- * When all the 63 LUT are all marked as USED, a clean-up operation is required
- * to the working buffer. The cleanup operation can only be initiated when all
- * the LUT are at IDLE state on the EPDC. During the cleanup, none of the LUT
- * should not be activated on the EPDC.
+ * in previous flow, when all LUTs are used, the LUT cleanup operation
+ * need to wait for all the LUT to finish, it will not happen util last LUT
+ * is done. while in new flow, the cleanup operation does not need to wait
+ * for all LUTs to finish, instead it can start when there's LUT's done.
+ * The saved time is multiple LUT operation time.
*/
static int epdc_choose_next_lut(struct mxc_epdc_fb_data *fb_data, int *next_lut)
{
while (!epdc_any_luts_available()) {
-
- while (epdc_any_luts_active(fb_data->rev))
- ;
+ u64 luts_complete = fb_data->luts_complete;
pxp_clear_wb_work_func(fb_data);
+ used_luts &= ~luts_complete;
+ fb_data->luts_complete &= ~luts_complete;
}
+ used_luts |= 0x1;
+
if ((u32)used_luts != ~0UL)
*next_lut = ffz((u32)used_luts);
else if ((u32)(used_luts >> 32) != ~0UL)
@@ -2238,6 +2245,7 @@ static int epdc_working_buffer_update(struct mxc_epdc_fb_data *fb_data,
u32 wv_mode = upd_data_list->update_desc->upd_data.waveform_mode;
int ret = 0;
u32 hist_stat;
+ u32 pixel_nums;
struct update_desc_list *upd_desc_list;
ret = pxp_wfe_a_process(fb_data, update_region, upd_data_list);
@@ -2254,7 +2262,8 @@ static int epdc_working_buffer_update(struct mxc_epdc_fb_data *fb_data,
}
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_complete_update(fb_data, &fb_data->hist_status);
+ ret = pxp_complete_update(fb_data, &fb_data->hist_status,
+ &fb_data->pixel_nums);
if (ret) {
dev_err(fb_data->dev, "Unable to complete PxP update task: main process\n");
return ret;
@@ -2313,7 +2322,7 @@ static int epdc_working_buffer_update(struct mxc_epdc_fb_data *fb_data,
}
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_complete_update(fb_data, &hist_stat);
+ ret = pxp_complete_update(fb_data, &hist_stat, &pixel_nums);
if (ret) {
dev_err(fb_data->dev, "Unable to complete PxP update task: reagl/-d process\n");
mutex_unlock(&fb_data->pxp_mutex);
@@ -2335,6 +2344,7 @@ static int epdc_process_update(struct update_data_list *upd_data_list,
u32 post_rotation_xcoord, post_rotation_ycoord, width_pxp_blocks;
u32 pxp_input_offs, pxp_output_offs, pxp_output_shift;
u32 hist_stat = 0;
+ u32 pixel_nums = 0;
int width_unaligned, height_unaligned;
bool input_unaligned = false;
bool line_overflow = false;
@@ -2585,7 +2595,7 @@ static int epdc_process_update(struct update_data_list *upd_data_list,
}
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_complete_update(fb_data, &hist_stat);
+ ret = pxp_complete_update(fb_data, &hist_stat, &pixel_nums);
if (ret) {
dev_err(fb_data->dev, "Unable to complete PxP update task: pre_prcoess.\n");
mutex_unlock(&fb_data->pxp_mutex);
@@ -2617,7 +2627,7 @@ static int epdc_process_update(struct update_data_list *upd_data_list,
}
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_complete_update(fb_data, &hist_stat);
+ ret = pxp_complete_update(fb_data, &hist_stat, &pixel_nums);
if (ret) {
dev_err(fb_data->dev, "Unable to complete PxP update task: dithering process\n");
mutex_unlock(&fb_data->pxp_mutex);
@@ -2757,6 +2767,8 @@ static void epdc_submit_work_func(struct work_struct *work)
struct update_marker_data *next_marker, *temp_marker;
struct mxc_epdc_fb_data *fb_data =
container_of(work, struct mxc_epdc_fb_data, epdc_submit_work);
+ struct pxp_config_data *pxp_conf = &fb_data->pxp_conf;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
struct update_data_list *upd_data_list = NULL;
struct mxcfb_rect adj_update_region, *upd_region;
bool end_merge = false;
@@ -2904,22 +2916,22 @@ static void epdc_submit_work_func(struct work_struct *work)
* - FB unrotated
* - FB pixel format = 8-bit grayscale
* - No look-up transformations (inversion, posterization, etc.)
- *
- * Note: A bug with EPDC stride prevents us from skipping
- * PxP in versions 2.0 and earlier of EPDC.
+ * - No scaling/flip
*/
- is_transform = upd_data_list->update_desc->upd_data.flags &
+ is_transform = ((upd_data_list->update_desc->upd_data.flags &
(EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
- EPDC_FLAG_USE_CMAP) ? true : false;
+ EPDC_FLAG_USE_CMAP)) && (proc_data->scaling == 0) &&
+ (proc_data->hflip == 0) && (proc_data->vflip == 0)) ?
+ true : false;
/*XXX if we use external mode, we should first use pxp
* to update upd buffer data to working buffer first.
*/
if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
(fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
- !is_transform && (fb_data->rev > 20) &&
- !fb_data->restrict_width && !fb_data->epdc_wb_mode) {
+ !is_transform && (proc_data->dither_mode == 0) &&
+ !fb_data->restrict_width) {
/* If needed, enable EPDC HW while ePxP is processing */
if ((fb_data->power_state == POWER_STATE_OFF)
@@ -4082,9 +4094,8 @@ static void epdc_intr_work_func(struct work_struct *work)
epdc_luts_active = epdc_any_luts_active(fb_data->rev);
epdc_wb_busy = epdc_is_working_buffer_busy();
- /*XXX unsupport update cancelled in external mode temporarily */
if (fb_data->epdc_wb_mode)
- epdc_lut_cancelled = 0;
+ epdc_lut_cancelled = fb_data->pixel_nums == 0 ? true : false;
else
epdc_lut_cancelled = epdc_is_lut_cancelled();
@@ -4129,6 +4140,8 @@ static void epdc_intr_work_func(struct work_struct *work)
epdc_clear_lut_complete_irq(fb_data->rev, i);
fb_data->luts_complete_wb |= 1ULL << i;
+ if (i != 0)
+ fb_data->luts_complete |= 1ULL << i;
fb_data->lut_update_order[i] = 0;
@@ -5835,7 +5848,7 @@ static int pxp_chan_init(struct mxc_epdc_fb_data *fb_data)
return 0;
}
-static int pxp_wfe_b_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
+static int pxp_wfe_a_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_data,
u32 panel_width, u32 panel_height)
{
dma_cookie_t cookie;
@@ -5848,7 +5861,7 @@ static int pxp_wfe_b_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_dat
int i, j = 0, ret;
int length;
- dev_dbg(fb_data->dev, "Starting PxP WFE_B process for clearing WB.\n");
+ dev_dbg(fb_data->dev, "Starting PxP WFE_A process for clearing WB.\n");
/* First, check to see that we have acquired a PxP Channel object */
if (fb_data->pxp_chan == NULL) {
@@ -5890,64 +5903,71 @@ static int pxp_wfe_b_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_dat
txd->callback = pxp_dma_done;
proc_data->working_mode = PXP_MODE_STANDARD;
- proc_data->engine_enable = PXP_ENABLE_WFE_B;
- proc_data->lut_update = true;
+ proc_data->engine_enable = PXP_ENABLE_WFE_A;
+ proc_data->lut = 0;
+ proc_data->detection_only = 0;
+ proc_data->reagl_en = 0;
+ proc_data->partial_update = 0;
+ proc_data->alpha_en = 1;
+ proc_data->lut_sels = fb_data->luts_complete;
+ proc_data->lut_cleanup = 1;
+
+ pxp_conf->wfe_a_fetch_param[0].stride = panel_width;
+ pxp_conf->wfe_a_fetch_param[0].width = panel_width;
+ pxp_conf->wfe_a_fetch_param[0].height = panel_height;
+ pxp_conf->wfe_a_fetch_param[0].paddr = fb_data->phys_addr_black;
+ pxp_conf->wfe_a_fetch_param[1].stride = panel_width;
+ pxp_conf->wfe_a_fetch_param[1].width = panel_width;
+ pxp_conf->wfe_a_fetch_param[1].height = panel_height;
+ pxp_conf->wfe_a_fetch_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_fetch_param[0].left = 0;
+ pxp_conf->wfe_a_fetch_param[0].top = 0;
+ pxp_conf->wfe_a_fetch_param[1].left = 0;
+ pxp_conf->wfe_a_fetch_param[1].top = 0;
- pxp_conf->wfe_b_fetch_param[0].stride = panel_width;
- pxp_conf->wfe_b_fetch_param[0].width = panel_width;
- pxp_conf->wfe_b_fetch_param[0].height = panel_height;
- pxp_conf->wfe_b_fetch_param[0].paddr = fb_data->phys_addr_black;
- pxp_conf->wfe_b_fetch_param[1].stride = panel_width;
- pxp_conf->wfe_b_fetch_param[1].width = panel_width;
- pxp_conf->wfe_b_fetch_param[1].height = panel_height;
- pxp_conf->wfe_b_fetch_param[1].paddr = fb_data->working_buffer_phys;
-
- pxp_conf->wfe_b_store_param[0].stride = panel_width;
- pxp_conf->wfe_b_store_param[0].width = panel_width;
- pxp_conf->wfe_b_store_param[0].height = panel_height;
- pxp_conf->wfe_b_store_param[0].paddr = fb_data->working_buffer_phys;/*WB*/
- pxp_conf->wfe_b_store_param[1].stride = panel_width;
- pxp_conf->wfe_b_store_param[1].width = panel_width;
- pxp_conf->wfe_b_store_param[1].height = panel_height;
- pxp_conf->wfe_b_store_param[1].paddr = 0;
+ pxp_conf->wfe_a_store_param[0].stride = panel_width;
+ pxp_conf->wfe_a_store_param[0].width = panel_width;
+ pxp_conf->wfe_a_store_param[0].height = panel_height;
+ pxp_conf->wfe_a_store_param[0].paddr = fb_data->phys_addr_y4c;
+ pxp_conf->wfe_a_store_param[1].stride = panel_width;
+ pxp_conf->wfe_a_store_param[1].width = panel_width;
+ pxp_conf->wfe_a_store_param[1].height = panel_height;
+ pxp_conf->wfe_a_store_param[1].paddr = fb_data->working_buffer_phys;
+ pxp_conf->wfe_a_store_param[0].left = 0;
+ pxp_conf->wfe_a_store_param[0].top = 0;
+ pxp_conf->wfe_a_store_param[1].left = 0;
+ pxp_conf->wfe_a_store_param[1].top = 0;
desc = to_tx_desc(txd);
length = desc->len;
+ memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
for (i = 0; i < length; i++) {
- if (i == 0) {/* S0 */
- memcpy(&desc->proc_data, proc_data, sizeof(struct pxp_proc_data));
- pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
- memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
- sizeof(struct pxp_layer_param));
- desc = desc->next;
- } else if (i == 1) {
- pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
- memcpy(&desc->layer_param.out_param, &pxp_conf->out_param,
- sizeof(struct pxp_layer_param));
+ if (i == 0 || i == 1) {/* wfe_a won't use s0 or output at all */
desc = desc->next;
- } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_B) && (j < 4)) {
+
+ } else if ((pxp_conf->proc_data.engine_enable & PXP_ENABLE_WFE_A) && (j < 4)) {
for (j = 0; j < 4; j++) {
if (j == 0) {
memcpy(&desc->layer_param.processing_param,
- &pxp_conf->wfe_b_fetch_param[0],
+ &pxp_conf->wfe_a_fetch_param[0],
sizeof(struct pxp_layer_param));
- desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_FETCH0;
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH0;
} else if (j == 1) {
memcpy(&desc->layer_param.processing_param,
- &pxp_conf->wfe_b_fetch_param[1],
+ &pxp_conf->wfe_a_fetch_param[1],
sizeof(struct pxp_layer_param));
- desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_FETCH1;
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_FETCH1;
} else if (j == 2) {
memcpy(&desc->layer_param.processing_param,
- &pxp_conf->wfe_b_store_param[0],
+ &pxp_conf->wfe_a_store_param[0],
sizeof(struct pxp_layer_param));
- desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_STORE0;
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE0;
} else if (j == 3) {
memcpy(&desc->layer_param.processing_param,
- &pxp_conf->wfe_b_store_param[1],
+ &pxp_conf->wfe_a_store_param[1],
sizeof(struct pxp_layer_param));
- desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_B_STORE1;
+ desc->layer_param.processing_param.flag = PXP_BUF_FLAG_WFE_A_STORE1;
}
desc = desc->next;
@@ -5975,16 +5995,19 @@ static int pxp_wfe_b_process_clear_workingbuffer(struct mxc_epdc_fb_data *fb_dat
static int pxp_clear_wb_work_func(struct mxc_epdc_fb_data *fb_data)
{
unsigned int hist_stat;
+ unsigned int pixel_nums;
int ret;
- dev_dbg(fb_data->dev, "PxP WFE_B to clear working buffer.\n");
+ dev_dbg(fb_data->dev, "PxP WFE to clear working buffer.\n");
- ret = pxp_wfe_b_process_clear_workingbuffer(fb_data, fb_data->cur_mode->vmode->xres, fb_data->cur_mode->vmode->yres);
+ mutex_lock(&fb_data->pxp_mutex);
+ ret = pxp_wfe_a_process_clear_workingbuffer(fb_data, fb_data->cur_mode->vmode->xres, fb_data->cur_mode->vmode->yres);
if (ret) {
dev_err(fb_data->dev, "Unable to submit PxP update task.\n");
mutex_unlock(&fb_data->pxp_mutex);
return ret;
}
+ mutex_unlock(&fb_data->pxp_mutex);
/* If needed, enable EPDC HW while ePxP is processing */
if ((fb_data->power_state == POWER_STATE_OFF)
@@ -5993,15 +6016,13 @@ static int pxp_clear_wb_work_func(struct mxc_epdc_fb_data *fb_data)
}
/* This is a blocking call, so upon return PxP tx should be done */
- ret = pxp_complete_update(fb_data, &hist_stat);
+ ret = pxp_complete_update(fb_data, &hist_stat, &pixel_nums);
if (ret) {
- dev_err(fb_data->dev, "Unable to complete PxP update task: reagl/-d process\n");
+ dev_err(fb_data->dev, "Unable to complete PxP update task: clear wb process\n");
mutex_unlock(&fb_data->pxp_mutex);
return ret;
}
- epdc_reset_used_lut();
-
return 0;
}
@@ -6076,6 +6097,7 @@ static int pxp_legacy_process(struct mxc_epdc_fb_data *fb_data,
proc_data->srect.left = update_region->left;
proc_data->srect.width = update_region->width;
proc_data->srect.height = update_region->height;
+ proc_data->lut_cleanup = 0;
/*
* Because only YUV/YCbCr image can be scaled, configure
@@ -6302,6 +6324,7 @@ static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
u32 wv_mode = upd_data_list->update_desc->upd_data.waveform_mode;
int i, j = 0, ret;
int length;
+ bool is_transform;
dev_dbg(fb_data->dev, "Starting PxP WFE_A process.\n");
@@ -6347,8 +6370,11 @@ static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
proc_data->working_mode = PXP_MODE_STANDARD;
proc_data->engine_enable = PXP_ENABLE_WFE_A;
proc_data->lut = upd_data_list->lut_num;
+ proc_data->alpha_en = 0;
+ proc_data->lut_sels = fb_data->luts_complete;
proc_data->lut_status_1 = __raw_readl(EPDC_STATUS_LUTS);
proc_data->lut_status_2 = __raw_readl(EPDC_STATUS_LUTS2);
+ proc_data->lut_cleanup = 0;
if (upd_data_list->update_desc->upd_data.flags & EPDC_FLAG_TEST_COLLISION) {
proc_data->detection_only = 1;
@@ -6376,12 +6402,32 @@ static int pxp_wfe_a_process(struct mxc_epdc_fb_data *fb_data,
if (proc_data->dither_mode) {
pxp_conf->wfe_a_fetch_param[0].paddr = fb_data->phys_addr_y4;
} else {
-#ifdef USE_PS_AS_OUTPUT
- pxp_conf->wfe_a_fetch_param[0].paddr = upd_data_list->phys_addr + upd_data_list->update_desc->epdc_offs;
-
-#else
- pxp_conf->wfe_a_fetch_param[0].paddr = sg_dma_address(&sg[0]);
-#endif
+ is_transform = ((upd_data_list->update_desc->upd_data.flags &
+ (EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
+ EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
+ EPDC_FLAG_USE_CMAP)) && (proc_data->scaling == 0) &&
+ (proc_data->hflip == 0) && (proc_data->vflip == 0)) ?
+ true : false;
+
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
+ (fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
+ !is_transform && (proc_data->dither_mode == 0) &&
+ !(upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_ALT_BUFFER) &&
+ !fb_data->restrict_width) {
+ sg_dma_address(&sg[0]) = fb_data->info.fix.smem_start;
+ sg_set_page(&sg[0],
+ virt_to_page(fb_data->info.screen_base),
+ fb_data->info.fix.smem_len,
+ offset_in_page(fb_data->info.screen_base));
+ pxp_conf->wfe_a_fetch_param[0].paddr =
+ sg_dma_address(&sg[0]);
+
+ pxp_conf->wfe_a_fetch_param[0].left = update_region->left;
+ pxp_conf->wfe_a_fetch_param[0].top = update_region->top;
+ } else
+ pxp_conf->wfe_a_fetch_param[0].paddr =
+ upd_data_list->phys_addr + upd_data_list->update_desc->epdc_offs;
}
/* fetch1 is working buffer */
@@ -6521,6 +6567,7 @@ static int pxp_wfe_b_process_update(struct mxc_epdc_fb_data *fb_data,
proc_data->working_mode = PXP_MODE_STANDARD;
proc_data->engine_enable = PXP_ENABLE_WFE_B;
proc_data->lut_update = false;
+ proc_data->lut_cleanup = 0;
pxp_conf->wfe_b_fetch_param[0].stride = fb_data->cur_mode->vmode->xres;
pxp_conf->wfe_b_fetch_param[0].width = fb_data->cur_mode->vmode->xres;
@@ -6617,7 +6664,8 @@ static int pxp_wfe_b_process_update(struct mxc_epdc_fb_data *fb_data,
return 0;
}
-static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
+static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat,
+ u32 *pixel_nums)
{
int ret;
/*
@@ -6639,6 +6687,7 @@ static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
fb_data->pxp_conf.proc_data.lut_map_updated = false;
*hist_stat = to_tx_desc(fb_data->txd)->hist_status;
+ *pixel_nums = to_tx_desc(fb_data->txd)->pixel_nums;
dma_release_channel(&fb_data->pxp_chan->dma_chan);
fb_data->pxp_chan = NULL;