text: /*
   * Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
   *
   * 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
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   *
   */
  /*
   * Based on STMP378X PxP driver
   * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
   */
  
  #include <linux/dma-mapping.h>
  #include <linux/freezer.h>
  #include <linux/init.h>
  #include <linux/interrupt.h>
  #include <linux/irq.h>
  #include <linux/io.h>
  #include <linux/kernel.h>
  #include <linux/kthread.h>
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/of.h>
  #include <linux/of_device.h>
  #include <linux/of_gpio.h>
  #include <linux/platform_device.h>
  #include <linux/pm_runtime.h>
  #include <linux/slab.h>
  #include <linux/vmalloc.h>
  #include <linux/dmaengine.h>
  #include <linux/pxp_dma.h>
  #include <linux/timer.h>
  #include <linux/clk.h>
  #include <linux/workqueue.h>
  #include <linux/sched.h>
  #include <linux/of.h>
  
  #include "regs-pxp_v3.h"
  
  #ifdef CONFIG_MXC_FPGA_M4_TEST
  #include "cm4_image.c"
  #define FPGA_TCML_ADDR        0x0C7F8000
  #define PINCTRL               0x0C018000
  #define PIN_DOUT              0x700
  void __iomem *fpga_tcml_base;
  void __iomem *pinctrl_base;
  #endif
  
  
  #define PXP_FILL_TIMEOUT	3000
  #define busy_wait(cond)							\
  	({                                                              \
  	unsigned long end_jiffies = jiffies + 				\
  			msecs_to_jiffies(PXP_FILL_TIMEOUT);         	\
  	bool succeeded = false;                                         \
  	do {                                                            \
  		if (cond) {                                             \
  			succeeded = true;                               \
  			break;                                          \
  		}                                                       \
  		cpu_relax();                                            \
  	} while (time_after(end_jiffies, jiffies));                   	\
  		succeeded;                                              \
  	})
  
  #define	PXP_DOWNSCALE_THRESHOLD		0x4000
  
  #define CONFIG_FB_MXC_EINK_FPGA
  
  static LIST_HEAD(head);
  static int timeout_in_ms = 600;
  static unsigned int block_size;
  static struct kmem_cache *tx_desc_cache;
  static struct pxp_collision_info col_info;
  
  struct pxp_dma {
  	struct dma_device dma;
  };
  
  struct pxps {
  	struct platform_device *pdev;
  	struct clk *ipg_clk;
  	struct clk *axi_clk;
  	void __iomem *base;
  	int irq;		/* PXP IRQ to the CPU */
  
  	spinlock_t lock;
  	struct mutex clk_mutex;
  	int clk_stat;
  #define	CLK_STAT_OFF		0
  #define	CLK_STAT_ON		1
  	int pxp_ongoing;
  	int lut_state;
  
  	struct device *dev;
  	struct pxp_dma pxp_dma;
  	struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
  	struct work_struct work;
  
  	const struct pxp_devdata *devdata;
  
  	/* describes most recent processing configuration */
  	struct pxp_config_data pxp_conf_state;
  
  	/* to turn clock off when pxp is inactive */
  	struct timer_list clk_timer;
  
  	/* for pxp config dispatch asynchronously*/
  	struct task_struct *dispatch;
  	wait_queue_head_t thread_waitq;
  	struct completion complete;
  };
  
  #define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
  #define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  #define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  #define to_pxp(id) container_of(id, struct pxps, pxp_dma)
  
  #define PXP_DEF_BUFS	2
  #define PXP_MIN_PIX	8
  static void __iomem *pxp_reg_base;
  
  static __attribute__((aligned (1024*4))) unsigned int active_matrix_data_8x8[64]={
     0x06050100, 0x04030207, 0x06050100, 0x04030207,
     0x00040302, 0x07060501, 0x00040302, 0x07060501,
     0x02070605, 0x01000403, 0x02070605, 0x01000403,
     0x05010004, 0x03020706, 0x05010004, 0x03020706,
     0x04030207, 0x06050100, 0x04030207, 0x06050100,
     0x07060501, 0x00040302, 0x07060501, 0x00040302,
     0x01000403, 0x02070605, 0x01000403, 0x02070605,
     0x03020706, 0x05010004, 0x03020706, 0x05010004,
     0x06050100, 0x04030207, 0x06050100, 0x04030207,
     0x00040302, 0x07060501, 0x00040302, 0x07060501,
     0x02070605, 0x01000403, 0x02070605, 0x01000403,
     0x05010004, 0x03020706, 0x05010004, 0x03020706,
     0x04030207, 0x06050100, 0x04030207, 0x06050100,
     0x07060501, 0x00040302, 0x07060501, 0x00040302,
     0x01000403, 0x02070605, 0x01000403, 0x02070605,
     0x03020706, 0x05010004, 0x03020706, 0x05010004
      };
  
  static __attribute__((aligned (1024*4))) unsigned int dither_data_8x8[64]={
  		1,
  		49*2,
  		13*2,
  		61*2,
  		4*2,
  		52*2,
  		16*2,
  		64*2,
  		33*2,
  		17*2,
  		45*2,
  		29*2,
  		36*2,
  		20*2,
  		48*2,
  		32*2,
  		9*2,
  		57*2,
  		5*2,
  		53*2,
  		12*2,
  		60*2,
  		8*2,
  		56*2,
  		41*2,
  		25*2,
  		37*2,
  		21*2,
  		44*2,
  		28*2,
  		40*2,
  		24*2,
  		3*2,
  		51*2,
  		15*2,
  		63*2,
  		2*2,
  		50*2,
  		14*2,
  		62*2,
  		35*2,
  		19*2,
  		47*2,
  		31*2,
  		34*2,
  		18*2,
  		46*2,
  		30*2,
  		11*2,
  		59*2,
  		7*2,
  		55*2,
  		10*2,
  		58*2,
  		6*2,
  		54*2,
  		43*2,
  		27*2,
  		39*2,
  		23*2,
  		42*2,
  		26*2,
  		38*2,
  		22*2
  		};
  
  static void pxp_dithering_configure(struct pxps *pxp);
  static void pxp_dithering_configure_v3p(struct pxps *pxp);
  static void pxp_dithering_process(struct pxps *pxp);
  static void pxp_wfe_a_process(struct pxps *pxp);
  static void pxp_wfe_a_process_v3p(struct pxps *pxp);
  static void pxp_wfe_a_configure(struct pxps *pxp);
  static void pxp_wfe_a_configure_v3p(struct pxps *pxp);
  static void pxp_wfe_b_process(struct pxps *pxp);
  static void pxp_wfe_b_configure(struct pxps *pxp);
  static void pxp_lut_status_set(struct pxps *pxp, unsigned int lut);
  static void pxp_lut_status_set_v3p(struct pxps *pxp, unsigned int lut);
  static void pxp_start2(struct pxps *pxp);
  static void pxp_data_path_config_v3p(struct pxps *pxp);
  static void pxp_soft_reset(struct pxps *pxp);
  static void pxp_collision_detection_disable(struct pxps *pxp);
  static void pxp_collision_detection_enable(struct pxps *pxp,
  					   unsigned int width,
  					   unsigned int height);
  static void pxp_luts_activate(struct pxps *pxp, u64 lut_status);
  static bool pxp_collision_status_report(struct pxps *pxp, struct pxp_collision_info *info);
  static void pxp_histogram_status_report(struct pxps *pxp, u32 *hist_status);
  static void pxp_histogram_enable(struct pxps *pxp,
  				 unsigned int width,
  				 unsigned int height);
  static void pxp_histogram_disable(struct pxps *pxp);
  
  enum {
  	DITHER0_LUT = 0x0,	/* Select the LUT memory for access */
  	DITHER0_ERR0 = 0x1,	/* Select the ERR0 memory for access */
  	DITHER0_ERR1 = 0x2,	/* Select the ERR1 memory for access */
  	DITHER1_LUT = 0x3,	/* Select the LUT memory for access */
  	DITHER2_LUT = 0x4,	/* Select the LUT memory for access */
  	ALU_A = 0x5,		/* Select the ALU instr memory for access */
  	ALU_B = 0x6,		/* Select the ALU instr memory for access */
  	WFE_A = 0x7,		/* Select the WFE_A instr memory for access */
  	WFE_B = 0x8,		/* Select the WFE_B instr memory for access */
  	RESERVED = 0x15,
  };
  
  enum pxp_devtype {
  	PXP_V3,
  	PXP_V3P,	/* minor changes over V3, use WFE_B to replace WFE_A */
  };
  
  #define pxp_is_v3(pxp) (pxp->devdata->version == 30)
  #define pxp_is_v3p(pxp) (pxp->devdata->version == 31)
  
  struct pxp_devdata {
  	void (*pxp_wfe_a_configure)(struct pxps *pxp);
  	void (*pxp_wfe_a_process)(struct pxps *pxp);
  	void (*pxp_lut_status_set)(struct pxps *pxp, unsigned int lut);
  	void (*pxp_dithering_configure)(struct pxps *pxp);
  	void (*pxp_data_path_config)(struct pxps *pxp);
  	unsigned int version;
  };
  
  static const struct pxp_devdata pxp_devdata[] = {
  	[PXP_V3] = {
  		.pxp_wfe_a_configure = pxp_wfe_a_configure,
  		.pxp_wfe_a_process = pxp_wfe_a_process,
  		.pxp_lut_status_set = pxp_lut_status_set,
  		.pxp_dithering_configure = pxp_dithering_configure,
  		.pxp_data_path_config = NULL,
  		.version = 30,
  	},
  	[PXP_V3P] = {
  		.pxp_wfe_a_configure = pxp_wfe_a_configure_v3p,
  		.pxp_wfe_a_process = pxp_wfe_a_process_v3p,
  		.pxp_lut_status_set = pxp_lut_status_set_v3p,
  		.pxp_dithering_configure = pxp_dithering_configure_v3p,
  		.pxp_data_path_config = pxp_data_path_config_v3p,
  		.version = 31,
  	},
  };
  
  /*
   * PXP common functions
   */
  static void dump_pxp_reg(struct pxps *pxp)
  {
  	dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CTRL));
  	dev_dbg(pxp->dev, "PXP_STAT 0x%x",
  		__raw_readl(pxp->base + HW_PXP_STAT));
  	dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_CTRL));
  	dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_BUF));
  	dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_BUF2));
  	dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_PITCH));
  	dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_LRC));
  	dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
  	dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
  	dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
  	dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
  		__raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
  	dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_CTRL));
  	dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_BUF));
  	dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_UBUF));
  	dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_VBUF));
  	dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_PITCH));
  	dev_dbg(pxp->dev, "PXP_PS_BACKGROUND_0 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_BACKGROUND_0));
  	dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_SCALE));
  	dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_OFFSET));
  	dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW_0 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW_0));
  	dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
  		__raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH_0));
  	dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_AS_CTRL));
  	dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
  		__raw_readl(pxp->base + HW_PXP_AS_BUF));
  	dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
  		__raw_readl(pxp->base + HW_PXP_AS_PITCH));
  	dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
  		__raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW_0));
  	dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
  		__raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH_0));
  	dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
  	dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
  	dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
  	dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
  	dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
  	dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_LUT_CTRL));
  	dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
  		__raw_readl(pxp->base + HW_PXP_LUT_ADDR));
  	dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
  		__raw_readl(pxp->base + HW_PXP_LUT_DATA));
  	dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
  		__raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
  	dev_dbg(pxp->dev, "PXP_CFA 0x%x",
  		__raw_readl(pxp->base + HW_PXP_CFA));
  	dev_dbg(pxp->dev, "PXP_POWER_REG0 0x%x",
  		__raw_readl(pxp->base + HW_PXP_POWER_REG0));
  	dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
  		__raw_readl(pxp->base + HW_PXP_NEXT));
  	dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
  		__raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
  	dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
  		__raw_readl(pxp->base + HW_PXP_DEBUG));
  	dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
  		__raw_readl(pxp->base + HW_PXP_VERSION));
  }
  
  static void dump_pxp_reg2(struct pxps *pxp)
  {
  #ifdef DEBUG
  	int i = 0;
  
  	for (i=0; i< ((0x33C0/0x10) + 1);i++) {
  		printk("0x%08x: 0x%08x\n", 0x10*i, __raw_readl(pxp->base + 0x10*i));
  	}
  #endif
  }
  
  static void print_param(struct pxp_layer_param *p, char *s)
  {
  	pr_debug("%s: t/l/w/h/s %d/%d/%d/%d/%d, addr %x\n", s,
  		p->top, p->left, p->width, p->height, p->stride, p->paddr);
  }
  
  static bool is_yuv(u32 pix_fmt)
  {
  	if ((pix_fmt == PXP_PIX_FMT_YUYV) |
  	    (pix_fmt == PXP_PIX_FMT_UYVY) |
  	    (pix_fmt == PXP_PIX_FMT_YVYU) |
  	    (pix_fmt == PXP_PIX_FMT_VYUY) |
  	    (pix_fmt == PXP_PIX_FMT_Y41P) |
  	    (pix_fmt == PXP_PIX_FMT_VUY444) |
  	    (pix_fmt == PXP_PIX_FMT_NV12) |
  	    (pix_fmt == PXP_PIX_FMT_NV21) |
  	    (pix_fmt == PXP_PIX_FMT_NV16) |
  	    (pix_fmt == PXP_PIX_FMT_NV61) |
  	    (pix_fmt == PXP_PIX_FMT_GREY) |
  	    (pix_fmt == PXP_PIX_FMT_GY04) |
  	    (pix_fmt == PXP_PIX_FMT_YVU410P) |
  	    (pix_fmt == PXP_PIX_FMT_YUV410P) |
  	    (pix_fmt == PXP_PIX_FMT_YVU420P) |
  	    (pix_fmt == PXP_PIX_FMT_YUV420P) |
  	    (pix_fmt == PXP_PIX_FMT_YUV420P2) |
  	    (pix_fmt == PXP_PIX_FMT_YVU422P) |
  	    (pix_fmt == PXP_PIX_FMT_YUV422P)) {
  		return true;
  	} else {
  		return false;
  	}
  }
  
  
  static void pxp_set_ctrl(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  	u32 ctrl;
  	u32 fmt_ctrl;
  	int need_swap = 0;   /* to support YUYV and YVYU formats */
  
  	/* Configure S0 input format */
  	switch (pxp_conf->s0_param.pixel_fmt) {
  	case PXP_PIX_FMT_RGB32:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
  		break;
  	case PXP_PIX_FMT_RGB565:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
  		break;
  	case PXP_PIX_FMT_RGB555:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
  		break;
  	case PXP_PIX_FMT_YUV420P:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  		break;
  	case PXP_PIX_FMT_YVU420P:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  		break;
  	case PXP_PIX_FMT_GREY:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
  		break;
  	case PXP_PIX_FMT_GY04:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
  		break;
  	case PXP_PIX_FMT_VUY444:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV1P444;
  		break;
  	case PXP_PIX_FMT_YUV422P:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
  		break;
  	case PXP_PIX_FMT_UYVY:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  		break;
  	case PXP_PIX_FMT_YUYV:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  		need_swap = 1;
  		break;
  	case PXP_PIX_FMT_VYUY:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  		break;
  	case PXP_PIX_FMT_YVYU:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  		need_swap = 1;
  		break;
  	case PXP_PIX_FMT_NV12:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
  		break;
  	case PXP_PIX_FMT_NV21:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
  		break;
  	case PXP_PIX_FMT_NV16:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
  		break;
  	case PXP_PIX_FMT_NV61:
  		fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
  		break;
  	default:
  		fmt_ctrl = 0;
  	}
  
  	ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) |
  		(need_swap ? BM_PXP_PS_CTRL_WB_SWAP : 0);
  	__raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
  
  	/* Configure output format based on out_channel format */
  	switch (pxp_conf->out_param.pixel_fmt) {
  	case PXP_PIX_FMT_RGB32:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
  		break;
  	case PXP_PIX_FMT_BGRA32:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
  		break;
  	case PXP_PIX_FMT_RGB24:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
  		break;
  	case PXP_PIX_FMT_RGB565:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
  		break;
  	case PXP_PIX_FMT_RGB555:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
  		break;
  	case PXP_PIX_FMT_GREY:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
  		break;
  	case PXP_PIX_FMT_GY04:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
  		break;
  	case PXP_PIX_FMT_UYVY:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
  		break;
  	case PXP_PIX_FMT_VYUY:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
  		break;
  	case PXP_PIX_FMT_NV12:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
  		break;
  	case PXP_PIX_FMT_NV21:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
  		break;
  	case PXP_PIX_FMT_NV16:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
  		break;
  	case PXP_PIX_FMT_NV61:
  		fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
  		break;
  	default:
  		fmt_ctrl = 0;
  	}
  
  	ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
  	__raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
  
  	ctrl = 0;
  	if (proc_data->scaling)
  		;
  	if (proc_data->vflip)
  		ctrl |= BM_PXP_CTRL_VFLIP0;
  	if (proc_data->hflip)
  		ctrl |= BM_PXP_CTRL_HFLIP0;
  	if (proc_data->rotate) {
  		ctrl |= BF_PXP_CTRL_ROTATE0(proc_data->rotate / 90);
  #if 0
  		if (proc_data->rot_pos)
  			ctrl |= BM_PXP_CTRL_ROT_POS;
  #endif
  	}
  
  	/* In default, the block size is set to 8x8
  	 * But block size can be set to 16x16 due to
  	 * blocksize variable modification
  	 */
  	ctrl |= block_size << 23;
  
  	__raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
  }
  
  static int pxp_start(struct pxps *pxp)
  {
  	__raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  	__raw_writel(BM_PXP_CTRL_ENABLE | BM_PXP_CTRL_ENABLE_CSC2 |
  		BM_PXP_CTRL_ENABLE_LUT | BM_PXP_CTRL_ENABLE_ROTATE0 |
  		BM_PXP_CTRL_ENABLE_PS_AS_OUT, pxp->base + HW_PXP_CTRL_SET);
  	dump_pxp_reg(pxp);
  
  	return 0;
  }
  
  static void pxp_set_outbuf(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *out_params = &pxp_conf->out_param;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  
  	__raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
  
  	if ((out_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
  		(out_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
  		(out_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  		(out_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
  		dma_addr_t Y, U;
  
  		Y = out_params->paddr;
  		U = Y + (out_params->width * out_params->height);
  
  		__raw_writel(U, pxp->base + HW_PXP_OUT_BUF2);
  	}
  
  	if (proc_data->rotate == 90 || proc_data->rotate == 270)
  		__raw_writel(BF_PXP_OUT_LRC_X(out_params->height - 1) |
  				BF_PXP_OUT_LRC_Y(out_params->width - 1),
  				pxp->base + HW_PXP_OUT_LRC);
  	else
  		__raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
  				BF_PXP_OUT_LRC_Y(out_params->height - 1),
  				pxp->base + HW_PXP_OUT_LRC);
  
  	if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
  		__raw_writel(out_params->stride * 3,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
  		 out_params->pixel_fmt == PXP_PIX_FMT_RGB32) {
  		__raw_writel(out_params->stride << 2,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else if ((out_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
  		   (out_params->pixel_fmt == PXP_PIX_FMT_RGB555)) {
  		__raw_writel(out_params->stride << 1,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  		(out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
  		__raw_writel(out_params->stride << 1,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  		   out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  		   out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  		   out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  		   out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
  		__raw_writel(out_params->stride,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
  		__raw_writel(out_params->stride >> 1,
  				pxp->base + HW_PXP_OUT_PITCH);
  	} else {
  		__raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
  	}
  
  	/* set global alpha if necessary */
  	if (out_params->global_alpha_enable) {
  		__raw_writel(out_params->global_alpha << 24,
  				pxp->base + HW_PXP_OUT_CTRL_SET);
  		__raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
  				pxp->base + HW_PXP_OUT_CTRL_SET);
  	}
  }
  
  static void pxp_set_s0colorkey(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  
  	/* Low and high are set equal. V4L does not allow a chromakey range */
  	if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
  		/* disable color key */
  		__raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW_0);
  		__raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH_0);
  	} else {
  		__raw_writel(s0_params->color_key,
  			     pxp->base + HW_PXP_PS_CLRKEYLOW_0);
  		__raw_writel(s0_params->color_key,
  			     pxp->base + HW_PXP_PS_CLRKEYHIGH_0);
  	}
  }
  
  static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
  
  	/* Low and high are set equal. V4L does not allow a chromakey range */
  	if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
  		__raw_writel(ol_params->color_key,
  			     pxp->base + HW_PXP_AS_CLRKEYLOW_0);
  		__raw_writel(ol_params->color_key,
  			     pxp->base + HW_PXP_AS_CLRKEYHIGH_0);
  	} else {
  		/* disable color key */
  		__raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW_0);
  		__raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH_0);
  	}
  }
  
  static void pxp_set_oln(int layer_no, struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  	dma_addr_t phys_addr = olparams_data->paddr;
  	u32 pitch = olparams_data->stride ? olparams_data->stride :
  					    olparams_data->width;
  
  	__raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
  
  	/* Fixme */
  	if (olparams_data->width == 0 && olparams_data->height == 0) {
  		__raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
  		__raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
  	} else {
  		__raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
  		__raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  				BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  				pxp->base + HW_PXP_OUT_AS_LRC);
  	}
  
  	if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) ||
  		 (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32)) {
  		__raw_writel(pitch << 2,
  				pxp->base + HW_PXP_AS_PITCH);
  	} else if ((olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) ||
  		   (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB555)) {
  		__raw_writel(pitch << 1,
  				pxp->base + HW_PXP_AS_PITCH);
  	} else {
  		__raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
  	}
  }
  
  static void pxp_set_olparam(int layer_no, struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  	u32 olparam;
  
  	olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
  	if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32) {
  		olparam |=
  		    BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
  	} else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
  		olparam |=
  		    BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
  		if (!olparams_data->combine_enable) {
  			olparam |=
  				BF_PXP_AS_CTRL_ALPHA_CTRL
  				(BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
  			olparam |= 0x3 << 16;
  		}
  	} else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  		olparam |=
  		    BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
  	} else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB555) {
  		olparam |=
  		    BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB555);
  	}
  
  	if (olparams_data->global_alpha_enable) {
  		if (olparams_data->global_override) {
  			olparam |=
  				BF_PXP_AS_CTRL_ALPHA_CTRL
  				(BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
  		} else {
  			olparam |=
  				BF_PXP_AS_CTRL_ALPHA_CTRL
  				(BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
  		}
  		if (olparams_data->alpha_invert)
  			olparam |= BM_PXP_AS_CTRL_ALPHA0_INVERT;
  	}
  	if (olparams_data->color_key_enable)
  		olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
  
  	__raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
  }
  
  static void pxp_set_s0param(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  	struct pxp_layer_param *out_params = &pxp_conf->out_param;
  	u32 s0param_ulc, s0param_lrc;
  
  	/* contains the coordinate for the PS in the OUTPUT buffer. */
  	if ((pxp_conf->s0_param).width == 0 &&
  		(pxp_conf->s0_param).height == 0) {
  		__raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
  		__raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
  	} else {
  		switch (proc_data->rotate) {
  		case 0:
  			s0param_ulc = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
  			s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
  			s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.width - 1);
  			s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.height - 1);
  			break;
  		case 90:
  			s0param_ulc = BF_PXP_OUT_PS_ULC_Y(out_params->width - (proc_data->drect.left + proc_data->drect.width));
  			s0param_ulc |= BF_PXP_OUT_PS_ULC_X(proc_data->drect.top);
  			s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.height - 1);
  			s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.width - 1);
  			break;
  		case 180:
  			s0param_ulc = BF_PXP_OUT_PS_ULC_X(out_params->width - (proc_data->drect.left + proc_data->drect.width));
  			s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(out_params->height - (proc_data->drect.top + proc_data->drect.height));
  			s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.width - 1);
  			s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.height - 1);
  			break;
  		case 270:
  			s0param_ulc = BF_PXP_OUT_PS_ULC_X(out_params->height - (proc_data->drect.top + proc_data->drect.height));
  			s0param_ulc |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.left);
  			s0param_lrc = BF_PXP_OUT_PS_LRC_X(((s0param_ulc & BM_PXP_OUT_PS_ULC_X) >> 16) + proc_data->drect.height - 1);
  			s0param_lrc |= BF_PXP_OUT_PS_LRC_Y((s0param_ulc & BM_PXP_OUT_PS_ULC_Y) + proc_data->drect.width - 1);
  			break;
  		default:
  			return;
  		}
  		__raw_writel(s0param_ulc, pxp->base + HW_PXP_OUT_PS_ULC);
  		__raw_writel(s0param_lrc, pxp->base + HW_PXP_OUT_PS_LRC);
  	}
  
  	/* Since user apps always pass the rotated drect
  	 * to this driver, we need to first swap the width
  	 * and height which is used to calculate the scale
  	 * factors later.
  	 */
  	if (proc_data->rotate == 90 || proc_data->rotate == 270) {
  		int temp;
  		temp = proc_data->drect.width;
  		proc_data->drect.width = proc_data->drect.height;
  		proc_data->drect.height = temp;
  	}
  }
  
  /* crop behavior is re-designed in h/w. */
  static void pxp_set_s0crop(struct pxps *pxp)
  {
  	/*
  	 * place-holder, it's implemented in other functions in this driver.
  	 * Refer to "Clipping source images" section in RM for detail.
  	 */
  }
  
  static int pxp_set_scaling(struct pxps *pxp)
  {
  	int ret = 0;
  	u32 xscale, yscale, s0scale;
  	u32 decx, decy, xdec = 0, ydec = 0;
  	struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  	struct pxp_layer_param *out_params = &pxp_conf->out_param;
  
  	proc_data->scaling = 1;
  
  	if (!proc_data->drect.width || !proc_data->drect.height) {
  		pr_err("Invalid drect width and height passed in\n");
  		return -EINVAL;
  	}
  
  	decx = proc_data->srect.width / proc_data->drect.width;
  	decy = proc_data->srect.height / proc_data->drect.height;
  	if (decx > 1) {
  		if (decx >= 2 && decx < 4) {
  			decx = 2;
  			xdec = 1;
  		} else if (decx >= 4 && decx < 8) {
  			decx = 4;
  			xdec = 2;
  		} else if (decx >= 8) {
  			decx = 8;
  			xdec = 3;
  		}
  		xscale = proc_data->srect.width * 0x1000 /
  			 (proc_data->drect.width * decx);
  	} else {
  		if (!is_yuv(s0_params->pixel_fmt) ||
  		    (is_yuv(s0_params->pixel_fmt) ==
  		     is_yuv(out_params->pixel_fmt)) ||
  		    (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
  		    (s0_params->pixel_fmt == PXP_PIX_FMT_GY04) ||
  		    (s0_params->pixel_fmt == PXP_PIX_FMT_VUY444)) {
  			if ((proc_data->srect.width > 1) &&
  			    (proc_data->drect.width > 1))
  				xscale = (proc_data->srect.width - 1) * 0x1000 /
  					 (proc_data->drect.width - 1);
  			else
  				xscale = proc_data->srect.width * 0x1000 /
  					 proc_data->drect.width;
  		} else {
  			if ((proc_data->srect.width > 2) &&
  			    (proc_data->drect.width > 1))
  				xscale = (proc_data->srect.width - 2) * 0x1000 /
  					 (proc_data->drect.width - 1);
  			else
  				xscale = proc_data->srect.width * 0x1000 /
  					 proc_data->drect.width;
  		}
  	}
  	if (decy > 1) {
  		if (decy >= 2 && decy < 4) {
  			decy = 2;
  			ydec = 1;
  		} else if (decy >= 4 && decy < 8) {
  			decy = 4;
  			ydec = 2;
  		} else if (decy >= 8) {
  			decy = 8;
  			ydec = 3;
  		}
  		yscale = proc_data->srect.height * 0x1000 /
  			 (proc_data->drect.height * decy);
  	} else {
  		if ((proc_data->srect.height > 1) &&
  		    (proc_data->drect.height > 1))
  			yscale = (proc_data->srect.height - 1) * 0x1000 /
  				 (proc_data->drect.height - 1);
  		else
  			yscale = proc_data->srect.height * 0x1000 /
  				 proc_data->drect.height;
  	}
  
  	__raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
  
  	if (xscale > PXP_DOWNSCALE_THRESHOLD)
  		xscale = PXP_DOWNSCALE_THRESHOLD;
  	if (yscale > PXP_DOWNSCALE_THRESHOLD)
  		yscale = PXP_DOWNSCALE_THRESHOLD;
  	s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
  		BF_PXP_PS_SCALE_XSCALE(xscale);
  	__raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
  
  	pxp_set_ctrl(pxp);
  
  	return ret;
  }
  
  static void pxp_set_bg(struct pxps *pxp)
  {
  	__raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
  		     pxp->base + HW_PXP_PS_BACKGROUND_0);
  }
  
  static void pxp_set_lut(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	int lut_op = pxp_conf->proc_data.lut_transform;
  	u32 reg_val;
  	int i;
  	bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
  	u8 *cmap = pxp_conf->proc_data.lut_map;
  	u32 entry_src;
  	u32 pix_val;
  	u8 entry[4];
  
  	/*
  	 * If LUT already configured as needed, return...
  	 * Unless CMAP is needed and it has been updated.
  	 */
  	if ((pxp->lut_state == lut_op) &&
  		!(use_cmap && pxp_conf->proc_data.lut_map_updated))
  		return;
  
  	if (lut_op == PXP_LUT_NONE) {
  		__raw_writel(BM_PXP_LUT_CTRL_BYPASS,
  			     pxp->base + HW_PXP_LUT_CTRL);
  	} else if (((lut_op & PXP_LUT_INVERT) != 0)
  		&& ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
  		/* Fill out LUT table with inverted monochromized values */
  
  		/* clear bypass bit, set lookup mode & out mode */
  		__raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  				(BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  				BF_PXP_LUT_CTRL_OUT_MODE
  				(BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  				pxp->base + HW_PXP_LUT_CTRL);
  
  		/* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  		__raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  
  		/* LUT address pointer auto-increments after each data write */
  		for (pix_val = 0; pix_val < 256; pix_val += 4) {
  			for (i = 0; i < 4; i++) {
  				entry_src = use_cmap ?
  					cmap[pix_val + i] : pix_val + i;
  				entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
  			}
  			reg_val = (entry[3] << 24) | (entry[2] << 16) |
  				(entry[1] << 8) | entry[0];
  			__raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  		}
  	} else if ((lut_op & PXP_LUT_INVERT) != 0) {
  		/* Fill out LUT table with 8-bit inverted values */
  
  		/* clear bypass bit, set lookup mode & out mode */
  		__raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  				(BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  				BF_PXP_LUT_CTRL_OUT_MODE
  				(BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  				pxp->base + HW_PXP_LUT_CTRL);
  
  		/* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  		__raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  
  		/* LUT address pointer auto-increments after each data write */
  		for (pix_val = 0; pix_val < 256; pix_val += 4) {
  			for (i = 0; i < 4; i++) {
  				entry_src = use_cmap ?
  					cmap[pix_val + i] : pix_val + i;
  				entry[i] = ~entry_src & 0xFF;
  			}
  			reg_val = (entry[3] << 24) | (entry[2] << 16) |
  				(entry[1] << 8) | entry[0];
  			__raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  		}
  	} else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
  		/* Fill out LUT table with 8-bit monochromized values */
  
  		/* clear bypass bit, set lookup mode & out mode */
  		__raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  				(BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  				BF_PXP_LUT_CTRL_OUT_MODE
  				(BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  				pxp->base + HW_PXP_LUT_CTRL);
  
  		/* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  		__raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  
  		/* LUT address pointer auto-increments after each data write */
  		for (pix_val = 0; pix_val < 256; pix_val += 4) {
  			for (i = 0; i < 4; i++) {
  				entry_src = use_cmap ?
  					cmap[pix_val + i] : pix_val + i;
  				entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
  			}
  			reg_val = (entry[3] << 24) | (entry[2] << 16) |
  				(entry[1] << 8) | entry[0];
  			__raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  		}
  	} else if (use_cmap) {
  		/* Fill out LUT table using colormap values */
  
  		/* clear bypass bit, set lookup mode & out mode */
  		__raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  				(BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  				BF_PXP_LUT_CTRL_OUT_MODE
  				(BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  				pxp->base + HW_PXP_LUT_CTRL);
  
  		/* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  		__raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  
  		/* LUT address pointer auto-increments after each data write */
  		for (pix_val = 0; pix_val < 256; pix_val += 4) {
  			for (i = 0; i < 4; i++)
  				entry[i] = cmap[pix_val + i];
  			reg_val = (entry[3] << 24) | (entry[2] << 16) |
  				(entry[1] << 8) | entry[0];
  			__raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  		}
  	}
  
  	pxp->lut_state = lut_op;
  }
  
  static void pxp_set_csc(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  	struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
  	struct pxp_layer_param *out_params = &pxp_conf->out_param;
  
  	bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
  	bool output_is_YUV = is_yuv(out_params->pixel_fmt);
  
  	if (input_is_YUV && output_is_YUV) {
  		/*
  		 * Input = YUV, Output = YUV
  		 * No CSC unless we need to do combining
  		 */
  		if (ol_params->combine_enable) {
  			/* Must convert to RGB for combining with RGB overlay */
  
  			/* CSC1 - YUV->RGB */
  			__raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
  			__raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
  			__raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
  
  			/* CSC2 - RGB->YUV */
  			__raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  			__raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  			__raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  			__raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  			__raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  			__raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  			__raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  		} else {
  			/* Input & Output both YUV, so bypass both CSCs */
  
  			/* CSC1 - Bypass */
  			__raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  
  			/* CSC2 - Bypass */
  			__raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  		}
  	} else if (input_is_YUV && !output_is_YUV) {
  		/*
  		 * Input = YUV, Output = RGB
  		 * Use CSC1 to convert to RGB
  		 */
  
  		/* CSC1 - YUV->RGB */
  		__raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
  		__raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
  		__raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
  
  		/* CSC2 - Bypass */
  		__raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  	} else if (!input_is_YUV && output_is_YUV) {
  		/*
  		 * Input = RGB, Output = YUV
  		 * Use CSC2 to convert to YUV
  		 */
  
  		/* CSC1 - Bypass */
  		__raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  
  		/* CSC2 - RGB->YUV */
  		__raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  		__raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  		__raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  		__raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  		__raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  		__raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  		__raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  	} else {
  		/*
  		 * Input = RGB, Output = RGB
  		 * Input & Output both RGB, so bypass both CSCs
  		 */
  
  		/* CSC1 - Bypass */
  		__raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  
  		/* CSC2 - Bypass */
  		__raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  	}
  
  	/* YCrCb colorspace */
  	/* Not sure when we use this...no YCrCb formats are defined for PxP */
  	/*
  	   __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
  	   __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
  	   __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
  	 */
  
  }
  
  static void pxp_set_s0buf(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  	dma_addr_t Y, U, V;
  	dma_addr_t Y1, U1, V1;
  	u32 offset, bpp = 1;
  	u32 pitch = s0_params->stride ? s0_params->stride :
  					s0_params->width;
  
  	Y = s0_params->paddr;
  
  	if ((s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
  		(s0_params->pixel_fmt == PXP_PIX_FMT_RGB555))
  		bpp = 2;
  	else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  		bpp = 4;
  	offset = (proc_data->srect.top * s0_params->width +
  		 proc_data->srect.left) * bpp;
  	/* clipping or cropping */
  	Y1 = Y + offset;
  	__raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
  	if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
  	    (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
  	    (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)    ||
  	    (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
  		/* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
  		int s = 2;
  		if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
  			s = 1;
  
  		offset = proc_data->srect.top * s0_params->width / 4 +
  			 proc_data->srect.left / 2;
  		U = Y + (s0_params->width * s0_params->height);
  		U1 = U + offset;
  		V = U + ((s0_params->width * s0_params->height) >> s);
  		V1 = V + offset;
  		if (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) {
  			__raw_writel(V1, pxp->base + HW_PXP_PS_UBUF);
  			__raw_writel(U1, pxp->base + HW_PXP_PS_VBUF);
  		} else {
  			__raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  			__raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
  		}
  	} else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
  		 (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
  		 (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  		 (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
  		int s = 2;
  		if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  		    (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
  			s = 1;
  
  		offset = (proc_data->srect.top * s0_params->width +
  			  proc_data->srect.left) / s;
  		U = Y + (s0_params->width * s0_params->height);
  		U1 = U + offset;
  
  		__raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  	}
  
  	/* TODO: only support RGB565, Y8, Y4, YUV420 */
  	if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
  	    s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
  		__raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
  	}
  	else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
  		__raw_writel(pitch >> 1,
  				pxp->base + HW_PXP_PS_PITCH);
  	else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32 ||
  			 s0_params->pixel_fmt == PXP_PIX_FMT_VUY444)
  		__raw_writel(pitch << 2,
  				pxp->base + HW_PXP_PS_PITCH);
  	else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  		 s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
  		 s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
  		 s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
  		__raw_writel(pitch << 1,
  				pxp->base + HW_PXP_PS_PITCH);
  	else if ((s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) ||
  		 (s0_params->pixel_fmt == PXP_PIX_FMT_RGB555))
  		__raw_writel(pitch << 1,
  				pxp->base + HW_PXP_PS_PITCH);
  	else
  		__raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
  }
  
  /**
   * pxp_config() - configure PxP for a processing task
   * @pxps:	PXP context.
   * @pxp_chan:	PXP channel.
   * @return:	0 on success or negative error code on failure.
   */
  static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
  {
  	struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &pxp_conf_data->proc_data;
  	int ol_nr;
  	int i;
  
  	if ((proc_data->working_mode & PXP_MODE_STANDARD) == PXP_MODE_STANDARD) {
  
  		/* now only test dithering feature */
  		if ((proc_data->engine_enable & PXP_ENABLE_DITHER) == PXP_ENABLE_DITHER) {
  			pxp_dithering_process(pxp);
  			if (pxp_is_v3p(pxp)) {
  				__raw_writel(
  					BM_PXP_CTRL_ENABLE         |
  					BM_PXP_CTRL_ENABLE_DITHER  |
  					BM_PXP_CTRL_ENABLE_CSC2    |
  					BM_PXP_CTRL_ENABLE_LUT     |
  					BM_PXP_CTRL_ENABLE_ROTATE0 |
  					BM_PXP_CTRL_ENABLE_PS_AS_OUT,
  					pxp->base + HW_PXP_CTRL_SET);
  				return 0;
  			}
  }
  
  		if ((proc_data->engine_enable & PXP_ENABLE_WFE_A) == PXP_ENABLE_WFE_A)
  		{
  			/* We should enable histogram in standard mode 
  			 * in wfe_a processing for waveform mode selection
  			 */
  			pxp_histogram_enable(pxp, pxp_conf_data->wfe_a_fetch_param[0].width,
  					pxp_conf_data->wfe_a_fetch_param[0].height);
  
  			/* collision detection should be always enable in standard mode */
  			pxp_luts_activate(pxp, (u64)proc_data->lut_status_1 |
  					((u64)proc_data->lut_status_2 << 32));
  
  			pxp_collision_detection_enable(pxp, pxp_conf_data->wfe_a_fetch_param[0].width,
  						pxp_conf_data->wfe_a_fetch_param[0].height);
  
  			if (pxp->devdata && pxp->devdata->pxp_wfe_a_configure)
  				pxp->devdata->pxp_wfe_a_configure(pxp);
  			if (pxp->devdata && pxp->devdata->pxp_wfe_a_process)
  				pxp->devdata->pxp_wfe_a_process(pxp);
  		}
  
  		if ((proc_data->engine_enable & PXP_ENABLE_WFE_B) == PXP_ENABLE_WFE_B) {
  			pxp_wfe_b_configure(pxp);
  			pxp_wfe_b_process(pxp);
  		}
  
  
  		return 0;
  	}
  
  	/* Configure PxP regs */
  	pxp_set_ctrl(pxp);
  	pxp_set_s0param(pxp);
  	pxp_set_s0crop(pxp);
  	pxp_set_scaling(pxp);
  	ol_nr = pxp_conf_data->layer_nr - 2;
  	if (ol_nr > 0) {
  		while (ol_nr > 0) {
  			i = pxp_conf_data->layer_nr - 2 - ol_nr;
  			pxp_set_oln(i, pxp);
  			pxp_set_olparam(i, pxp);
  			/* only the color key in higher overlay will take effect. */
  			pxp_set_olcolorkey(i, pxp);
  			ol_nr--;
  		}
  	} else {
  		__raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
  		__raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
  	}
  	pxp_set_s0colorkey(pxp);
  	pxp_set_csc(pxp);
  	pxp_set_bg(pxp);
  	pxp_set_lut(pxp);
  
  	pxp_set_s0buf(pxp);
  	pxp_set_outbuf(pxp);
  
  	return 0;
  }
  
  static void pxp_clk_enable(struct pxps *pxp)
  {
  	mutex_lock(&pxp->clk_mutex);
  
  	if (pxp->clk_stat == CLK_STAT_ON) {
  		mutex_unlock(&pxp->clk_mutex);
  		return;
  	}
  
  	pm_runtime_get_sync(pxp->dev);
  
  	clk_prepare_enable(pxp->ipg_clk);
  	clk_prepare_enable(pxp->axi_clk);
  	pxp->clk_stat = CLK_STAT_ON;
  
  	mutex_unlock(&pxp->clk_mutex);
  }
  
  static void pxp_clk_disable(struct pxps *pxp)
  {
  	unsigned long flags;
  
  	mutex_lock(&pxp->clk_mutex);
  
  	if (pxp->clk_stat == CLK_STAT_OFF) {
  		mutex_unlock(&pxp->clk_mutex);
  		return;
  	}
  
  	spin_lock_irqsave(&pxp->lock, flags);
  	if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
  		spin_unlock_irqrestore(&pxp->lock, flags);
  		clk_disable_unprepare(pxp->ipg_clk);
  		clk_disable_unprepare(pxp->axi_clk);
  		pxp->clk_stat = CLK_STAT_OFF;
  	} else
  		spin_unlock_irqrestore(&pxp->lock, flags);
  
  	pm_runtime_put_sync_suspend(pxp->dev);
  
  	mutex_unlock(&pxp->clk_mutex);
  }
  
  static inline void clkoff_callback(struct work_struct *w)
  {
  	struct pxps *pxp = container_of(w, struct pxps, work);
  
  	pxp_clk_disable(pxp);
  }
  
  static void pxp_clkoff_timer(unsigned long arg)
  {
  	struct pxps *pxp = (struct pxps *)arg;
  
  	if ((pxp->pxp_ongoing == 0) && list_empty(&head))
  		schedule_work(&pxp->work);
  	else
  		mod_timer(&pxp->clk_timer,
  			  jiffies + msecs_to_jiffies(timeout_in_ms));
  }
  
  static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
  {
  	return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
  }
  
  /* called with pxp_chan->lock held */
  static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
  {
  	struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
  	struct pxps *pxp = to_pxp(pxp_dma);
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &config_data->proc_data;
  	struct pxp_tx_desc *desc;
  	struct pxp_tx_desc *child;
  	int i = 0;
  
  	memset(&pxp->pxp_conf_state.s0_param, 0,  sizeof(struct pxp_layer_param));
  	memset(&pxp->pxp_conf_state.out_param, 0,  sizeof(struct pxp_layer_param));
  	memset(pxp->pxp_conf_state.ol_param, 0,  sizeof(struct pxp_layer_param) * 8);
  	memset(&pxp->pxp_conf_state.proc_data, 0,  sizeof(struct pxp_proc_data));
  	/* S0 */
  	desc = list_first_entry(&head, struct pxp_tx_desc, list);
  	memcpy(&pxp->pxp_conf_state.s0_param,
  	       &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
  	memcpy(&pxp->pxp_conf_state.proc_data,
  	       &desc->proc_data, sizeof(struct pxp_proc_data));
  
  	/* Save PxP configuration */
  	list_for_each_entry(child, &desc->tx_list, list) {
  		if (i == 0) {	/* Output */
  			memcpy(&pxp->pxp_conf_state.out_param,
  			       &child->layer_param.out_param,
  			       sizeof(struct pxp_layer_param));
  		} else if (i == 1) {	/* Overlay */
  			memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
  			       &child->layer_param.ol_param,
  			       sizeof(struct pxp_layer_param));
  		}
  
  		if (proc_data->engine_enable & PXP_ENABLE_DITHER) {
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_FETCH0)
  				memcpy(&pxp->pxp_conf_state.dither_fetch_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_FETCH1)
  				memcpy(&pxp->pxp_conf_state.dither_fetch_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_STORE0)
  				memcpy(&pxp->pxp_conf_state.dither_store_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_DITHER_STORE1)
  				memcpy(&pxp->pxp_conf_state.dither_store_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  		}
  
  		if (proc_data->engine_enable & PXP_ENABLE_WFE_A) {
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_FETCH0)
  				memcpy(&pxp->pxp_conf_state.wfe_a_fetch_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_FETCH1)
  				memcpy(&pxp->pxp_conf_state.wfe_a_fetch_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_STORE0)
  				memcpy(&pxp->pxp_conf_state.wfe_a_store_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_A_STORE1)
  				memcpy(&pxp->pxp_conf_state.wfe_a_store_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  		}
  
  		if (proc_data->engine_enable & PXP_ENABLE_WFE_B) {
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_FETCH0)
  				memcpy(&pxp->pxp_conf_state.wfe_b_fetch_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_FETCH1)
  				memcpy(&pxp->pxp_conf_state.wfe_b_fetch_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_STORE0)
  				memcpy(&pxp->pxp_conf_state.wfe_b_store_param[0],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  			if (child->layer_param.processing_param.flag & PXP_BUF_FLAG_WFE_B_STORE1)
  				memcpy(&pxp->pxp_conf_state.wfe_b_store_param[1],
  				       &child->layer_param.processing_param,
  				       sizeof(struct pxp_layer_param));
  		}
  
  		i++;
  	}
  	pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
  		 pxp->pxp_conf_state.s0_param.width,
  		 pxp->pxp_conf_state.s0_param.height,
  		 pxp->pxp_conf_state.s0_param.paddr);
  	pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
  		 pxp->pxp_conf_state.out_param.width,
  		 pxp->pxp_conf_state.out_param.height,
  		 pxp->pxp_conf_state.out_param.paddr);
  }
  
  static void pxpdma_dostart_work(struct pxps *pxp)
  {
  	struct pxp_channel *pxp_chan = NULL;
  	unsigned long flags;
  	struct pxp_tx_desc *desc = NULL;
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &config_data->proc_data;
  
  	spin_lock_irqsave(&pxp->lock, flags);
  
  	desc = list_entry(head.next, struct pxp_tx_desc, list);
  	pxp_chan = to_pxp_channel(desc->txd.chan);
  
  	__pxpdma_dostart(pxp_chan);
  
  	/* Configure PxP */
  	pxp_config(pxp, pxp_chan);
  
  	if (proc_data->working_mode & PXP_MODE_STANDARD) {
  		if(!pxp_is_v3p(pxp) || !(proc_data->engine_enable & PXP_ENABLE_DITHER))
  			pxp_start2(pxp);
  	} else
  		pxp_start(pxp);
  
  	spin_unlock_irqrestore(&pxp->lock, flags);
  }
  
  static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
  {
  	unsigned long flags;
  	struct pxp_tx_desc *desc = NULL;
  
  	do {
  		desc = pxpdma_first_queued(pxp_chan);
  		spin_lock_irqsave(&pxp->lock, flags);
  		list_move_tail(&desc->list, &head);
  		spin_unlock_irqrestore(&pxp->lock, flags);
  	} while (!list_empty(&pxp_chan->queue));
  }
  
  static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
  {
  	struct pxp_tx_desc *desc = to_tx_desc(tx);
  	struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
  	dma_cookie_t cookie;
  
  	dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
  
  	/* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
  	spin_lock(&pxp_chan->lock);
  
  	cookie = pxp_chan->dma_chan.cookie;
  
  	if (++cookie < 0)
  		cookie = 1;
  
  	/* from dmaengine.h: "last cookie value returned to client" */
  	pxp_chan->dma_chan.cookie = cookie;
  	tx->cookie = cookie;
  
  	/* Here we add the tx descriptor to our PxP task queue. */
  	list_add_tail(&desc->list, &pxp_chan->queue);
  
  	spin_unlock(&pxp_chan->lock);
  
  	dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
  
  	return cookie;
  }
  
  /**
   * pxp_init_channel() - initialize a PXP channel.
   * @pxp_dma:   PXP DMA context.
   * @pchan:  pointer to the channel object.
   * @return      0 on success or negative error code on failure.
   */
  static int pxp_init_channel(struct pxp_dma *pxp_dma,
  			    struct pxp_channel *pxp_chan)
  {
  	int ret = 0;
  
  	/*
  	 * We are using _virtual_ channel here.
  	 * Each channel contains all parameters of corresponding layers
  	 * for one transaction; each layer is represented as one descriptor
  	 * (i.e., pxp_tx_desc) here.
  	 */
  
  	INIT_LIST_HEAD(&pxp_chan->queue);
  
  	return ret;
  }
  
  static irqreturn_t pxp_irq(int irq, void *dev_id)
  {
  	struct pxps *pxp = dev_id;
  	struct pxp_channel *pxp_chan;
  	struct pxp_tx_desc *desc;
  	struct pxp_tx_desc *child, *_child;
  	dma_async_tx_callback callback;
  	void *callback_param;
  	unsigned long flags;
  	u32 hist_status;
  	int pxp_irq_status = 0;
  
  	dump_pxp_reg(pxp);
  
  
  	if (__raw_readl(pxp->base + HW_PXP_STAT) & BM_PXP_STAT_IRQ0)
  		__raw_writel(BM_PXP_STAT_IRQ0, pxp->base + HW_PXP_STAT_CLR);
  	else {
  		int irq_clr = 0;
  
  		pxp_irq_status = __raw_readl(pxp->base + HW_PXP_IRQ);
  		BUG_ON(!pxp_irq_status);
  
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_B_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_B_STORE_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_A_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_A_STORE_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_DITHER_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_DITHER_STORE_IRQ;
  
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ;
  
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ;
  
  		if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ)
  			irq_clr |= BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ)
  			irq_clr |= BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH0_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_DITHER_CH0_STORE_IRQ;
  		if (pxp_irq_status & BM_PXP_IRQ_DITHER_CH1_STORE_IRQ)
  			irq_clr |= BM_PXP_IRQ_DITHER_CH1_STORE_IRQ;
  		/*XXX other irqs status clear should be added below */
  
  		__raw_writel(irq_clr, pxp->base + HW_PXP_IRQ_CLR);
  	}
  	pxp_collision_status_report(pxp, &col_info);
  	pxp_histogram_status_report(pxp, &hist_status);
  	/*XXX before a new update operation, we should
  	 * always clear all the collision information
  	 */
  	pxp_collision_detection_disable(pxp);
  	pxp_histogram_disable(pxp);
  
  	pxp_soft_reset(pxp);
  	if (pxp->devdata && pxp->devdata->pxp_data_path_config)
  		pxp->devdata->pxp_data_path_config(pxp);
  	__raw_writel(0xffff, pxp->base + HW_PXP_IRQ_MASK);
  
  	spin_lock_irqsave(&pxp->lock, flags);
  	if (list_empty(&head)) {
  		pxp->pxp_ongoing = 0;
  		spin_unlock_irqrestore(&pxp->lock, flags);
  		return IRQ_NONE;
  	}
  
  	/* Get descriptor and call callback */
  	desc = list_entry(head.next, struct pxp_tx_desc, list);
  	pxp_chan = to_pxp_channel(desc->txd.chan);
  
  	pxp_chan->completed = desc->txd.cookie;
  
  	callback = desc->txd.callback;
  	callback_param = desc->txd.callback_param;
  
  	/* Send histogram status back to caller */
  	desc->hist_status = hist_status;
  
  	if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
  		callback(callback_param);
  
  	pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  
  	list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
  		list_del_init(&child->list);
  		kmem_cache_free(tx_desc_cache, (void *)child);
  	}
  	list_del_init(&desc->list);
  	kmem_cache_free(tx_desc_cache, (void *)desc);
  
  
  	complete(&pxp->complete);
  	pxp->pxp_ongoing = 0;
  	mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
  
  	spin_unlock_irqrestore(&pxp->lock, flags);
  
  	return IRQ_HANDLED;
  }
  
  /* allocate/free dma tx descriptor dynamically*/
  static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
  {
  	struct pxp_tx_desc *desc = NULL;
  	struct dma_async_tx_descriptor *txd = NULL;
  
  	desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
  	if (desc == NULL)
  		return NULL;
  
  	INIT_LIST_HEAD(&desc->list);
  	INIT_LIST_HEAD(&desc->tx_list);
  	txd = &desc->txd;
  	dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
  	txd->tx_submit = pxp_tx_submit;
  
  	return desc;
  }
  
  
  /* Allocate and initialise a transfer descriptor. */
  static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
  							 struct scatterlist
  							 *sgl,
  							 unsigned int sg_len,
  							 enum
  							 dma_transfer_direction
  							 direction,
  							 unsigned long tx_flags,
  							 void *context)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  	struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  	struct pxps *pxp = to_pxp(pxp_dma);
  	struct pxp_tx_desc *pos = NULL, *next = NULL;
  	struct pxp_tx_desc *desc = NULL;
  	struct pxp_tx_desc *first = NULL, *prev = NULL;
  	struct scatterlist *sg;
  	dma_addr_t phys_addr;
  	int i;
  
  	if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
  		dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
  			direction);
  		return NULL;
  	}
  
  	if (unlikely(sg_len < 2))
  		return NULL;
  
  	for_each_sg(sgl, sg, sg_len, i) {
  		desc = pxpdma_desc_alloc(pxp_chan);
  		if (!desc) {
  			dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
  
  			if (first) {
  				list_for_each_entry_safe(pos, next, &first->tx_list, list) {
  					list_del_init(&pos->list);
  					kmem_cache_free(tx_desc_cache, (void*)pos);
  				}
  				list_del_init(&first->list);
  				kmem_cache_free(tx_desc_cache, (void*)first);
  			}
  
  			return NULL;
  		}
  
  		phys_addr = sg_dma_address(sg);
  
  		if (!first) {
  			first = desc;
  
  			desc->layer_param.s0_param.paddr = phys_addr;
  		} else {
  			list_add_tail(&desc->list, &first->tx_list);
  			prev->next = desc;
  			desc->next = NULL;
  
  			if (i == 1)
  				desc->layer_param.out_param.paddr = phys_addr;
  			else
  				desc->layer_param.ol_param.paddr = phys_addr;
  		}
  
  		prev = desc;
  	}
  
  	pxp->pxp_conf_state.layer_nr = sg_len;
  	first->txd.flags = tx_flags;
  	first->len = sg_len;
  	pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
  		 __func__, __LINE__, first, first->len, first->txd.flags);
  
  	return &first->txd;
  }
  
  static void pxp_issue_pending(struct dma_chan *chan)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  	struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  	struct pxps *pxp = to_pxp(pxp_dma);
  
  	spin_lock(&pxp_chan->lock);
  
  	if (list_empty(&pxp_chan->queue)) {
  		spin_unlock(&pxp_chan->lock);
  		return;
  	}
  
  	pxpdma_dequeue(pxp_chan, pxp);
  	pxp_chan->status = PXP_CHANNEL_READY;
  
  	spin_unlock(&pxp_chan->lock);
  
  	pxp_clk_enable(pxp);
  	wake_up_interruptible(&pxp->thread_waitq);
  }
  
  static void __pxp_terminate_all(struct dma_chan *chan)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  	pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  }
  
  static int pxp_device_terminate_all(struct dma_chan *chan)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  
  	spin_lock(&pxp_chan->lock);
  	__pxp_terminate_all(chan);
  	spin_unlock(&pxp_chan->lock);
  
  	return 0;
  }
  
  static int pxp_alloc_chan_resources(struct dma_chan *chan)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  	struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  	int ret;
  
  	/* dmaengine.c now guarantees to only offer free channels */
  	BUG_ON(chan->client_count > 1);
  	WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
  
  	chan->cookie = 1;
  	pxp_chan->completed = -ENXIO;
  
  	pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
  	ret = pxp_init_channel(pxp_dma, pxp_chan);
  	if (ret < 0)
  		goto err_chan;
  
  	pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  
  	dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
  		chan->chan_id, pxp_chan->eof_irq);
  
  	return ret;
  
  err_chan:
  	return ret;
  }
  
  static void pxp_free_chan_resources(struct dma_chan *chan)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  
  	spin_lock(&pxp_chan->lock);
  
  	__pxp_terminate_all(chan);
  
  	pxp_chan->status = PXP_CHANNEL_FREE;
  
  	spin_unlock(&pxp_chan->lock);
  }
  
  static enum dma_status pxp_tx_status(struct dma_chan *chan,
  				     dma_cookie_t cookie,
  				     struct dma_tx_state *txstate)
  {
  	struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  
  	if (cookie != chan->cookie)
  		return DMA_ERROR;
  
  	if (txstate) {
  		txstate->last = pxp_chan->completed;
  		txstate->used = chan->cookie;
  		txstate->residue = 0;
  	}
  	return DMA_COMPLETE;
  }
  
  static void pxp_data_path_config_v3p(struct pxps *pxp)
  {
  	u32 val = 0;
  
  	__raw_writel(
  		BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(1)|
  		BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(1)|
  		BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(0)|
  		BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(0),
  		pxp->base + HW_PXP_DATA_PATH_CTRL0);
  
  	/*
  	 * MUX17: HIST_B as histogram: 0: output buffer, 1: wfe_store
  	 * MUX16: HIST_A as collision: 0: output buffer, 1: wfe_store
  	 */
  	if (pxp_is_v3(pxp))
  		val = BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1)|
  		      BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(0);
  	else if (pxp_is_v3p(pxp))
  		val = BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1)|
  		      BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(1);
  	__raw_writel(val, pxp->base + HW_PXP_DATA_PATH_CTRL1);
  }
  
  static void pxp_soft_reset(struct pxps *pxp)
  {
  	__raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
  	__raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
  
  	__raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_SET);
  	while (!(__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_CLKGATE))
  		dev_dbg(pxp->dev, "%s: wait for clock gate off", __func__);
  
  	__raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL_CLR);
  	__raw_writel(BM_PXP_CTRL_CLKGATE, pxp->base + HW_PXP_CTRL_CLR);
  }
  
  static void pxp_sram_init(struct pxps *pxp, u32 select,
  			u32 buffer_addr, u32 length)
  {
  	u32 i;
  
  	__raw_writel(
  		BF_PXP_INIT_MEM_CTRL_ADDR(0) |
  		BF_PXP_INIT_MEM_CTRL_SELECT(select) |
  		BF_PXP_INIT_MEM_CTRL_START(1),
  		pxp->base + HW_PXP_INIT_MEM_CTRL);
  
  	if ((select == WFE_A) || (select == WFE_B)) {
  		for (i = 0; i < length / 2; i++) {
  			__raw_writel(*(((u32*)buffer_addr) + 2 * i + 1),
  				pxp->base + HW_PXP_INIT_MEM_DATA_HIGH);
  
  			__raw_writel(*(((u32*)buffer_addr) + 2 * i),
  				pxp->base + HW_PXP_INIT_MEM_DATA);
  		}
  	} else {
  		for (i = 0; i < length; i++) {
  			__raw_writel(*(((u32*) buffer_addr) + i),
  				pxp->base + HW_PXP_INIT_MEM_DATA);
  		}
  	}
  
  	__raw_writel(
  		BF_PXP_INIT_MEM_CTRL_ADDR(0) |
  		BF_PXP_INIT_MEM_CTRL_SELECT(select) |
  		BF_PXP_INIT_MEM_CTRL_START(0),
  		pxp->base + HW_PXP_INIT_MEM_CTRL);
  }
  
  /*
   * wfe a configuration
   * configure wfe a engine for waveform processing
   * including its fetch and store module
   */
  static void pxp_wfe_a_configure(struct pxps *pxp)
  {
  	/* FETCH */
  	__raw_writel(
  		BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
  		BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
  		pxp->base + HW_PXP_WFA_FETCH_CTRL);
  
  	__raw_writel(
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_SIGN_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_H_OFS(0) |
  		BF_PXP_WFA_ARRAY_PIXEL0_MASK_L_OFS(3),
  		pxp->base + HW_PXP_WFA_ARRAY_PIXEL0_MASK);
  
  	 __raw_writel(
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_SIGN_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_H_OFS(4) |
  		BF_PXP_WFA_ARRAY_PIXEL1_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFA_ARRAY_PIXEL1_MASK);
  
  	 __raw_writel(
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_SIGN_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_BUF_SEL(1) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_H_OFS(8) |
  		BF_PXP_WFA_ARRAY_PIXEL3_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFA_ARRAY_PIXEL2_MASK);
  
  	__raw_writel(
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_SIGN_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_OFFSET_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_BUF_SEL(1) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_H_OFS(10) |
  		BF_PXP_WFA_ARRAY_PIXEL4_MASK_L_OFS(15),
  		pxp->base + HW_PXP_WFA_ARRAY_PIXEL3_MASK);
  
  	__raw_writel(
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_SIGN_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_BUF_SEL(0) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_H_OFS(4) |
  		BF_PXP_WFA_ARRAY_PIXEL2_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFA_ARRAY_PIXEL4_MASK);
  
  	__raw_writel(1, pxp->base + HW_PXP_WFA_ARRAY_REG2);
  
  	/* STORE */
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_CTRL_CH0_CH_EN(1)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_EN(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_BLOCK_16(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_EN(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_PACK_IN_SEL(1)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_WR_NUM_BYTES(8)|
  		BF_PXP_WFE_A_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
  		BF_PXP_WFE_A_STORE_CTRL_CH0_ARBIT_EN(0),
  		pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH0);
  
  	__raw_writel(
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
  		 BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
  		pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
  		pxp->base + HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH0);
  
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(1)|
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_A_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
  		pxp->base + HW_PXP_WFE_A_STORE_SHIFT_CTRL_CH1);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
  		pxp->base + HW_PXP_WFE_A_STORE_FILL_DATA_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK0_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xf), /* fetch CP */
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK0_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK1_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xf00), /* fetch NP */
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK1_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK2_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x00000),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK2_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK3_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(0x3f000000), /* fetch LUT */
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK3_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(0xf),
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK4_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(0x0), /* fetch Y4 */
  		pxp->base + HW_PXP_WFE_A_STORE_D_MASK4_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(1) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(28)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(24)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(18)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(1),
  		pxp->base + HW_PXP_WFE_A_STORE_D_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(28) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0) |
  		BF_PXP_WFE_A_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0),
  		pxp->base + HW_PXP_WFE_A_STORE_D_SHIFT_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(1)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(1)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(32+6)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(1)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(32+6)|
  		BF_PXP_WFE_A_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(1),
  		pxp->base + HW_PXP_WFE_A_STORE_F_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK4(0)|
  		BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK5(0)|
  		BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK6(0)|
  		BF_PXP_WFE_A_STORE_F_MASK_H_CH0_F_MASK7(0),
  		pxp->base + HW_PXP_WFE_A_STORE_F_MASK_H_CH0);
  
  
  	__raw_writel(
  		BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK0(0x1) |
  		BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK1(0x2) |
  		BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK2(0x4) |
  		BF_PXP_WFE_A_STORE_F_MASK_L_CH0_F_MASK3(0x8),
  		pxp->base + HW_PXP_WFE_A_STORE_F_MASK_L_CH0);
  
  	/* ALU */
  	__raw_writel(BF_PXP_ALU_A_INST_ENTRY_ENTRY_ADDR(0),
  		pxp->base + HW_PXP_ALU_A_INST_ENTRY);
  
  	__raw_writel(BF_PXP_ALU_A_PARAM_PARAM0(0) |
  		BF_PXP_ALU_A_PARAM_PARAM1(0),
  		pxp->base + HW_PXP_ALU_A_PARAM);
  
  	__raw_writel(BF_PXP_ALU_A_CONFIG_BUF_ADDR(0),
  		pxp->base + HW_PXP_ALU_A_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_A_LUT_CONFIG_MODE(0) |
  		BF_PXP_ALU_A_LUT_CONFIG_EN(0),
  		pxp->base + HW_PXP_ALU_A_LUT_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_A_LUT_DATA0_LUT_DATA_L(0),
  		pxp->base + HW_PXP_ALU_A_LUT_DATA0);
  
  	__raw_writel(BF_PXP_ALU_A_LUT_DATA1_LUT_DATA_H(0),
  		pxp->base + HW_PXP_ALU_A_LUT_DATA1);
  
  	__raw_writel(BF_PXP_ALU_A_CTRL_BYPASS    (1) |
  		BF_PXP_ALU_A_CTRL_ENABLE    (1) |
  		BF_PXP_ALU_A_CTRL_START     (0) |
  		BF_PXP_ALU_A_CTRL_SW_RESET  (0),
  		pxp->base + HW_PXP_ALU_A_CTRL);
  
  	/* WFE A */
  	__raw_writel(0x3F3F3F03, pxp->base + HW_PXP_WFE_A_STAGE1_MUX0);
  	__raw_writel(0x0C00000C, pxp->base + HW_PXP_WFE_A_STAGE1_MUX1);
  	__raw_writel(0x01040000, pxp->base + HW_PXP_WFE_A_STAGE1_MUX2);
  	__raw_writel(0x0A0A0904, pxp->base + HW_PXP_WFE_A_STAGE1_MUX3);
  	__raw_writel(0x00000B0B, pxp->base + HW_PXP_WFE_A_STAGE1_MUX4);
  
  	__raw_writel(0x1800280E, pxp->base + HW_PXP_WFE_A_STAGE2_MUX0);
  	__raw_writel(0x00280E00, pxp->base + HW_PXP_WFE_A_STAGE2_MUX1);
  	__raw_writel(0x280E0018, pxp->base + HW_PXP_WFE_A_STAGE2_MUX2);
  	__raw_writel(0x00001800, pxp->base + HW_PXP_WFE_A_STAGE2_MUX3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX4);
  	__raw_writel(0x1800280E, pxp->base + HW_PXP_WFE_A_STAGE2_MUX5);
  	__raw_writel(0x00280E00, pxp->base + HW_PXP_WFE_A_STAGE2_MUX6);
  	__raw_writel(0x1A0E0018, pxp->base + HW_PXP_WFE_A_STAGE2_MUX7);
  	__raw_writel(0x1B002911, pxp->base + HW_PXP_WFE_A_STAGE2_MUX8);
  	__raw_writel(0x00002911, pxp->base + HW_PXP_WFE_A_STAGE2_MUX9);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX10);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX11);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STAGE2_MUX12);
  
  	__raw_writel(0x07060504, pxp->base + HW_PXP_WFE_A_STAGE3_MUX0);
  	__raw_writel(0x3F3F3F08, pxp->base + HW_PXP_WFE_A_STAGE3_MUX1);
  	__raw_writel(0x03020100, pxp->base + HW_PXP_WFE_A_STAGE3_MUX2);
  	__raw_writel(0x3F3F3F3F, pxp->base + HW_PXP_WFE_A_STAGE3_MUX3);
  
  	__raw_writel(0x000F0F0F, pxp->base + HW_PXP_WFE_A_STAGE2_5X6_MASKS_0);
  	__raw_writel(0x3f030100, pxp->base + HW_PXP_WFE_A_STAGE2_5X6_ADDR_0);
  
  	__raw_writel(0x00000700, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT0);
  	__raw_writel(0x0000F000, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT1);
  	__raw_writel(0x0000A000, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT2);
  	__raw_writel(0x000000C0, pxp->base + HW_PXP_WFE_A_STG2_5X1_OUT3);
  	__raw_writel(0x070F0F0F, pxp->base + HW_PXP_WFE_A_STG2_5X1_MASKS);
  
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_2);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_3);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_4);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_5);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_6);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT1_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT2_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT3_7);
  
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_0);
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_1);
  	__raw_writel(0x04050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_2);
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT0_7);
  
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_0);
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_1);
  	__raw_writel(0x05080808, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_2);
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT1_7);
  
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_0);
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_1);
  	__raw_writel(0x070C0C0C, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_2);
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT2_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_A_STG2_5X6_OUT3_7);
  }
  
  static void pxp_wfe_a_configure_v3p(struct pxps *pxp)
  {
  	/* FETCH */
  	__raw_writel(
  		BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
  		pxp->base + HW_PXP_WFB_FETCH_CTRL);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS(3),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL0_MASK);
  
  	 __raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS(4) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL1_MASK);
  
  	 __raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL2_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS(10) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS(15),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL3_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS(4) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL4_MASK);
  
  	__raw_writel(1, pxp->base + HW_PXP_WFB_ARRAY_REG2);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(2) |    // 0: Y4C  1: WB   2: sw_reg2
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(0),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
  
  	/* STORE */
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(8)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
  		pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH0);
  
  	__raw_writel(
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(1)|
  		 BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(16),
  		pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
  		pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
  
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(1)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
  		pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
  		pxp->base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xf), /* fetch CP */
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xf00), /* fetch NP */
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x00000),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK3_H_CH0_D_MASK3_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK3_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK3_L_CH0_D_MASK3_L_CH0(0x3f000000), /* fetch LUT */
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK3_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK4_H_CH0_D_MASK4_H_CH0(0xf),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK4_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK4_L_CH0_D_MASK4_L_CH0(0x0), /* fetch Y4 */
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK4_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(1) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(28)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(24)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(18)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(1),
  		pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(28) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH4(3)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG4(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH5(5)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG5(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH6(32+2)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG6(1)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_WIDTH7(32+2)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_H_CH0_F_SHIFT_FLAG7(1),
  		pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4(0x10)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5(0x20)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6(0x40)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7(0x80),
  		pxp->base + HW_PXP_WFE_B_STORE_F_MASK_H_CH0);
  
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(0x0) |
  		BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0x0) |
  		BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0x0) |
  		BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
  
  	/* ALU */
  	__raw_writel(BF_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR(0),
  		pxp->base + HW_PXP_ALU_B_INST_ENTRY);
  
  	__raw_writel(BF_PXP_ALU_B_PARAM_PARAM0(0) |
  		BF_PXP_ALU_B_PARAM_PARAM1(0),
  		pxp->base + HW_PXP_ALU_B_PARAM);
  
  	__raw_writel(BF_PXP_ALU_B_CONFIG_BUF_ADDR(0),
  		pxp->base + HW_PXP_ALU_B_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_CONFIG_MODE(0) |
  		BF_PXP_ALU_B_LUT_CONFIG_EN(0),
  		pxp->base + HW_PXP_ALU_B_LUT_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_DATA0_LUT_DATA_L(0),
  		pxp->base + HW_PXP_ALU_B_LUT_DATA0);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_DATA1_LUT_DATA_H(0),
  		pxp->base + HW_PXP_ALU_B_LUT_DATA1);
  
  	__raw_writel(BF_PXP_ALU_B_CTRL_BYPASS    (1) |
  		BF_PXP_ALU_B_CTRL_ENABLE    (1) |
  		BF_PXP_ALU_B_CTRL_START     (0) |
  		BF_PXP_ALU_B_CTRL_SW_RESET  (0),
  		pxp->base + HW_PXP_ALU_B_CTRL);
  
  	/* WFE A */
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX2);
  	__raw_writel(0x03000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX4);
  	__raw_writel(0x04000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX5);
  	__raw_writel(0x00090401, pxp->base + HW_PXP_WFE_B_STAGE1_MUX6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX7);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX8);
  
  	__raw_writel(0x1901290C, pxp->base + HW_PXP_WFE_B_STAGE2_MUX0);
  	__raw_writel(0x01290C00, pxp->base + HW_PXP_WFE_B_STAGE2_MUX1);
  	__raw_writel(0x290C0019, pxp->base + HW_PXP_WFE_B_STAGE2_MUX2);
  	__raw_writel(0x00001901, pxp->base + HW_PXP_WFE_B_STAGE2_MUX3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX4);
  	__raw_writel(0x1901290C, pxp->base + HW_PXP_WFE_B_STAGE2_MUX5);
  	__raw_writel(0x01290C00, pxp->base + HW_PXP_WFE_B_STAGE2_MUX6);
  	__raw_writel(0x1B0C0019, pxp->base + HW_PXP_WFE_B_STAGE2_MUX7);
  	__raw_writel(0x1C002A0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX8);
  	__raw_writel(0x00002A0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX9);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX10);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX11);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_MUX12);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX2);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX7);
  	__raw_writel(0x07060504, pxp->base + HW_PXP_WFE_B_STAGE3_MUX8);
  	__raw_writel(0x00000008, pxp->base + HW_PXP_WFE_B_STAGE3_MUX9);
  	__raw_writel(0x03020100, pxp->base + HW_PXP_WFE_B_STAGE3_MUX10);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_2);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_7);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_2);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_7);
  
  	__raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STAGE1_5X8_MASKS_0);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X1_OUT0);
  	__raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STG1_5X1_MASKS);
  
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_2);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_3);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_4);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_5);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_6);
  	__raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_7);
  
  	__raw_writel(0x00000700, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT0);
  	__raw_writel(0x0000F000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT1);
  	__raw_writel(0x0000A000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT2);
  	__raw_writel(0x000000C0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT3);
  	__raw_writel(0x070F0F0F, pxp->base + HW_PXP_WFE_B_STG2_5X1_MASKS);
  
  	__raw_writel(0x000F0F0F, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_MASKS_0);
  	__raw_writel(0x3f232120, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_ADDR_0);
  
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_0);
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_1);
  	__raw_writel(0x04050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_2);
  	__raw_writel(0x04040404, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_7);
  
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_0);
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_1);
  	__raw_writel(0x05080808, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_2);
  	__raw_writel(0x05050505, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_7);
  
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_0);
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_1);
  	__raw_writel(0x070C0C0C, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_2);
  	__raw_writel(0x07070707, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT2_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT3_7);
  
  	__raw_writel(0x00007F7F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_MASKS);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_0);
  	__raw_writel(0x00FF00FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_2);
  	__raw_writel(0x000000FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_7);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_0);
  	__raw_writel(0xFF3FFF3F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_2);
  	__raw_writel(0xFFFFFF1F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_7);
  }
  
  /*
   *  wfe a processing
   * use wfe a to process an update
   * x,y,width,height:
   *         coordinate and size of the update region
   * wb:
   *         working buffer, 16bpp
   * upd:
   *         update buffer, in Y4 with or without alpha, 8bpp
   * twb:
   *         temp working buffer, 16bpp
   *         only used when reagl_en is 1
   * y4c:
   *         y4c buffer, {Y4[3:0],3'b000,collision}, 8bpp
   * lut:
   *         valid value 0-63
   *         set to the lut used for next update
   * partial:
   *         0 - full update
   *         1 - partial update
   * reagl_en:
   *         0 - use normal waveform algorithm
   *         1 - enable reagl/-d waveform algorithm
   * detection_only:
   *         0 - write working buffer
   *         1 - do no write working buffer, detection only
   * alpha_en:
   *         0 - upd is {Y4[3:0],4'b0000} format
   *         1 - upd is {Y4[3:0],3'b000,alpha} format
   */
  static void pxp_wfe_a_process(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &config_data->proc_data;
  	struct pxp_layer_param *fetch_ch0 = &config_data->wfe_a_fetch_param[0];
  	struct pxp_layer_param *fetch_ch1 = &config_data->wfe_a_fetch_param[1];
  	struct pxp_layer_param *store_ch0 = &config_data->wfe_a_store_param[0];
  	struct pxp_layer_param *store_ch1 = &config_data->wfe_a_store_param[1];
  	int v;
  
  	if (fetch_ch0->width != fetch_ch1->width ||
  		fetch_ch0->height != fetch_ch1->height) {
  		dev_err(pxp->dev, "width/height should be same for two fetch "
  				"channels\n");
  	}
  
  	print_param(fetch_ch0, "wfe_a fetch_ch0");
  	print_param(fetch_ch1, "wfe_a fetch_ch1");
  	print_param(store_ch0, "wfe_a store_ch0");
  	print_param(store_ch1, "wfe_a store_ch1");
  
  	/* Fetch */
  	__raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFA_FETCH_BUF1_ADDR);
  
  	__raw_writel(BF_PXP_WFA_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
  		BF_PXP_WFA_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
  		pxp->base + HW_PXP_WFA_FETCH_BUF1_CORD);
  
  	__raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_WFA_FETCH_BUF1_PITCH);
  
  	__raw_writel(BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height - 1) |
  		BF_PXP_WFA_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width - 1),
  		pxp->base + HW_PXP_WFA_FETCH_BUF1_SIZE);
  
  	__raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFA_FETCH_BUF2_ADDR);
  
  	__raw_writel(BF_PXP_WFA_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
  		BF_PXP_WFA_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
  		pxp->base + HW_PXP_WFA_FETCH_BUF2_CORD);
  
  	__raw_writel(fetch_ch1->stride * 2, pxp->base + HW_PXP_WFA_FETCH_BUF2_PITCH);
  
  	__raw_writel(BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height - 1) |
  		BF_PXP_WFA_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width - 1),
  		pxp->base + HW_PXP_WFA_FETCH_BUF2_SIZE);
  
  	/* Store */
  	__raw_writel(BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
  		BF_PXP_WFE_A_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
  		pxp->base + HW_PXP_WFE_A_STORE_SIZE_CH0);
  
  
  	__raw_writel(BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
  		BF_PXP_WFE_A_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
  		pxp->base + HW_PXP_WFE_A_STORE_SIZE_CH1);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
  		BF_PXP_WFE_A_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
  		pxp->base + HW_PXP_WFE_A_STORE_PITCH);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
  		pxp->base + HW_PXP_WFE_A_STORE_ADDR_0_CH0);
  	__raw_writel(BF_PXP_WFE_A_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_A_STORE_ADDR_1_CH0);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(
  		store_ch1->paddr + (store_ch1->left + store_ch1->top *
  		store_ch1->stride) * 2),
  		pxp->base + HW_PXP_WFE_A_STORE_ADDR_0_CH1);
  
  	__raw_writel(BF_PXP_WFE_A_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_A_STORE_ADDR_1_CH1);
  
  	/* ALU */
  	__raw_writel(BF_PXP_ALU_A_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
  	        BF_PXP_ALU_A_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_ALU_A_BUF_SIZE);
  
  	/* WFE */
  	__raw_writel(BF_PXP_WFE_A_DIMENSIONS_WIDTH(fetch_ch0->width) |
  		BF_PXP_WFE_A_DIMENSIONS_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_WFE_A_DIMENSIONS);
  
  	/* Here it should be fetch_ch1 */
  	__raw_writel(BF_PXP_WFE_A_OFFSET_X_OFFSET(fetch_ch1->left) |
  		BF_PXP_WFE_A_OFFSET_Y_OFFSET(fetch_ch1->top),
  		pxp->base + HW_PXP_WFE_A_OFFSET);
  
  	__raw_writel((proc_data->lut & 0x000000FF) | 0x00000F00,
  			pxp->base + HW_PXP_WFE_A_SW_DATA_REGS);
  	__raw_writel((proc_data->partial_update | (proc_data->reagl_en << 1)),
  			pxp->base + HW_PXP_WFE_A_SW_FLAG_REGS);
  
  	__raw_writel(
  		BF_PXP_WFE_A_CTRL_ENABLE(1) |
  		BF_PXP_WFE_A_CTRL_SW_RESET(1),
  		pxp->base + HW_PXP_WFE_A_CTRL);
  
  	/* disable CH1 when only doing detection */
  	v = __raw_readl(pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
  	if (proc_data->detection_only) {
  		v &= ~BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1);
  		printk(KERN_EMERG "%s: detection only happens\n", __func__);
  	} else
  		v |= BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1);
  	__raw_writel(v, pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
  }
  
  static void pxp_wfe_a_process_v3p(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &config_data->proc_data;
  	struct pxp_layer_param *fetch_ch0 = &config_data->wfe_a_fetch_param[0];
  	struct pxp_layer_param *fetch_ch1 = &config_data->wfe_a_fetch_param[1];
  	struct pxp_layer_param *store_ch0 = &config_data->wfe_a_store_param[0];
  	struct pxp_layer_param *store_ch1 = &config_data->wfe_a_store_param[1];
  	int v;
  
  	if (fetch_ch0->width != fetch_ch1->width ||
  		fetch_ch0->height != fetch_ch1->height) {
  		dev_err(pxp->dev, "width/height should be same for two fetch "
  				"channels\n");
  	}
  
  	print_param(fetch_ch0, "wfe_a fetch_ch0");
  	print_param(fetch_ch1, "wfe_a fetch_ch1");
  	print_param(store_ch0, "wfe_a store_ch0");
  	print_param(store_ch1, "wfe_a store_ch1");
  
  	/* Fetch */
  	__raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF1_ADDR);
  
  	__raw_writel(BF_PXP_WFB_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
  		BF_PXP_WFB_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
  		pxp->base + HW_PXP_WFB_FETCH_BUF1_CORD);
  
  	__raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_WFB_FETCH_BUF1_PITCH);
  
  	__raw_writel(BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height - 1) |
  		BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width - 1),
  		pxp->base + HW_PXP_WFB_FETCH_BUF1_SIZE);
  
  	__raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF2_ADDR);
  
  	__raw_writel(BF_PXP_WFB_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
  		BF_PXP_WFB_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
  		pxp->base + HW_PXP_WFB_FETCH_BUF2_CORD);
  
  	__raw_writel(fetch_ch1->stride * 2, pxp->base + HW_PXP_WFB_FETCH_BUF2_PITCH);
  
  	__raw_writel(BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height - 1) |
  		BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width - 1),
  		pxp->base + HW_PXP_WFB_FETCH_BUF2_SIZE);
  
  	/* Store */
  	__raw_writel(BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
  		BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
  		pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH0);
  
  
  	__raw_writel(BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
  		BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
  		pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
  		BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
  		pxp->base + HW_PXP_WFE_B_STORE_PITCH);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(
  		store_ch1->paddr + (store_ch1->left + store_ch1->top *
  		store_ch1->stride) * 2),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
  
  	/* ALU */
  	__raw_writel(BF_PXP_ALU_B_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
  	        BF_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_ALU_B_BUF_SIZE);
  
  	/* WFE */
  	__raw_writel(BF_PXP_WFE_B_DIMENSIONS_WIDTH(fetch_ch0->width) |
  		BF_PXP_WFE_B_DIMENSIONS_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_WFE_B_DIMENSIONS);
  
  	/* Here it should be fetch_ch1 */
  	__raw_writel(BF_PXP_WFE_B_OFFSET_X_OFFSET(fetch_ch1->left) |
  		BF_PXP_WFE_B_OFFSET_Y_OFFSET(fetch_ch1->top),
  		pxp->base + HW_PXP_WFE_B_OFFSET);
  
  	__raw_writel((proc_data->lut & 0x000000FF) | 0x00000F00,
  			pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
  	__raw_writel((proc_data->partial_update | (proc_data->reagl_en << 1)),
  			pxp->base + HW_PXP_WFE_B_SW_FLAG_REGS);
  
  	__raw_writel(
  		BF_PXP_WFE_B_CTRL_ENABLE(1) |
  		BF_PXP_WFE_B_CTRL_SW_RESET(1),
  		pxp->base + HW_PXP_WFE_B_CTRL);
  
         if (proc_data->alpha_en) {
  		__raw_writel(BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(0),
  			pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
          } else {
  		__raw_writel(BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(2) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(0) |
  			BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(0),
  			pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
          }
  
  	/* disable CH1 when only doing detection */
  	v = __raw_readl(pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
  	if (proc_data->detection_only) {
  		v &= ~BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1);
  		printk(KERN_EMERG "%s: detection only happens\n", __func__);
  	} else
  		v |= BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(1);
  	__raw_writel(v, pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
  }
  
  /*
   * wfe b configuration
   *
   * configure wfe b engnine for reagl/-d waveform processing
   */
  static void pxp_wfe_b_configure(struct pxps *pxp)
  {
  	/* Fetch */
  	__raw_writel(
  		BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
  		BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
  		pxp->base + HW_PXP_WFB_FETCH_CTRL);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL0_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL0_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_H_OFS(10) |
  		BF_PXP_WFB_ARRAY_PIXEL1_MASK_L_OFS(15),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL1_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_H_OFS(2) |
  		BF_PXP_WFB_ARRAY_PIXEL2_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL2_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL3_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL3_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_SIGN_X(1) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL4_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL4_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL5_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL5_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_Y(1) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL6_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL6_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_BUF_SEL(0) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_H_OFS(0) |
  		BF_PXP_WFB_ARRAY_PIXEL7_MASK_L_OFS(7),
  		pxp->base + HW_PXP_WFB_ARRAY_PIXEL7_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_FLAG0_MASK_L_OFS(8),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG0_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_H_OFS(9) |
  		BF_PXP_WFB_ARRAY_FLAG1_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG1_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_SIGN_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_FLAG2_MASK_L_OFS(8),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG2_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_SIGN_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_H_OFS(9) |
  		BF_PXP_WFB_ARRAY_FLAG3_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG3_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_FLAG4_MASK_L_OFS(8),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG4_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_OFFSET_X(1) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_H_OFS(9) |
  		BF_PXP_WFB_ARRAY_FLAG5_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG5_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_FLAG6_MASK_L_OFS(8),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG6_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_H_OFS(9) |
  		BF_PXP_WFB_ARRAY_FLAG7_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG7_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_H_OFS(8) |
  		BF_PXP_WFB_ARRAY_FLAG8_MASK_L_OFS(8),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG8_MASK);
  
  	__raw_writel(
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_Y(0) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_Y(1) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_SIGN_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_OFFSET_X(0) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_BUF_SEL(1) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_H_OFS(9) |
  		BF_PXP_WFB_ARRAY_FLAG9_MASK_L_OFS(9),
  		pxp->base + HW_PXP_WFB_ARRAY_FLAG9_MASK);
  
  	pxp_sram_init(pxp, WFE_B, (u32)active_matrix_data_8x8, 64);
  
  
  	/* Store */
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(1) |
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
  		pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(32),
  		pxp->base + HW_PXP_WFE_B_STORE_CTRL_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(1)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
  		pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(1)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(0),
  		pxp->base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(0),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
  		pxp->base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x00000000),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0xff),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x3f00),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
  
  	__raw_writel(BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH4(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG4(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH5(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG5(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH6(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG6(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_WIDTH7(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_H_CH0_D_SHIFT_FLAG7(0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(2)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(6)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
  		pxp->base + HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(8)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
  		BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
  		pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK4(0)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK5(0)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK6(0)|
  		BF_PXP_WFE_B_STORE_F_MASK_H_CH0_F_MASK7(0),
  		pxp->base + HW_PXP_WFE_B_STORE_F_MASK_H_CH0);
  
  	/* ALU */
  	__raw_writel(BF_PXP_ALU_B_INST_ENTRY_ENTRY_ADDR(0),
  		pxp->base + HW_PXP_ALU_B_INST_ENTRY);
  
  	__raw_writel(BF_PXP_ALU_B_PARAM_PARAM0(0) |
  		BF_PXP_ALU_B_PARAM_PARAM1(0),
  		pxp->base + HW_PXP_ALU_B_PARAM);
  
  	__raw_writel(BF_PXP_ALU_B_CONFIG_BUF_ADDR(0),
  		pxp->base + HW_PXP_ALU_B_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_CONFIG_MODE(0) |
  		BF_PXP_ALU_B_LUT_CONFIG_EN(0),
  		pxp->base + HW_PXP_ALU_B_LUT_CONFIG);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_DATA0_LUT_DATA_L(0),
  		pxp->base + HW_PXP_ALU_B_LUT_DATA0);
  
  	__raw_writel(BF_PXP_ALU_B_LUT_DATA1_LUT_DATA_H(0),
  		pxp->base + HW_PXP_ALU_B_LUT_DATA1);
  
  	__raw_writel(
  		BF_PXP_ALU_B_CTRL_BYPASS    (1) |
  		BF_PXP_ALU_B_CTRL_ENABLE    (1) |
  		BF_PXP_ALU_B_CTRL_START     (0) |
  		BF_PXP_ALU_B_CTRL_SW_RESET  (0),
  		pxp->base + HW_PXP_ALU_B_CTRL);
  
  	/* WFE */
  	__raw_writel(0x00000402, pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
  
  	__raw_writel(0x02040608, pxp->base + HW_PXP_WFE_B_STAGE1_MUX0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX2);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX4);
  	__raw_writel(0x03000000, pxp->base + HW_PXP_WFE_B_STAGE1_MUX5);
  	__raw_writel(0x050A040A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX6);
  	__raw_writel(0x070A060A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX7);
  	__raw_writel(0x0000000A, pxp->base + HW_PXP_WFE_B_STAGE1_MUX8);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX0);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX1);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX2);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX4);
  	__raw_writel(0x1C1E2022, pxp->base + HW_PXP_WFE_B_STAGE2_MUX5);
  	__raw_writel(0x1215181A, pxp->base + HW_PXP_WFE_B_STAGE2_MUX6);
  	__raw_writel(0x00000C0F, pxp->base + HW_PXP_WFE_B_STAGE2_MUX7);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX8);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX9);
  	__raw_writel(0x01000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX10);
  	__raw_writel(0x000C010B, pxp->base + HW_PXP_WFE_B_STAGE2_MUX11);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE2_MUX12);
  
  	__raw_writel(0x09000C01, pxp->base + HW_PXP_WFE_B_STAGE3_MUX0);
  	__raw_writel(0x003A2A1D, pxp->base + HW_PXP_WFE_B_STAGE3_MUX1);
  	__raw_writel(0x09000C01, pxp->base + HW_PXP_WFE_B_STAGE3_MUX2);
  	__raw_writel(0x003A2A1D, pxp->base + HW_PXP_WFE_B_STAGE3_MUX3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STAGE3_MUX7);
  	__raw_writel(0x07060504, pxp->base + HW_PXP_WFE_B_STAGE3_MUX8);
  	__raw_writel(0x00000008, pxp->base + HW_PXP_WFE_B_STAGE3_MUX9);
  	__raw_writel(0x00001211, pxp->base + HW_PXP_WFE_B_STAGE3_MUX10);
  
  	__raw_writel(0x02010100, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_0);
  	__raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_1);
  	__raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_2);
  	__raw_writel(0x04030302, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT0_7);
  
  	__raw_writel(0x02010100, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_0);
  	__raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_1);
  	__raw_writel(0x03020201, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_2);
  	__raw_writel(0x04030302, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_3);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_4);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_5);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_6);
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X8_OUT1_7);
  
  	__raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STAGE1_5X8_MASKS_0);
  
  	__raw_writel(0x00000000, pxp->base + HW_PXP_WFE_B_STG1_5X1_OUT0);
  	__raw_writel(0x0000000F, pxp->base + HW_PXP_WFE_B_STG1_5X1_MASKS);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT1_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT2_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT3_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT4_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_MASKS_0);
  	__raw_writel(0x3F3F3F3F, pxp->base + HW_PXP_WFE_B_STAGE2_5X6_ADDR_0);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT0_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_0);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X6_OUT1_7);
  
  	__raw_writel(0x00008000, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT0);
  	__raw_writel(0x0000FFFE, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT2);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG2_5X1_OUT3);
  	__raw_writel(0x00000F0F, pxp->base + HW_PXP_WFE_B_STG2_5X1_MASKS);
  
  	__raw_writel(0x00007F7F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_MASKS);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_0);
  	__raw_writel(0x00FF00FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_2);
  	__raw_writel(0x000000FF, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT0_7);
  
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_0);
  	__raw_writel(0xFF3FFF3F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_1);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_2);
  	__raw_writel(0xFFFFFF1F, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_3);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_4);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_5);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_6);
  	__raw_writel(0, pxp->base + HW_PXP_WFE_B_STG3_F8X1_OUT1_7);
  
  	__raw_writel(
  		BF_PXP_WFE_B_CTRL_ENABLE(1) |
  		BF_PXP_WFE_B_CTRL_SW_RESET(1),
  		pxp->base + HW_PXP_WFE_B_CTRL);
  }
  
  /* wfe b processing
   * use wfe b to process an update
   * call this function only after pxp_wfe_a_processing
   * x,y,width,height:
   *         coordinate and size of the update region
   * twb:
   *         temp working buffer, 16bpp
   *         only used when reagl_en is 1
   * wb:
   *         working buffer, 16bpp
   * lut:
   *         lut buffer, 8bpp
   * lut_update:
   *         0 - wfe_b is used for reagl/reagl-d operation
   *         1 - wfe_b is used for lut update operation
   * reagl_d_en:
   *         0 - use reagl waveform algorithm
   *         1 - use reagl/-d waveform algorithm
   */
  static void pxp_wfe_b_process(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &config_data->proc_data;
  	struct pxp_layer_param *fetch_ch0 = &config_data->wfe_b_fetch_param[0];
  	struct pxp_layer_param *fetch_ch1 = &config_data->wfe_b_fetch_param[1];
  	struct pxp_layer_param *store_ch0 = &config_data->wfe_b_store_param[0];
  	struct pxp_layer_param *store_ch1 = &config_data->wfe_b_store_param[1];
  	static int comp_mask;
  	/* Fetch */
  
  	print_param(fetch_ch0, "wfe_b fetch_ch0");
  	print_param(fetch_ch1, "wfe_b fetch_ch1");
  	print_param(store_ch0, "wfe_b store_ch0");
  	print_param(store_ch1, "wfe_b store_ch1");
  
  	__raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF1_ADDR);
  
  	__raw_writel(
  		BF_PXP_WFB_FETCH_BUF1_CORD_YCORD(fetch_ch0->top) |
  		BF_PXP_WFB_FETCH_BUF1_CORD_XCORD(fetch_ch0->left),
  		pxp->base + HW_PXP_WFB_FETCH_BUF1_CORD);
  
  	__raw_writel(fetch_ch0->stride,
  		pxp->base + HW_PXP_WFB_FETCH_BUF1_PITCH);
  
  	__raw_writel(
  		BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_HEIGHT(fetch_ch0->height-1) |
  		BF_PXP_WFB_FETCH_BUF1_SIZE_BUF_WIDTH(fetch_ch0->width-1),
  		pxp->base + HW_PXP_WFB_FETCH_BUF1_SIZE);
  
  	__raw_writel(fetch_ch1->paddr, pxp->base + HW_PXP_WFB_FETCH_BUF2_ADDR);
  
  	__raw_writel(fetch_ch1->stride * 2,
  			pxp->base + HW_PXP_WFB_FETCH_BUF2_PITCH);
  
  	__raw_writel(
  		BF_PXP_WFB_FETCH_BUF2_CORD_YCORD(fetch_ch1->top) |
  		BF_PXP_WFB_FETCH_BUF2_CORD_XCORD(fetch_ch1->left),
  		pxp->base + HW_PXP_WFB_FETCH_BUF2_CORD);
  
  	__raw_writel(
  		BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_HEIGHT(fetch_ch1->height-1) |
  		BF_PXP_WFB_FETCH_BUF2_SIZE_BUF_WIDTH(fetch_ch1->width-1),
  		pxp->base + HW_PXP_WFB_FETCH_BUF2_SIZE);
  
  	if (!proc_data->lut_update) {
  		__raw_writel(
  			BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
  			pxp->base + HW_PXP_WFB_FETCH_CTRL);
  	} else {
  		__raw_writel(
  			BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
  			pxp->base + HW_PXP_WFB_FETCH_CTRL);
  	}
  
  #ifdef	CONFIG_REAGLD_ALGO_CHECK
  	__raw_writel(
  			(__raw_readl(pxp->base + HW_PXP_WFE_B_SW_DATA_REGS) & 0x0000FFFF) | ((fetch_ch0->comp_mask&0x000000FF)<<16),
  			pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
  #else
  	__raw_writel(
  			(__raw_readl(pxp->base + HW_PXP_WFE_B_SW_DATA_REGS) & 0x0000FFFF) | ((comp_mask&0x000000FF)<<16),
  			pxp->base + HW_PXP_WFE_B_SW_DATA_REGS);
  
  	/* comp_mask only need to be updated upon REAGL-D, 0,1,...7, 0,1,...  */
  	if (proc_data->reagl_d_en) {
  		comp_mask++;
  		if (comp_mask>7)
  			comp_mask = 0;
  	}
  #endif
  
  	/* Store */
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width-1)|
  		BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height-1),
  		pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width-1)|
  		BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height-1),
  		pxp->base + HW_PXP_WFE_B_STORE_SIZE_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride * 2)|
  		BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride * 2),
  		pxp->base + HW_PXP_WFE_B_STORE_PITCH);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr
  			+ (store_ch0->left + store_ch0->top * store_ch0->stride) * 2),
  		pxp->base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
  
  	if (proc_data->lut_update) {
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x3f0000),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(0x30)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0),
  			pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(4)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
  			pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
  	} else {
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x3f00),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x0),
  			pxp->base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK0(3)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK1(0)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK2(0)|
  			BF_PXP_WFE_B_STORE_F_MASK_L_CH0_F_MASK3(0),
  			pxp->base + HW_PXP_WFE_B_STORE_F_MASK_L_CH0);
  
  		__raw_writel(
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH0(8)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG0(1)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH1(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG1(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH2(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG2(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_WIDTH3(0)|
  			BF_PXP_WFE_B_STORE_F_SHIFT_L_CH0_F_SHIFT_FLAG3(0),
  			pxp->base + HW_PXP_WFE_B_STORE_F_SHIFT_L_CH0);
  	}
  
  	/* ALU */
  	__raw_writel(
  		BF_PXP_ALU_B_BUF_SIZE_BUF_WIDTH(fetch_ch0->width) |
  		BF_PXP_ALU_B_BUF_SIZE_BUF_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_ALU_B_BUF_SIZE);
  
  	/* WFE */
  	__raw_writel(
  		BF_PXP_WFE_B_DIMENSIONS_WIDTH(fetch_ch0->width) |
  		BF_PXP_WFE_B_DIMENSIONS_HEIGHT(fetch_ch0->height),
  		pxp->base + HW_PXP_WFE_B_DIMENSIONS);
  
  	__raw_writel(	/*TODO check*/
  		BF_PXP_WFE_B_OFFSET_X_OFFSET(fetch_ch0->left) |
  		BF_PXP_WFE_B_OFFSET_Y_OFFSET(fetch_ch0->top),
  		pxp->base + HW_PXP_WFE_B_OFFSET);
  
  	__raw_writel(proc_data->reagl_d_en, pxp->base + HW_PXP_WFE_B_SW_FLAG_REGS);
  }
  
  void pxp_fill(
          u32 bpp,
          u32 value,
          u32 width,
          u32 height,
          u32 output_buffer,
          u32 output_pitch)
  {
  	u32 active_bpp;
  	u32 pitch;
  
  	if (bpp == 8) {
  		active_bpp = 0;
  		pitch = output_pitch;
  	} else if(bpp == 16) {
  		active_bpp = 1;
  		pitch = output_pitch * 2;
  	} else {
  		active_bpp = 2;
  		pitch = output_pitch * 4;
  	}
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_CTRL_CH0_CH_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_BLOCK_16(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_PACK_IN_SEL(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_FILL_DATA_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
  		BF_PXP_WFE_B_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
  		BF_PXP_WFE_B_STORE_CTRL_CH0_ARBIT_EN(0),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_CTRL_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_CTRL_CH1_CH_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_BLOCK_16(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_PACK_IN_SEL(0)|
  		BF_PXP_WFE_B_STORE_CTRL_CH1_WR_NUM_BYTES(16),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_CTRL_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_WIDTH(width-1)|
  		BF_PXP_WFE_B_STORE_SIZE_CH0_OUT_HEIGHT(height-1),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_SIZE_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_WIDTH(width-1)|
  		BF_PXP_WFE_B_STORE_SIZE_CH1_OUT_HEIGHT(height-1),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_SIZE_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_PITCH_CH0_OUT_PITCH(pitch)|
  		BF_PXP_WFE_B_STORE_PITCH_CH1_OUT_PITCH(pitch),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_PITCH);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(active_bpp)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(active_bpp)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
  		BF_PXP_WFE_B_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_SHIFT_CTRL_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(output_buffer),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_0_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_1_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(output_buffer),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_0_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_ADDR_1_CH1);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_FILL_DATA_CH0_FILL_DATA_CH0(value),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_FILL_DATA_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0x00000000),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK0_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0x000000ff),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK0_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x00000000),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK1_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0x000000ff),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK1_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK2_H_CH0_D_MASK2_H_CH0(0x00000000),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK2_H_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_MASK2_L_CH0_D_MASK2_L_CH0(0x000000ff),
  		pxp_reg_base + HW_PXP_WFE_B_STORE_D_MASK2_L_CH0);
  
  	__raw_writel(
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(32)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(40)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(1)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
  		BF_PXP_WFE_B_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
  		pxp_reg_base +  HW_PXP_WFE_B_STORE_D_SHIFT_L_CH0);
  
  	__raw_writel(
  		BF_PXP_CTRL2_ENABLE                   (1) |
  		BF_PXP_CTRL2_ROTATE0                  (0) |
  		BF_PXP_CTRL2_HFLIP0                   (0) |
  		BF_PXP_CTRL2_VFLIP0                   (0) |
  		BF_PXP_CTRL2_ROTATE1                  (0) |
  		BF_PXP_CTRL2_HFLIP1                   (0) |
  		BF_PXP_CTRL2_VFLIP1                   (0) |
  		BF_PXP_CTRL2_ENABLE_DITHER            (0) |
  		BF_PXP_CTRL2_ENABLE_WFE_A             (0) |
  		BF_PXP_CTRL2_ENABLE_WFE_B             (1) |
  		BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE (0) |
  		BF_PXP_CTRL2_ENABLE_ALPHA_B           (0) |
  		BF_PXP_CTRL2_BLOCK_SIZE               (0) |
  		BF_PXP_CTRL2_ENABLE_CSC2              (0) |
  		BF_PXP_CTRL2_ENABLE_LUT               (0) |
  		BF_PXP_CTRL2_ENABLE_ROTATE0           (0) |
  		BF_PXP_CTRL2_ENABLE_ROTATE1           (0),
  		pxp_reg_base + HW_PXP_CTRL2);
  
  	if (busy_wait(BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ &
  			__raw_readl(pxp_reg_base + HW_PXP_IRQ)) == false)
  		printk("%s: wait for completion timeout\n", __func__);
  }
  EXPORT_SYMBOL(pxp_fill);
  
  #ifdef CONFIG_MXC_FPGA_M4_TEST
  void m4_process(void)
  {
  	__raw_writel(0x7, pinctrl_base + PIN_DOUT);	/* M4 Start */
  
  	while (!(__raw_readl(pxp_reg_base + HW_PXP_HANDSHAKE_CPU_STORE) & BM_PXP_HANDSHAKE_CPU_STORE_SW0_B0_READY));
  
  	__raw_writel(0x3, pinctrl_base + PIN_DOUT);	/* M4 Stop */
  
  
  }
  #else
  void m4_process(void) {}
  #endif
  EXPORT_SYMBOL(m4_process);
  
  static void pxp_lut_status_set(struct pxps *pxp, unsigned int lut)
  {
  	if(lut<32)
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0) | (1 << lut),
  				pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_0);
  	else {
  		lut = lut -32;
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1) | (1 << lut),
  				pxp->base + HW_PXP_WFE_A_STG1_8X1_OUT0_1);
  	}
  }
  
  static void pxp_lut_status_set_v3p(struct pxps *pxp, unsigned int lut)
  {
  	if(lut<32)
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_0) | (1 << lut),
  				pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_0);
  	else {
  		lut = lut -32;
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_B_STG1_8X1_OUT0_1) | (1 << lut),
  				pxp->base + HW_PXP_WFE_B_STG1_8X1_OUT0_1);
  	}
  }
  
  static void pxp_luts_activate(struct pxps *pxp, u64 lut_status)
  {
  	int i = 0;
  
  	if (!lut_status)
  		return;
  
  	for (i = 0; i < 64; i++) {
  		if (lut_status & (1ULL << i))
  			if (pxp->devdata && pxp->devdata->pxp_lut_status_set)
  				pxp->devdata->pxp_lut_status_set(pxp, i);
  	}
  }
  
  static void pxp_lut_status_clr(unsigned int lut)
  {
  	if(lut<32)
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0) & (~(1 << lut)),
  				pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_0);
  	else
  	{
  		lut = lut -32;
  		__raw_writel(
  				__raw_readl(pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1) & (~(1 << lut)),
  				pxp_reg_base + HW_PXP_WFE_A_STG1_8X1_OUT0_1);
  	}
  }
  
  /* this function should be called in the epdc
   * driver explicitly when some epdc lut becomes
   * idle. So it should be exported.
   */
  void pxp_luts_deactivate(u64 lut_status)
  {
  	int i = 0;
  
  	if (!lut_status)
  		return;
  
  	for (i = 0; i < 64; i++) {
  		if (lut_status & (1ULL << i))
  			pxp_lut_status_clr(i);
  	}
  }
  
  /* use histogram_B engine to calculate histogram status */
  static void pxp_histogram_enable(struct pxps *pxp,
  				 unsigned int width,
  				 unsigned int height)
  {
  	u32 val = 0;
  
  	__raw_writel(
  			BF_PXP_HIST_B_BUF_SIZE_HEIGHT(height)|
  			BF_PXP_HIST_B_BUF_SIZE_WIDTH(width),
  			pxp->base + HW_PXP_HIST_B_BUF_SIZE);
  
  	if (pxp_is_v3(pxp))
  		val = 64;
  	else if (pxp_is_v3p(pxp))
  		val = 64 + 4;
  
  	__raw_writel(
  			BF_PXP_HIST_B_MASK_MASK_EN(1)|
  			BF_PXP_HIST_B_MASK_MASK_MODE(0)|
  			BF_PXP_HIST_B_MASK_MASK_OFFSET(val)|
  			BF_PXP_HIST_B_MASK_MASK_WIDTH(0)|
  			BF_PXP_HIST_B_MASK_MASK_VALUE0(1) |
  			BF_PXP_HIST_B_MASK_MASK_VALUE1(0),
  			pxp->base + HW_PXP_HIST_B_MASK);
  
  	__raw_writel(
  			BF_PXP_HIST_B_CTRL_PIXEL_WIDTH(3)|
  			BF_PXP_HIST_B_CTRL_PIXEL_OFFSET(8)|
  			BF_PXP_HIST_B_CTRL_CLEAR(0)|
  			BF_PXP_HIST_B_CTRL_ENABLE(1),
  			pxp->base + HW_PXP_HIST_B_CTRL);
  }
  
  static void pxp_histogram_status_report(struct pxps *pxp, u32 *hist_status)
  {
  	BUG_ON(!hist_status);
  
  	*hist_status = (__raw_readl(pxp->base + HW_PXP_HIST_B_CTRL) & BM_PXP_HIST_B_CTRL_STATUS)
  			>> BP_PXP_HIST_B_CTRL_STATUS;
  	dev_dbg(pxp->dev, "%d pixels are used to calculate histogram status %d\n",
  			__raw_readl(pxp->base + HW_PXP_HIST_B_TOTAL_PIXEL), *hist_status);
  }
  
  static void pxp_histogram_disable(struct pxps *pxp)
  {
  	__raw_writel(
  			BF_PXP_HIST_B_CTRL_PIXEL_WIDTH(3)|
  			BF_PXP_HIST_B_CTRL_PIXEL_OFFSET(4)|
  			BF_PXP_HIST_B_CTRL_CLEAR(1)|
  			BF_PXP_HIST_B_CTRL_ENABLE(0),
  			pxp->base + HW_PXP_HIST_B_CTRL);
  }
  
  /* the collision detection function will be
   * called by epdc driver when required
   */
  static void pxp_collision_detection_enable(struct pxps *pxp,
  					   unsigned int width,
  					   unsigned int height)
  {
  	u32 val = 0;
  
  	__raw_writel(
  			BF_PXP_HIST_A_BUF_SIZE_HEIGHT(height)|
  			BF_PXP_HIST_A_BUF_SIZE_WIDTH(width),
  			pxp_reg_base + HW_PXP_HIST_A_BUF_SIZE);
  
  	if (pxp_is_v3(pxp))
  		val = 65;
  	else if (pxp_is_v3p(pxp))
  		val = 65 + 4;
  
  	__raw_writel(
  			BF_PXP_HIST_A_MASK_MASK_EN(1)|
  			BF_PXP_HIST_A_MASK_MASK_MODE(0)|
  			BF_PXP_HIST_A_MASK_MASK_OFFSET(val)|
  			BF_PXP_HIST_A_MASK_MASK_WIDTH(0)|
  			BF_PXP_HIST_A_MASK_MASK_VALUE0(1) |
  			BF_PXP_HIST_A_MASK_MASK_VALUE1(0),
  			pxp_reg_base + HW_PXP_HIST_A_MASK);
  
  	__raw_writel(
  			BF_PXP_HIST_A_CTRL_PIXEL_WIDTH(6)|
  			BF_PXP_HIST_A_CTRL_PIXEL_OFFSET(24)|
  			BF_PXP_HIST_A_CTRL_CLEAR(0)|
  			BF_PXP_HIST_A_CTRL_ENABLE(1),
  			pxp_reg_base + HW_PXP_HIST_A_CTRL);
  }
  
  static void pxp_collision_detection_disable(struct pxps *pxp)
  {
  	__raw_writel(
  			BF_PXP_HIST_A_CTRL_PIXEL_WIDTH(6)|
  			BF_PXP_HIST_A_CTRL_PIXEL_OFFSET(24)|
  			BF_PXP_HIST_A_CTRL_CLEAR(1)|
  			BF_PXP_HIST_A_CTRL_ENABLE(0),
  			pxp_reg_base + HW_PXP_HIST_A_CTRL);
  }
  
  /* this function can be called in the epdc callback
   * function in the pxp_irq() to let the epdc know
   * the collision information for the previous working
   * buffer update.
   */
  static bool pxp_collision_status_report(struct pxps *pxp, struct pxp_collision_info *info)
  {
  	unsigned int count;
  
  	BUG_ON(!info);
  	memset(info, 0x0, sizeof(*info));
  
  	info->pixel_cnt = count = __raw_readl(pxp->base + HW_PXP_HIST_A_TOTAL_PIXEL);
  	if (!count)
  		return false;
  
  	dev_dbg(pxp->dev, "%s: pixel_cnt = %d\n", __func__, info->pixel_cnt);
  	info->rect_min_x = __raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_X) & 0xffff;
  	dev_dbg(pxp->dev, "%s: rect_min_x = %d\n", __func__, info->rect_min_x);
  	info->rect_max_x = (__raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_X) >> 16) & 0xffff;
  	dev_dbg(pxp->dev, "%s: rect_max_x = %d\n", __func__, info->rect_max_x);
  	info->rect_min_y = __raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_Y) & 0xffff;
  	dev_dbg(pxp->dev, "%s: rect_min_y = %d\n", __func__, info->rect_min_y);
  	info->rect_max_y = (__raw_readl(pxp->base + HW_PXP_HIST_A_ACTIVE_AREA_Y) >> 16) & 0xffff;
  	dev_dbg(pxp->dev, "%s: rect_max_y = %d\n", __func__, info->rect_max_y);
  
  	info->victim_luts[0] = __raw_readl(pxp->base + HW_PXP_HIST_A_RAW_STAT0);
  	dev_dbg(pxp->dev, "%s: victim_luts[0] = 0x%x\n", __func__, info->victim_luts[0]);
  	info->victim_luts[1] = __raw_readl(pxp->base + HW_PXP_HIST_A_RAW_STAT1);
  	dev_dbg(pxp->dev, "%s: victim_luts[1] = 0x%x\n", __func__, info->victim_luts[1]);
  
  	return true;
  }
  
  void pxp_get_collision_info(struct pxp_collision_info *info)
  {
  	BUG_ON(!info);
  
  	memcpy(info, &col_info, sizeof(struct pxp_collision_info));
  }
  EXPORT_SYMBOL(pxp_get_collision_info);
  
  static void dither_prefetch_config(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_layer_param *fetch_ch0 = &config_data->dither_fetch_param[0];
  	struct pxp_layer_param *fetch_ch1 = &config_data->dither_fetch_param[1];
  
  	print_param(fetch_ch0, "dither fetch_ch0");
  	print_param(fetch_ch1, "dither fetch_ch1");
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_CTRL_CH0_CH_EN(1) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16(0)|
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_VFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES(32) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN(0),
  			pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_CTRL_CH1_CH_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_BLOCK_16(0)|
  			BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_BYPASS_PIXEL_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_HFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_VFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_ROTATION_ANGLE(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_RD_NUM_BYTES(2) |
  			BF_PXP_DITHER_FETCH_CTRL_CH1_HANDSHAKE_SCAN_LINE_NUM(0),
  			pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_X(0) |
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0_ACTIVE_SIZE_ULC_Y(0),
  			pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH0);
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_X(fetch_ch0->width - 1) |
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0_ACTIVE_SIZE_LRC_Y(fetch_ch0->height - 1),
  			pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_X(0) |
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1_ACTIVE_SIZE_ULC_Y(0),
  			pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_ULC_CH1);
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_X(fetch_ch1->width - 1) |
  			BF_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1_ACTIVE_SIZE_LRC_Y(fetch_ch1->height - 1),
  			pxp->base + HW_PXP_DITHER_FETCH_ACTIVE_SIZE_LRC_CH1);
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_WIDTH(fetch_ch0->width - 1) |
  			BF_PXP_DITHER_FETCH_SIZE_CH0_INPUT_TOTAL_HEIGHT(fetch_ch0->height - 1),
  			pxp->base + HW_PXP_DITHER_FETCH_SIZE_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_WIDTH(fetch_ch1->width - 1) |
  			BF_PXP_DITHER_FETCH_SIZE_CH1_INPUT_TOTAL_HEIGHT(fetch_ch1->height - 1),
  			pxp->base + HW_PXP_DITHER_FETCH_SIZE_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_PITCH_CH0_INPUT_PITCH(fetch_ch0->stride) |
  			BF_PXP_DITHER_FETCH_PITCH_CH1_INPUT_PITCH(fetch_ch1->stride),
  			pxp->base + HW_PXP_DITHER_FETCH_PITCH);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_INPUT_ACTIVE_BPP(0) |
  			BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_FORMAT(0) |
  			BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_EXPAND_EN(0) |
  			BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH0);
  
  	__raw_writel(
                          BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_INPUT_ACTIVE_BPP(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_FORMAT(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_EXPAND_EN(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_CTRL_CH1_SHIFT_BYPASS(1),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_CTRL_CH1);
  
  	__raw_writel(
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET0(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET1(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET2(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0_OFFSET3(0),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH0);
  
  	__raw_writel(
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET0(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET1(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET2(0) |
                          BF_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1_OFFSET3(0),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_OFFSET_CH1);
  
  	__raw_writel(
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH0(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH1(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH2(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0_WIDTH3(7),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH0);
  
  	__raw_writel(
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH0(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH1(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH2(7) |
                          BF_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1_WIDTH3(7),
  			pxp->base + HW_PXP_DITHER_FETCH_SHIFT_WIDTH_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ADDR_0_CH0_INPUT_BASE_ADDR0(fetch_ch0->paddr),
  			pxp->base + HW_PXP_DITHER_FETCH_ADDR_0_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ADDR_1_CH0_INPUT_BASE_ADDR1(0),
  			pxp->base + HW_PXP_DITHER_FETCH_ADDR_1_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ADDR_0_CH1_INPUT_BASE_ADDR0(fetch_ch1->paddr),
  			pxp->base + HW_PXP_DITHER_FETCH_ADDR_0_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_FETCH_ADDR_1_CH1_INPUT_BASE_ADDR1(0),
  			pxp->base + HW_PXP_DITHER_FETCH_ADDR_1_CH1);
  }
  
  static void dither_store_config(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_layer_param *store_ch0 = &config_data->dither_store_param[0];
  	struct pxp_layer_param *store_ch1 = &config_data->dither_store_param[1];
  
  	print_param(store_ch0, "dither store_ch0");
  	print_param(store_ch1, "dither store_ch1");
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
  			pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_CTRL_CH1_CH_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_BLOCK_16(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_PACK_IN_SEL(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH1_WR_NUM_BYTES(32),
  			pxp->base + HW_PXP_DITHER_STORE_CTRL_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH(store_ch0->width - 1) |
  			BF_PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT(store_ch0->height - 1),
  			pxp->base + HW_PXP_DITHER_STORE_SIZE_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_SIZE_CH1_OUT_WIDTH(store_ch1->width - 1) |
  			BF_PXP_DITHER_STORE_SIZE_CH1_OUT_HEIGHT(store_ch1->height - 1),
  			pxp->base + HW_PXP_DITHER_STORE_SIZE_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_PITCH_CH0_OUT_PITCH(store_ch0->stride) |
  			BF_PXP_DITHER_STORE_PITCH_CH1_OUT_PITCH(store_ch1->stride),
  			pxp->base + HW_PXP_DITHER_STORE_PITCH);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUTPUT_ACTIVE_BPP(0)|
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_1P_EN(0)|
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_OUT_YUV422_2P_EN(0)|
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH0_SHIFT_BYPASS(1),
  			pxp->base + HW_PXP_DITHER_STORE_SHIFT_CTRL_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUTPUT_ACTIVE_BPP(0)|
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_1P_EN(0)|
  			BF_PXP_DITHER_STORE_SHIFT_CTRL_CH1_OUT_YUV422_2P_EN(0),
  			pxp->base + HW_PXP_DITHER_STORE_SHIFT_CTRL_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_ADDR_0_CH0_OUT_BASE_ADDR0(store_ch0->paddr),
  			pxp->base + HW_PXP_DITHER_STORE_ADDR_0_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_ADDR_1_CH0_OUT_BASE_ADDR1(0),
  			pxp->base + HW_PXP_DITHER_STORE_ADDR_1_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_ADDR_0_CH1_OUT_BASE_ADDR0(store_ch1->paddr),
  			pxp->base + HW_PXP_DITHER_STORE_ADDR_0_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_ADDR_1_CH1_OUT_BASE_ADDR1(0),
  			pxp->base + HW_PXP_DITHER_STORE_ADDR_1_CH1);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_FILL_DATA_CH0_FILL_DATA_CH0(0),
  			pxp->base + HW_PXP_DITHER_STORE_FILL_DATA_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_D_MASK0_H_CH0_D_MASK0_H_CH0(0xffffff),
  			pxp->base + HW_PXP_DITHER_STORE_D_MASK0_H_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_D_MASK0_L_CH0_D_MASK0_L_CH0(0x0),
  			pxp->base + HW_PXP_DITHER_STORE_D_MASK0_L_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_D_MASK1_H_CH0_D_MASK1_H_CH0(0x0),
  			pxp->base + HW_PXP_DITHER_STORE_D_MASK1_H_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_D_MASK1_L_CH0_D_MASK1_L_CH0(0xff),
  			pxp->base + HW_PXP_DITHER_STORE_D_MASK1_L_CH0);
  
  	__raw_writel(
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH0(32) |
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG0(0) |
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH1(32)|
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG1(1) |
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH2(0)|
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG2(0)|
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_WIDTH3(0)|
  			BF_PXP_DITHER_STORE_D_SHIFT_L_CH0_D_SHIFT_FLAG3(0),
  			pxp->base + HW_PXP_DITHER_STORE_D_SHIFT_L_CH0);
  }
  
  static void pxp_set_final_lut_data(struct pxps *pxp)
  {
  	__raw_writel(
  			BF_PXP_DITHER_FINAL_LUT_DATA0_DATA0(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA0_DATA1(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA0_DATA2(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA0_DATA3(0x0),
  			pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA0);
  
  	__raw_writel(
  			BF_PXP_DITHER_FINAL_LUT_DATA1_DATA4(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA1_DATA5(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA1_DATA6(0x0) |
  			BF_PXP_DITHER_FINAL_LUT_DATA1_DATA7(0x0),
  			pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA1);
  
  	__raw_writel(
  			BF_PXP_DITHER_FINAL_LUT_DATA2_DATA8(0xff) |
  			BF_PXP_DITHER_FINAL_LUT_DATA2_DATA9(0xff) |
  			BF_PXP_DITHER_FINAL_LUT_DATA2_DATA10(0xff)|
  			BF_PXP_DITHER_FINAL_LUT_DATA2_DATA11(0xff),
  			pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA2);
  
  	__raw_writel(
  			BF_PXP_DITHER_FINAL_LUT_DATA3_DATA12(0xff) |
  			BF_PXP_DITHER_FINAL_LUT_DATA3_DATA13(0xff) |
  			BF_PXP_DITHER_FINAL_LUT_DATA3_DATA14(0xff) |
  			BF_PXP_DITHER_FINAL_LUT_DATA3_DATA15(0xff),
  			pxp->base + HW_PXP_DITHER_FINAL_LUT_DATA3);
  }
  
  static void pxp_dithering_process(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  	u32 val = 0;
  
  	if (pxp->devdata && pxp->devdata->pxp_dithering_configure)
  		pxp->devdata->pxp_dithering_configure(pxp);
  	pxp_sram_init(pxp, DITHER0_LUT, (u32)dither_data_8x8, 64);
  
  	__raw_writel(
  			BF_PXP_INIT_MEM_CTRL_ADDR(0) |
  			BF_PXP_INIT_MEM_CTRL_SELECT(0) |/*select the lut memory for access */
  			BF_PXP_INIT_MEM_CTRL_START(1),
  			pxp->base + HW_PXP_INIT_MEM_CTRL);
  
  
  	{
  		int i;
  		for (i = 0; i < 64; i++)
  			__raw_writel(
  					BF_PXP_INIT_MEM_DATA_DATA(dither_data_8x8[i]),
  					pxp->base + HW_PXP_INIT_MEM_DATA);
  	}
  
  	__raw_writel(
  			BF_PXP_INIT_MEM_CTRL_ADDR(0) |
  			BF_PXP_INIT_MEM_CTRL_SELECT(0) |/*select the lut memory for access*/
  			BF_PXP_INIT_MEM_CTRL_START(0),
  			pxp->base + HW_PXP_INIT_MEM_CTRL);
  
  	if (pxp_is_v3(pxp))
  		val = BF_PXP_DITHER_CTRL_ENABLE0            (1) |
  		      BF_PXP_DITHER_CTRL_ENABLE1            (0) |
  		      BF_PXP_DITHER_CTRL_ENABLE2            (0) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE2       (0) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE1       (0) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE0(proc_data->dither_mode) |
  		      BF_PXP_DITHER_CTRL_LUT_MODE           (0) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE   (1) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE   (0) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE   (0) |
  		      BF_PXP_DITHER_CTRL_BUSY2              (0) |
  		      BF_PXP_DITHER_CTRL_BUSY1              (0) |
  		      BF_PXP_DITHER_CTRL_BUSY0              (0);
  	else if (pxp_is_v3p(pxp))
  		val = BF_PXP_DITHER_CTRL_ENABLE0            (1) |
  		      BF_PXP_DITHER_CTRL_ENABLE1            (1) |
  		      BF_PXP_DITHER_CTRL_ENABLE2            (1) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE2       (3) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE1       (3) |
  		      BF_PXP_DITHER_CTRL_DITHER_MODE0(proc_data->dither_mode) |
  		      BF_PXP_DITHER_CTRL_LUT_MODE           (0) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX0_SIZE   (1) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX1_SIZE   (1) |
  		      BF_PXP_DITHER_CTRL_IDX_MATRIX2_SIZE   (1) |
  		      BF_PXP_DITHER_CTRL_BUSY2              (0) |
  		      BF_PXP_DITHER_CTRL_BUSY1              (0) |
  		      BF_PXP_DITHER_CTRL_BUSY0              (0);
  	__raw_writel(val, pxp->base + HW_PXP_DITHER_CTRL);
  
  	switch(proc_data->dither_mode) {
  		case PXP_DITHER_PASS_THROUGH:
  			/* no more settings required */
  			break;
  		case PXP_DITHER_FLOYD:
  		case PXP_DITHER_ATKINSON:
  		case PXP_DITHER_ORDERED:
  			if(!proc_data->quant_bit || proc_data->quant_bit > 7) {
  				dev_err(pxp->dev, "unsupported quantization bit number!\n");
  				return;
  			}
  			__raw_writel(
  					BF_PXP_DITHER_CTRL_FINAL_LUT_ENABLE(1) |
  					BF_PXP_DITHER_CTRL_NUM_QUANT_BIT(proc_data->quant_bit),
  					pxp->base + HW_PXP_DITHER_CTRL_SET);
  			pxp_set_final_lut_data(pxp);
  
  			break;
  		case PXP_DITHER_QUANT_ONLY:
  			if(!proc_data->quant_bit || proc_data->quant_bit > 7) {
  				dev_err(pxp->dev, "unsupported quantization bit number!\n");
  				return;
  			}
  			__raw_writel(
  					BF_PXP_DITHER_CTRL_NUM_QUANT_BIT(proc_data->quant_bit),
  					pxp->base + HW_PXP_DITHER_CTRL_SET);
  			break;
  		default:
  			/* unknown mode */
  			dev_err(pxp->dev, "unknown dithering mode passed!\n");
  			__raw_writel(0x0, pxp->base + HW_PXP_DITHER_CTRL);
  			return;
  	}
  }
  
  static void pxp_dithering_configure(struct pxps *pxp)
  {
  	dither_prefetch_config(pxp);
  	dither_store_config(pxp);
  }
  
  static void pxp_dithering_configure_v3p(struct pxps *pxp)
  {
  	struct pxp_config_data *config_data = &pxp->pxp_conf_state;
  	struct pxp_layer_param *fetch_ch0 = &config_data->dither_fetch_param[0];
  	struct pxp_layer_param *store_ch0 = &config_data->dither_store_param[0];
  
  	__raw_writel(BF_PXP_CTRL_BLOCK_SIZE(BV_PXP_CTRL_BLOCK_SIZE__8X8) |
  			BF_PXP_CTRL_ROTATE0(BV_PXP_CTRL_ROTATE0__ROT_0) |
  			BM_PXP_CTRL_IRQ_ENABLE,
  			pxp->base + HW_PXP_CTRL);
  
  	__raw_writel(BF_PXP_PS_CTRL_DECX(BV_PXP_PS_CTRL_DECX__DISABLE) |
  			BF_PXP_PS_CTRL_DECY(BV_PXP_PS_CTRL_DECY__DISABLE) |
  			BF_PXP_PS_CTRL_FORMAT(BV_PXP_PS_CTRL_FORMAT__Y8),
  			pxp->base + HW_PXP_PS_CTRL);
  
  	__raw_writel(BF_PXP_OUT_CTRL_FORMAT(BV_PXP_OUT_CTRL_FORMAT__Y8),
  			pxp->base + HW_PXP_OUT_CTRL);
  
  	__raw_writel(BF_PXP_PS_SCALE_YSCALE(4096) |
  			BF_PXP_PS_SCALE_XSCALE(4096),
  			pxp->base + HW_PXP_PS_SCALE);
  
  	__raw_writel(store_ch0->paddr, pxp->base + HW_PXP_OUT_BUF);
  
  	__raw_writel(store_ch0->stride, pxp->base + HW_PXP_OUT_PITCH);
  
  	__raw_writel(BF_PXP_OUT_LRC_X(store_ch0->width - 1) |
  			BF_PXP_OUT_LRC_Y(store_ch0->height - 1),
  			pxp->base + HW_PXP_OUT_LRC);
  
  	__raw_writel(BF_PXP_OUT_PS_ULC_X(0) |
  			BF_PXP_OUT_PS_ULC_Y(0),
  			pxp->base + HW_PXP_OUT_PS_ULC);
  
  	__raw_writel(BF_PXP_OUT_PS_LRC_X(fetch_ch0->width - 1) |
  			BF_PXP_OUT_PS_LRC_Y(fetch_ch0->height - 1),
  			pxp->base + HW_PXP_OUT_PS_LRC);
  
  	__raw_writel(fetch_ch0->paddr, pxp->base + HW_PXP_PS_BUF);
  
  	__raw_writel(fetch_ch0->stride, pxp->base + HW_PXP_PS_PITCH);
  
  	__raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  }
  
  static void pxp_start2(struct pxps *pxp)
  {
  	struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  	struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  	int dither_wfe_a_handshake = 0;
  	int wfe_a_b_handshake = 0;
  	int count = 0;
  
  	int wfe_a_enable = ((proc_data->engine_enable & PXP_ENABLE_WFE_A) == PXP_ENABLE_WFE_A);
  	int wfe_b_enable = ((proc_data->engine_enable & PXP_ENABLE_WFE_B) == PXP_ENABLE_WFE_B);
  	int dither_enable = ((proc_data->engine_enable & PXP_ENABLE_DITHER) == PXP_ENABLE_DITHER);
  	int handshake = ((proc_data->engine_enable & PXP_ENABLE_HANDSHAKE) == PXP_ENABLE_HANDSHAKE);
  	int dither_bypass = ((proc_data->engine_enable & PXP_ENABLE_DITHER_BYPASS) == PXP_ENABLE_DITHER_BYPASS);
  	u32 val = 0;
  
  	if (dither_enable)
  		count++;
  	if (wfe_a_enable)
  		count++;
  	if (wfe_b_enable)
  		count++;
  
  	if (count == 0)
  		return;
  	if (handshake && (count == 1)) {
  		dev_warn(pxp->dev, "Warning: Can not use handshake mode when "
  				"only one sub-block is enabled!\n");
  		handshake = 0;
  	}
  
  	if (handshake && wfe_b_enable && (wfe_a_enable == 0)) {
  		dev_err(pxp->dev, "WFE_B only works when WFE_A is enabled!\n");
  		return;
  	}
  
  	if (handshake && dither_enable && wfe_a_enable)
  		dither_wfe_a_handshake = 1;
  	if (handshake && wfe_a_enable && wfe_b_enable)
  		wfe_a_b_handshake = 1;
  
  	dev_dbg(pxp->dev, "handshake %d, dither_wfe_a_handshake %d, "
  				"wfe_a_b_handshake %d, dither_bypass %d\n",
  				handshake,
  				dither_wfe_a_handshake,
  				wfe_a_b_handshake,
  				dither_bypass);
  
  	if (handshake) {
  		/* for handshake, we only enable the last completion INT */
  		if (wfe_b_enable)
  			__raw_writel(0x8000, pxp->base + HW_PXP_IRQ_MASK);
  		else if (wfe_a_enable)
  			__raw_writel(0x4000, pxp->base + HW_PXP_IRQ_MASK);
  
  		/* Dither fetch */
  		__raw_writel(
  			BF_PXP_DITHER_FETCH_CTRL_CH0_CH_EN(1) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BLOCK_16(0)|
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_BYPASS_PIXEL_EN(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HIGH_BYTE(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_VFLIP(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_ROTATION_ANGLE(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_RD_NUM_BYTES(32) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_HANDSHAKE_SCAN_LINE_NUM(0) |
  			BF_PXP_DITHER_FETCH_CTRL_CH0_ARBIT_EN(0),
  			pxp->base + HW_PXP_DITHER_FETCH_CTRL_CH0);
  
  		if (dither_bypass) {
  			/* Dither store */
  			__raw_writel(
  			BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
  			pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
  
  			/* WFE_A fetch */
  			__raw_writel(
  			BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(2) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
  			pxp->base + HW_PXP_WFA_FETCH_CTRL);
  
  		} else if (dither_wfe_a_handshake) {
  			/* Dither store */
  			__raw_writel(
  			BF_PXP_DITHER_STORE_CTRL_CH0_CH_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_BLOCK_16(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_HANDSHAKE_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARRAY_LINE_NUM(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_BYPASS_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_STORE_MEMORY_EN(1)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_PACK_IN_SEL(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_FILL_DATA_EN(0)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_WR_NUM_BYTES(32)|
  			BF_PXP_DITHER_STORE_CTRL_CH0_COMBINE_2CHANNEL(0) |
  			BF_PXP_DITHER_STORE_CTRL_CH0_ARBIT_EN(0),
  			pxp->base + HW_PXP_DITHER_STORE_CTRL_CH0);
  
  			/* WFE_A fetch */
  			__raw_writel(
  			BF_PXP_WFA_FETCH_CTRL_BF1_EN(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_HSK_MODE(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BYTES_PP(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_LINE_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_SRAM_IF(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BURST_LEN(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_EN(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_HSK_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BYTES_PP(1) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_LINE_MODE(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_SRAM_IF(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BURST_LEN(0) |
  			BF_PXP_WFA_FETCH_CTRL_BF2_BYPASS_MODE(0),
  			pxp->base + HW_PXP_WFA_FETCH_CTRL);
  		}
  
  		if (wfe_a_b_handshake) {
  			/* WFE_A Store */
  			__raw_writel(
  			BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
  			pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
  
  			/* WFE_B fetch */
  			__raw_writel(
  			BF_PXP_WFB_FETCH_CTRL_BF1_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_HSK_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYTES_PP(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_SRAM_IF(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF1_BYPASS_MODE(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_EN(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_HSK_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYTES_PP(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_LINE_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_SRAM_IF(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BURST_LEN(0) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BORDER_MODE(1) |
  			BF_PXP_WFB_FETCH_CTRL_BF2_BYPASS_MODE(0),
  			pxp->base + HW_PXP_WFB_FETCH_CTRL);
  		} else {
  			/* WFE_A Store */
  			__raw_writel(
  			BF_PXP_WFE_A_STORE_CTRL_CH1_CH_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_BLOCK_16(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_HANDSHAKE_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_ARRAY_LINE_NUM(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_BYPASS_EN(0)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_STORE_MEMORY_EN(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_PACK_IN_SEL(1)|
  			BF_PXP_WFE_A_STORE_CTRL_CH1_WR_NUM_BYTES(16),
  			pxp->base + HW_PXP_WFE_A_STORE_CTRL_CH1);
  		}
  
  		if (pxp_is_v3(pxp))
  			val = BF_PXP_CTRL_ENABLE_WFE_A(wfe_a_enable) |
  				BF_PXP_CTRL_ENABLE_WFE_B(wfe_b_enable);
  		else if (pxp_is_v3p(pxp))
  			val = BF_PXP_CTRL_ENABLE_WFE_B(wfe_a_enable |
  				wfe_b_enable);
  
  		/* trigger operation */
  		__raw_writel(
  		BF_PXP_CTRL_ENABLE(1) |
  		BF_PXP_CTRL_IRQ_ENABLE(0) |
  		BF_PXP_CTRL_NEXT_IRQ_ENABLE(0) |
  		BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(0) |
  		BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(1) |
  		BF_PXP_CTRL_HANDSHAKE_ABORT_SKIP(1) |
  		BF_PXP_CTRL_ROTATE0(0) |
  		BF_PXP_CTRL_HFLIP0(0) |
  		BF_PXP_CTRL_VFLIP0(0) |
  		BF_PXP_CTRL_ROTATE1(0) |
  		BF_PXP_CTRL_HFLIP1(0) |
  		BF_PXP_CTRL_VFLIP1(0) |
  		BF_PXP_CTRL_ENABLE_PS_AS_OUT(0) |
  		BF_PXP_CTRL_ENABLE_DITHER(dither_enable) |
  		BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(0) |
  		BF_PXP_CTRL_ENABLE_ALPHA_B(0) |
  		BF_PXP_CTRL_BLOCK_SIZE(1) |
  		BF_PXP_CTRL_ENABLE_CSC2(0) |
  		BF_PXP_CTRL_ENABLE_LUT(1) |
  		BF_PXP_CTRL_ENABLE_ROTATE0(0) |
  		BF_PXP_CTRL_ENABLE_ROTATE1(0) |
  		BF_PXP_CTRL_EN_REPEAT(0) |
  		val,
  		pxp->base + HW_PXP_CTRL);
  
  		return;
  	}
  
  	if (pxp_is_v3(pxp))
  		val = BF_PXP_CTRL_ENABLE_WFE_A(wfe_a_enable) |
  		      BF_PXP_CTRL_ENABLE_WFE_B(wfe_b_enable) |
  		      BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(0) |
  		      BF_PXP_CTRL_ENABLE_ALPHA_B(0);
  	else if (pxp_is_v3p(pxp))
  		val = BF_PXP_CTRL_ENABLE_WFE_B(wfe_a_enable |
  			wfe_b_enable);
  
  	__raw_writel(
  			BF_PXP_CTRL_ENABLE(1) |
  			BF_PXP_CTRL_IRQ_ENABLE(0) |
  			BF_PXP_CTRL_NEXT_IRQ_ENABLE(0) |
  			BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(0) |
  			BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(0) |
  			BF_PXP_CTRL_ROTATE0(0) |
  			BF_PXP_CTRL_HFLIP0(0) |
  			BF_PXP_CTRL_VFLIP0(0) |
  			BF_PXP_CTRL_ROTATE1(0) |
  			BF_PXP_CTRL_HFLIP1(0) |
  			BF_PXP_CTRL_VFLIP1(0) |
  			BF_PXP_CTRL_ENABLE_PS_AS_OUT(0) |
  			BF_PXP_CTRL_ENABLE_DITHER(dither_enable) |
  			BF_PXP_CTRL_BLOCK_SIZE(0) |
  			BF_PXP_CTRL_ENABLE_CSC2(0) |
  			BF_PXP_CTRL_ENABLE_LUT(0) |
  			BF_PXP_CTRL_ENABLE_ROTATE0(0) |
  			BF_PXP_CTRL_ENABLE_ROTATE1(0) |
  			BF_PXP_CTRL_EN_REPEAT(0) |
  			val,
  			pxp->base + HW_PXP_CTRL);
  
  	if (pxp_is_v3(pxp))
  		val = BF_PXP_CTRL2_ENABLE_WFE_A             (0) |
  		      BF_PXP_CTRL2_ENABLE_WFE_B             (0) |
  		      BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE (0) |
  		      BF_PXP_CTRL2_ENABLE_ALPHA_B           (0);
  	else if (pxp_is_v3p(pxp))
  		val = BF_PXP_CTRL2_ENABLE_WFE_B(0);
  
  	__raw_writel(
  			BF_PXP_CTRL2_ENABLE                   (0) |
  			BF_PXP_CTRL2_ROTATE0                  (0) |
  			BF_PXP_CTRL2_HFLIP0                   (0) |
  			BF_PXP_CTRL2_VFLIP0                   (0) |
  			BF_PXP_CTRL2_ROTATE1                  (0) |
  			BF_PXP_CTRL2_HFLIP1                   (0) |
  			BF_PXP_CTRL2_VFLIP1                   (0) |
  			BF_PXP_CTRL2_ENABLE_DITHER            (0) |
  			BF_PXP_CTRL2_BLOCK_SIZE               (0) |
  			BF_PXP_CTRL2_ENABLE_CSC2              (0) |
  			BF_PXP_CTRL2_ENABLE_LUT               (0) |
  			BF_PXP_CTRL2_ENABLE_ROTATE0           (0) |
  			BF_PXP_CTRL2_ENABLE_ROTATE1           (0),
  			pxp->base + HW_PXP_CTRL2);
  
  	dump_pxp_reg2(pxp);
  }
  
  static int pxp_dma_init(struct pxps *pxp)
  {
  	struct pxp_dma *pxp_dma = &pxp->pxp_dma;
  	struct dma_device *dma = &pxp_dma->dma;
  	int i;
  
  	dma_cap_set(DMA_SLAVE, dma->cap_mask);
  	dma_cap_set(DMA_PRIVATE, dma->cap_mask);
  
  	/* Compulsory common fields */
  	dma->dev = pxp->dev;
  	dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
  	dma->device_free_chan_resources = pxp_free_chan_resources;
  	dma->device_tx_status = pxp_tx_status;
  	dma->device_issue_pending = pxp_issue_pending;
  
  	/* Compulsory for DMA_SLAVE fields */
  	dma->device_prep_slave_sg = pxp_prep_slave_sg;
  	dma->device_terminate_all = pxp_device_terminate_all;
  
  	/* Initialize PxP Channels */
  	INIT_LIST_HEAD(&dma->channels);
  	for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
  		struct pxp_channel *pxp_chan = pxp->channel + i;
  		struct dma_chan *dma_chan = &pxp_chan->dma_chan;
  
  		spin_lock_init(&pxp_chan->lock);
  
  		/* Only one EOF IRQ for PxP, shared by all channels */
  		pxp_chan->eof_irq = pxp->irq;
  		pxp_chan->status = PXP_CHANNEL_FREE;
  		pxp_chan->completed = -ENXIO;
  		snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
  			 "PXP EOF %d", i);
  
  		dma_chan->device = &pxp_dma->dma;
  		dma_chan->cookie = 1;
  		dma_chan->chan_id = i;
  		list_add_tail(&dma_chan->device_node, &dma->channels);
  	}
  
  	return dma_async_device_register(&pxp_dma->dma);
  }
  
  static ssize_t clk_off_timeout_show(struct device *dev,
  				    struct device_attribute *attr, char *buf)
  {
  	return sprintf(buf, "%d\n", timeout_in_ms);
  }
  
  static ssize_t clk_off_timeout_store(struct device *dev,
  				     struct device_attribute *attr,
  				     const char *buf, size_t count)
  {
  	int val;
  	if (sscanf(buf, "%d", &val) > 0) {
  		timeout_in_ms = val;
  		return count;
  	}
  	return -EINVAL;
  }
  
  static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
  		   clk_off_timeout_store);
  
  static ssize_t block_size_show(struct device *dev,
  			       struct device_attribute *attr,
  			       char *buf)
  {
  	return sprintf(buf, "%d\n", block_size);
  }
  
  static ssize_t block_size_store(struct device *dev,
  				struct device_attribute *attr,
  				const char *buf, size_t count)
  {
  	char **last = NULL;
  
  	block_size = simple_strtoul(buf, last, 0);
  	if (block_size > 1)
  		block_size = 1;
  
  	return count;
  }
  static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
  		   block_size_show, block_size_store);
  
  static struct platform_device_id imx_pxpdma_devtype[] = {
  	{
  		.name = "imx7d-pxp-dma",
  		.driver_data = PXP_V3,
  	}, {
  		.name = "imx6ull-pxp-dma",
  		.driver_data = PXP_V3P,
  	}, {
  		/* sentinel */
  	}
  };
  MODULE_DEVICE_TABLE(platform, imx_pxpdma_devtype);
  
  static const struct of_device_id imx_pxpdma_dt_ids[] = {
  	{ .compatible = "fsl,imx7d-pxp-dma", .data = &imx_pxpdma_devtype[0], },
  	{ .compatible = "fsl,imx6ull-pxp-dma", .data = &imx_pxpdma_devtype[1], },
  	{ /* sentinel */ }
  };
  MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
  
  static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
  {
  	int found;
  	unsigned long flags;
  
  	spin_lock_irqsave(&pxp->lock, flags);
  	found = !list_empty(&head);
  	spin_unlock_irqrestore(&pxp->lock, flags);
  
  	return found;
  }
  
  static int pxp_dispatch_thread(void *argv)
  {
  	struct pxps *pxp = (struct pxps *)argv;
  	struct pxp_channel *pending = NULL;
  	unsigned long flags;
  
  	set_freezable();
  
  	while (!kthread_should_stop()) {
  		int ret;
  		ret = wait_event_freezable(pxp->thread_waitq,
  					has_pending_task(pxp, pending) ||
  					kthread_should_stop());
  		if (ret < 0)
  			continue;
  
  		if (kthread_should_stop())
  			break;
  
  		spin_lock_irqsave(&pxp->lock, flags);
  		pxp->pxp_ongoing = 1;
  		spin_unlock_irqrestore(&pxp->lock, flags);
  		init_completion(&pxp->complete);
  		pxpdma_dostart_work(pxp);
  		ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
  		if (ret == 0) {
  			printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
  			break;
  		}
  	}
  
  	return 0;
  }
  
  static int pxp_probe(struct platform_device *pdev)
  {
  	const struct of_device_id *of_id =
  			of_match_device(imx_pxpdma_dt_ids, &pdev->dev);
  	struct pxps *pxp;
  	struct resource *res;
  	int irq, std_irq;
  	int err = 0;
  
  	if (of_id)
  		pdev->id_entry = of_id->data;
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	irq = platform_get_irq(pdev, 0);
  	std_irq = platform_get_irq(pdev, 1);
  	if (!res || irq < 0 || std_irq < 0) {
  		err = -ENODEV;
  		goto exit;
  	}
  
  	pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
  	if (!pxp) {
  		dev_err(&pdev->dev, "failed to allocate control object\n");
  		err = -ENOMEM;
  		goto exit;
  	}
  
  	pxp->dev = &pdev->dev;
  
  	platform_set_drvdata(pdev, pxp);
  	pxp->irq = irq;
  
  	pxp->pxp_ongoing = 0;
  	pxp->lut_state = 0;
  
  	spin_lock_init(&pxp->lock);
  	mutex_init(&pxp->clk_mutex);
  
  	pxp->base = devm_ioremap_resource(&pdev->dev, res);
  	if (pxp->base == NULL) {
  		dev_err(&pdev->dev, "Couldn't ioremap regs\n");
  		err = -ENODEV;
  		goto exit;
  	}
  	pxp_reg_base = pxp->base;
  
  	pxp->pdev = pdev;
  	pxp->devdata = &pxp_devdata[pdev->id_entry->driver_data];
  
  	pxp->ipg_clk = devm_clk_get(&pdev->dev, "pxp_ipg");
  	pxp->axi_clk = devm_clk_get(&pdev->dev, "pxp_axi");
  
  	if (IS_ERR(pxp->ipg_clk) || IS_ERR(pxp->axi_clk)) {
  		dev_err(&pdev->dev, "pxp clocks invalid\n");
  		err = -EINVAL;
  		goto exit;
  	}
  
  	err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
  				"pxp-dmaengine", pxp);
  	if (err)
  		goto exit;
  
  	err = devm_request_irq(&pdev->dev, std_irq, pxp_irq, 0,
  				"pxp-dmaengine-std", pxp);
  	if (err)
  		goto exit;
  
  	/* enable all the possible irq raised by PXP */
  	__raw_writel(0xffff, pxp->base + HW_PXP_IRQ_MASK);
  
  	/* Initialize DMA engine */
  	err = pxp_dma_init(pxp);
  	if (err < 0)
  		goto exit;
  
  	if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
  		dev_err(&pdev->dev,
  			"Unable to create file from clk_off_timeout\n");
  		goto exit;
  	}
  
  	device_create_file(&pdev->dev, &dev_attr_block_size);
  	pxp_clk_enable(pxp);
  	dump_pxp_reg(pxp);
  	pxp_clk_disable(pxp);
  
  	INIT_WORK(&pxp->work, clkoff_callback);
  	init_timer(&pxp->clk_timer);
  	pxp->clk_timer.function = pxp_clkoff_timer;
  	pxp->clk_timer.data = (unsigned long)pxp;
  
  	init_waitqueue_head(&pxp->thread_waitq);
  	/* allocate a kernel thread to dispatch pxp conf */
  	pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
  	if (IS_ERR(pxp->dispatch)) {
  		err = PTR_ERR(pxp->dispatch);
  		goto exit;
  	}
  	tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
  					  0, SLAB_HWCACHE_ALIGN, NULL);
  	if (!tx_desc_cache) {
  		err = -ENOMEM;
  		goto exit;
  	}
  
  #ifdef	CONFIG_MXC_FPGA_M4_TEST
  	fpga_tcml_base = ioremap(FPGA_TCML_ADDR, SZ_32K);
  	if (fpga_tcml_base == NULL) {
  		dev_err(&pdev->dev,
  			"get fpga_tcml_base error.\n");
  		goto exit;
  	}
  	pinctrl_base = ioremap(PINCTRL, SZ_4K);
  	if (pinctrl_base == NULL) {
  		dev_err(&pdev->dev,
  			"get fpga_tcml_base error.\n");
  		goto exit;
  	}
  
  	__raw_writel(0xC0000000, pinctrl_base + 0x08);
  	__raw_writel(0x3, pinctrl_base + PIN_DOUT);
  	int i;
  	for (i = 0; i < 1024 * 32 / 4; i++) {
  		*(((unsigned int *)(fpga_tcml_base)) + i) = cm4_image[i];
  	}
  #endif
  	register_pxp_device();
  
  	pm_runtime_enable(pxp->dev);
  
  
  exit:
  	if (err)
  		dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
  	return err;
  }
  
  static int pxp_remove(struct platform_device *pdev)
  {
  	struct pxps *pxp = platform_get_drvdata(pdev);
  
  	unregister_pxp_device();
  	kmem_cache_destroy(tx_desc_cache);
  	kthread_stop(pxp->dispatch);
  	cancel_work_sync(&pxp->work);
  	del_timer_sync(&pxp->clk_timer);
  	clk_disable_unprepare(pxp->ipg_clk);
  	clk_disable_unprepare(pxp->axi_clk);
  	device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
  	device_remove_file(&pdev->dev, &dev_attr_block_size);
  	dma_async_device_unregister(&(pxp->pxp_dma.dma));
  
  	return 0;
  }
  
  #ifdef CONFIG_PM_SLEEP
  static int pxp_suspend(struct device *dev)
  {
  	struct pxps *pxp = dev_get_drvdata(dev);
  
  	pxp_clk_enable(pxp);
  	while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
  		;
  
  	__raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
  	pxp_clk_disable(pxp);
  
  	return 0;
  }
  
  static int pxp_resume(struct device *dev)
  {
  	struct pxps *pxp = dev_get_drvdata(dev);
  
  	pxp_clk_enable(pxp);
  	/* Pull PxP out of reset */
  	__raw_writel(0, pxp->base + HW_PXP_CTRL);
  	pxp_clk_disable(pxp);
  
  	return 0;
  }
  #else
  #define	pxp_suspend	NULL
  #define	pxp_resume	NULL
  #endif
  
  #ifdef CONFIG_PM
  static int pxp_runtime_suspend(struct device *dev)
  {
  	dev_dbg(dev, "pxp busfreq high release.\n");
  
  	return 0;
  }
  
  static int pxp_runtime_resume(struct device *dev)
  {
  	dev_dbg(dev, "pxp busfreq high request.\n");
  
  	return 0;
  }
  #else
  #define	pxp_runtime_suspend	NULL
  #define	pxp_runtime_resume	NULL
  #endif
  
  static const struct dev_pm_ops pxp_pm_ops = {
  	SET_RUNTIME_PM_OPS(pxp_runtime_suspend, pxp_runtime_resume, NULL)
  	SET_SYSTEM_SLEEP_PM_OPS(pxp_suspend, pxp_resume)
  };
  
  static struct platform_driver pxp_driver = {
  	.driver = {
  			.name = "imx-pxp-v3",
  			.of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
  			.pm = &pxp_pm_ops,
  		   },
  	.probe = pxp_probe,
  	.remove = pxp_remove,
  };
  
  static int __init pxp_init(void)
  {
          return platform_driver_register(&pxp_driver);
  }
  late_initcall(pxp_init);
  
  static void __exit pxp_exit(void)
  {
          platform_driver_unregister(&pxp_driver);
  }
  module_exit(pxp_exit);
  
  
  MODULE_DESCRIPTION("i.MX PxP driver");
  MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  MODULE_LICENSE("GPL");
  