+static int area_xst(struct rk_lcdc_win *win, int area_num)
+{
+ struct rk_lcdc_win_area area_temp;
+ int i, j;
+
+ for (i = 0; i < area_num; i++) {
+ for (j = i + 1; j < area_num; j++) {
+ if (win->area[i].dsp_stx > win->area[j].dsp_stx) {
+ memcpy(&area_temp, &win->area[i],
+ sizeof(struct rk_lcdc_win_area));
+ memcpy(&win->area[i], &win->area[j],
+ sizeof(struct rk_lcdc_win_area));
+ memcpy(&win->area[j], &area_temp,
+ sizeof(struct rk_lcdc_win_area));
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int vop_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
+{
+ struct vop_device *vop_dev =
+ container_of(dev_drv, struct vop_device, driver);
+ struct rk_lcdc_win *win = dev_drv->win[win_id];
+ unsigned int off;
+ u64 val;
+
+ off = (win_id - 2) * 0x50;
+ area_xst(win, win->area_num);
+
+ if (win->state == 1) {
+ vop_axi_gather_cfg(vop_dev, win);
+ val = V_WIN2_EN(1) | V_WIN1_CSC_MODE(win->csc_mode);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ /* area 0 */
+ if (win->area[0].state == 1) {
+ val = V_WIN2_MST0_EN(win->area[0].state) |
+ V_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
+ V_WIN2_RB_SWAP0(win->area[0].swap_rb);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+
+ val = V_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
+ vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
+
+ val = V_WIN2_DSP_WIDTH0(win->area[0].xsize) |
+ V_WIN2_DSP_HEIGHT0(win->area[0].ysize);
+ vop_writel(vop_dev, WIN2_DSP_INFO0 + off, val);
+ val = V_WIN2_DSP_XST0(win->area[0].dsp_stx) |
+ V_WIN2_DSP_YST0(win->area[0].dsp_sty);
+ vop_writel(vop_dev, WIN2_DSP_ST0 + off, val);
+ } else {
+ val = V_WIN2_MST0_EN(0);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ }
+ /* area 1 */
+ if (win->area[1].state == 1) {
+ val = V_WIN2_MST1_EN(win->area[1].state) |
+ V_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
+ V_WIN2_RB_SWAP1(win->area[1].swap_rb);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+
+ val = V_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
+ vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
+
+ val = V_WIN2_DSP_WIDTH1(win->area[1].xsize) |
+ V_WIN2_DSP_HEIGHT1(win->area[1].ysize);
+ vop_writel(vop_dev, WIN2_DSP_INFO1 + off, val);
+ val = V_WIN2_DSP_XST1(win->area[1].dsp_stx) |
+ V_WIN2_DSP_YST1(win->area[1].dsp_sty);
+ vop_writel(vop_dev, WIN2_DSP_ST1 + off, val);
+ } else {
+ val = V_WIN2_MST1_EN(0);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ }
+ /* area 2 */
+ if (win->area[2].state == 1) {
+ val = V_WIN2_MST2_EN(win->area[2].state) |
+ V_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
+ V_WIN2_RB_SWAP2(win->area[2].swap_rb);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+
+ val = V_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
+ vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
+
+ val = V_WIN2_DSP_WIDTH2(win->area[2].xsize) |
+ V_WIN2_DSP_HEIGHT2(win->area[2].ysize);
+ vop_writel(vop_dev, WIN2_DSP_INFO2 + off, val);
+ val = V_WIN2_DSP_XST2(win->area[2].dsp_stx) |
+ V_WIN2_DSP_YST2(win->area[2].dsp_sty);
+ vop_writel(vop_dev, WIN2_DSP_ST2 + off, val);
+ } else {
+ val = V_WIN2_MST2_EN(0);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ }
+ /* area 3 */
+ if (win->area[3].state == 1) {
+ val = V_WIN2_MST3_EN(win->area[3].state) |
+ V_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
+ V_WIN2_RB_SWAP3(win->area[3].swap_rb);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+
+ val = V_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
+ vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
+
+ val = V_WIN2_DSP_WIDTH3(win->area[3].xsize) |
+ V_WIN2_DSP_HEIGHT3(win->area[3].ysize);
+ vop_writel(vop_dev, WIN2_DSP_INFO3 + off, val);
+ val = V_WIN2_DSP_XST3(win->area[3].dsp_stx) |
+ V_WIN2_DSP_YST3(win->area[3].dsp_sty);
+ vop_writel(vop_dev, WIN2_DSP_ST3 + off, val);
+ } else {
+ val = V_WIN2_MST3_EN(0);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ }
+
+ if (win->alpha_en == 1) {
+ vop_alpha_cfg(dev_drv, win_id);
+ } else {
+ val = V_WIN2_SRC_ALPHA_EN(0);
+ vop_msk_reg(vop_dev, WIN2_SRC_ALPHA_CTRL + off, val);
+ }
+ } else {
+ val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
+ V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
+ vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
+ }
+
+ return 0;
+}
+