s5p_tv_vmx_err __s5p_vm_init_layer(s5p_tv_vmx_layer layer, bool show, //video,grp bool win_blending, //video,grp u32 alpha, //video,grp u32 priority, //video,grp s5p_tv_vmx_color_fmt color, //grp bool blank_change, //grp bool pixel_blending, //grp bool premul, //grp u32 blank_color, //grp u32 base_addr, //grp u32 span, //grp u32 width, //grp u32 height, //grp u32 src_offs_x, //grp u32 src_offs_y, //grp u32 dst_offs_x, //grp u32 dst_offs_y) //grp { u32 temp_reg = 0; VMPRINTK("%d,%d,%d,%d,%d,%d,%d,%d,%d,0x%x,0x%x,%d,%d,%d,%d,%d,%d,%d)\n\r", layer, show, win_blending, alpha, priority, color, blank_change, pixel_blending, premul, blank_color,base_addr, span, width, height, src_offs_x, src_offs_y, dst_offs_x, dst_offs_y); switch (layer) { case VM_VIDEO_LAYER: temp_reg = (win_blending) ? S5P_MXR_VP_BLEND_ENABLE : S5P_MXR_VP_BLEND_DISABLE; temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); break; case VM_GPR0_LAYER: temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : S5P_MXR_BLANK_CHANGE_NEW_PIXEL; temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE; temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : S5P_MXR_WIN_BLEND_DISABLE; temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : S5P_MXR_PIXEL_BLEND_DISABLE; temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), mixer_base + S5P_MXR_GRAPHIC0_BLANK); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); __s5p_vm_set_grp_layer_size(layer, span, width, height, src_offs_x, src_offs_y); __s5p_vm_set_grp_base_address(layer, base_addr); __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); break; case VM_GPR1_LAYER: temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : S5P_MXR_BLANK_CHANGE_NEW_PIXEL; temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE; temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : S5P_MXR_WIN_BLEND_DISABLE; temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : S5P_MXR_PIXEL_BLEND_DISABLE; temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), mixer_base + S5P_MXR_GRAPHIC1_BLANK); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); __s5p_vm_set_grp_layer_size(layer, span, width, height, src_offs_x, src_offs_y); __s5p_vm_set_grp_base_address(layer, base_addr); __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); break; default: VMPRINTK("invalid layer parameter = %d\n\r", layer); return S5P_TV_VMX_ERR_INVALID_PARAM; break; } __s5p_vm_set_layer_priority(layer, priority); __s5p_vm_set_layer_show(layer, show); return VMIXER_NO_ERROR; }
int s5ptvfb_set_window_position(struct s5p_tv_status *ctrl, int id) { u32 off_x, off_y; u32 w_t, h_t; u32 w, h; struct fb_var_screeninfo *var = &ctrl->fb->var; struct s5ptvfb_window *win = ctrl->fb->par; off_x = (u32)win->x; off_y = (u32)win->y; w = var->xres; h = var->yres; /* * When tvout resolution was overscanned, there is no * adjust method in H/W. So, framebuffer should be resized. * In this case - TV w/h is greater than FB w/h, grp layer's * dst offset must be changed to fix tv screen. */ switch (ctrl->tvout_param.disp_mode) { case TVOUT_NTSC_M: case TVOUT_480P_60_16_9: case TVOUT_480P_60_4_3: case TVOUT_480P_59: w_t = 720; h_t = 480; break; case TVOUT_576P_50_16_9: case TVOUT_576P_50_4_3: w_t = 720; h_t = 576; break; case TVOUT_720P_60: case TVOUT_720P_59: case TVOUT_720P_50: w_t = 1280; h_t = 720; break; case TVOUT_1080I_60: case TVOUT_1080I_59: case TVOUT_1080I_50: case TVOUT_1080P_60: case TVOUT_1080P_59: case TVOUT_1080P_50: case TVOUT_1080P_30: w_t = 1920; h_t = 1080; break; default: w_t = 0; h_t = 0; break; } if (w_t > w) off_x = (w_t - w) / 2; if (h_t > h) off_y = (h_t - h) / 2; __s5p_vm_set_grp_layer_position(VM_GPR0_LAYER, off_x, off_y); return 0; }
enum s5p_tv_vmx_err __s5p_vm_init_layer(enum s5p_tv_disp_mode mode, enum s5p_tv_vmx_layer layer, bool show, bool win_blending, u32 alpha, u32 priority, enum s5p_tv_vmx_color_fmt color, bool blank_change, bool pixel_blending, bool premul, u32 blank_color, u32 base_addr, u32 span, u32 width, u32 height, u32 src_offs_x, u32 src_offs_y, u32 dst_offs_x, u32 dst_offs_y, u32 dst_width, u32 dst_height) { u32 temp_reg = 0; u32 h_factor = 0, v_factor = 0; VMPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x,\ 0x%x, %d, %d, %d, %d, %d, %d, %d)\n\r", layer, show, win_blending, alpha, priority, color, blank_change, pixel_blending, premul, blank_color, base_addr, span, width, height, src_offs_x, src_offs_y, dst_offs_x, dst_offs_y); switch (layer) { case VM_VIDEO_LAYER: temp_reg = (win_blending) ? S5P_MXR_VP_BLEND_ENABLE : S5P_MXR_VP_BLEND_DISABLE; temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); /* temp yuv pxl limiter setting*/ temp_reg &= ~(1<<17); writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); break; case VM_GPR0_LAYER: temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : S5P_MXR_BLANK_CHANGE_NEW_PIXEL; temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE; temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : S5P_MXR_WIN_BLEND_DISABLE; temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : S5P_MXR_PIXEL_BLEND_DISABLE; temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), mixer_base + S5P_MXR_GRAPHIC0_BLANK); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); __s5p_vm_set_grp_layer_size(layer, span, width, height, src_offs_x, src_offs_y); __s5p_vm_set_grp_base_address(layer, base_addr); __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_WH); h_factor = grp_scaling_factor(width, dst_width, 1); v_factor = grp_scaling_factor(height, dst_height, 0); temp_reg &= ~((0x3<<28)|(0x3<<12)); if (v_factor) { u32 reg = readl(mixer_base + S5P_MXR_CFG); /* In interlaced mode, vertical scaling must be * replaced by PROGRESSIVE_MODE - pixel duplication */ if (mode == TVOUT_1080I_50 || mode == TVOUT_1080I_59 || mode == TVOUT_1080I_60) { /* scaled up by progressive setting */ reg |= S5P_MXR_PROGRESSVE_MODE; writel(reg, mixer_base + S5P_MXR_CFG); } else /* scaled up by scale factor */ temp_reg |= v_factor << 12; } else { u32 reg = readl(mixer_base + S5P_MXR_CFG); /* * if v_factor is 0, recover the original mode */ if (mode == TVOUT_1080I_50 || mode == TVOUT_1080I_59 || mode == TVOUT_1080I_60) { reg &= S5P_MXR_INTERLACE_MODE; writel(reg, mixer_base + S5P_MXR_CFG); } } temp_reg |= h_factor << 28; writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC0_WH); break; case VM_GPR1_LAYER: temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : S5P_MXR_BLANK_CHANGE_NEW_PIXEL; temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE; temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : S5P_MXR_WIN_BLEND_DISABLE; temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : S5P_MXR_PIXEL_BLEND_DISABLE; temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), mixer_base + S5P_MXR_GRAPHIC1_BLANK); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); __s5p_vm_set_grp_layer_size(layer, span, width, height, src_offs_x, src_offs_y); __s5p_vm_set_grp_base_address(layer, base_addr); __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_WH); h_factor = grp_scaling_factor(width, dst_width, 1); v_factor = grp_scaling_factor(height, dst_height, 0); temp_reg &= ~((0x3<<28)|(0x3<<12)); if (v_factor) { u32 reg = readl(mixer_base + S5P_MXR_CFG); /* In interlaced mode, vertical scaling must be * replaced by PROGRESSIVE_MODE - pixel duplication */ if (mode == TVOUT_1080I_50 || mode == TVOUT_1080I_59 || mode == TVOUT_1080I_60) { /* scaled up by progressive setting */ reg |= S5P_MXR_PROGRESSVE_MODE; writel(reg, mixer_base + S5P_MXR_CFG); } else /* scaled up by scale factor */ temp_reg |= v_factor << 12; } else { u32 reg = readl(mixer_base + S5P_MXR_CFG); /* * if v_factor is 0, recover the original mode */ if (mode == TVOUT_1080I_50 || mode == TVOUT_1080I_59 || mode == TVOUT_1080I_60) { reg &= S5P_MXR_INTERLACE_MODE; writel(reg, mixer_base + S5P_MXR_CFG); } } temp_reg |= h_factor << 28; writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC1_WH); break; default: VMPRINTK("invalid layer parameter = %d\n\r", layer); return S5P_TV_VMX_ERR_INVALID_PARAM; break; } __s5p_vm_set_layer_priority(layer, priority); __s5p_vm_set_layer_show(layer, show); return VMIXER_NO_ERROR; }