Lines Matching +full:output +full:- +full:enable

1 // SPDX-License-Identifier: GPL-2.0
3 * camss-vfe-4-8.c
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8
7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2021 Linaro Ltd.
17 #include "camss-vfe.h"
18 #include "camss-vfe-gen1.h"
252 u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION); in vfe_hw_version_read()
259 u32 bits = readl_relaxed(vfe->base + reg); in vfe_reg_clr()
261 writel_relaxed(bits & ~clr_bits, vfe->base + reg); in vfe_reg_clr()
266 u32 bits = readl_relaxed(vfe->base + reg); in vfe_reg_set()
268 writel_relaxed(bits | set_bits, vfe->base + reg); in vfe_reg_set()
284 writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0); in vfe_global_reset()
288 writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); in vfe_global_reset()
294 vfe->base + VFE_0_BUS_BDG_CMD); in vfe_halt_request()
299 writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); in vfe_halt_clear()
302 static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) in vfe_wm_frame_based() argument
304 if (enable) in vfe_wm_frame_based()
312 #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
344 switch (pix->pixelformat) { in vfe_get_wm_sizes()
347 *width = pix->width; in vfe_get_wm_sizes()
348 *height = pix->height; in vfe_get_wm_sizes()
349 *bytesperline = pix->plane_fmt[0].bytesperline; in vfe_get_wm_sizes()
355 *width = pix->width; in vfe_get_wm_sizes()
356 *height = pix->height; in vfe_get_wm_sizes()
357 *bytesperline = pix->plane_fmt[0].bytesperline; in vfe_get_wm_sizes()
363 *width = pix->width; in vfe_get_wm_sizes()
364 *height = pix->height; in vfe_get_wm_sizes()
365 *bytesperline = pix->plane_fmt[plane].bytesperline; in vfe_get_wm_sizes()
372 u8 plane, u32 enable) in vfe_wm_line_based() argument
376 if (enable) { in vfe_wm_line_based()
381 wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width); in vfe_wm_line_based()
383 reg = height - 1; in vfe_wm_line_based()
384 reg |= ((wpl + 3) / 4 - 1) << 16; in vfe_wm_line_based()
386 writel_relaxed(reg, vfe->base + in vfe_wm_line_based()
392 reg |= (height - 1) << 2; in vfe_wm_line_based()
395 writel_relaxed(reg, vfe->base + in vfe_wm_line_based()
398 writel_relaxed(0, vfe->base + in vfe_wm_line_based()
400 writel_relaxed(0, vfe->base + in vfe_wm_line_based()
409 reg = readl_relaxed(vfe->base + in vfe_wm_set_framedrop_period()
418 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); in vfe_wm_set_framedrop_period()
424 writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm)); in vfe_wm_set_framedrop_pattern()
434 writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm)); in vfe_wm_set_ub_cfg()
442 writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); in vfe_bus_reload_wm()
451 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm)); in vfe_wm_set_ping_addr()
457 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm)); in vfe_wm_set_pong_addr()
464 reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS); in vfe_wm_get_ping_pong_status()
469 static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable) in vfe_bus_enable_wr_if() argument
471 if (enable) in vfe_bus_enable_wr_if()
472 writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG); in vfe_bus_enable_wr_if()
474 writel_relaxed(0, vfe->base + VFE_0_BUS_CFG); in vfe_bus_enable_wr_if()
515 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); in vfe_wm_set_subsample()
548 static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, in vfe_set_xbar_cfg() argument
549 u8 enable) in vfe_set_xbar_cfg() argument
551 struct vfe_line *line = container_of(output, struct vfe_line, output); in vfe_set_xbar_cfg()
552 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; in vfe_set_xbar_cfg()
563 if (output->wm_idx[0] % 2 == 1) in vfe_set_xbar_cfg()
566 if (enable) in vfe_set_xbar_cfg()
568 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), in vfe_set_xbar_cfg()
572 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), in vfe_set_xbar_cfg()
579 if (output->wm_idx[1] % 2 == 1) in vfe_set_xbar_cfg()
582 if (enable) in vfe_set_xbar_cfg()
584 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), in vfe_set_xbar_cfg()
588 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), in vfe_set_xbar_cfg()
601 if (output->wm_idx[0] % 2 == 1) in vfe_set_xbar_cfg()
604 if (enable) in vfe_set_xbar_cfg()
606 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), in vfe_set_xbar_cfg()
610 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), in vfe_set_xbar_cfg()
619 u8 enable) in vfe_set_realign_cfg() argument
621 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; in vfe_set_realign_cfg()
628 if (enable) { in vfe_set_realign_cfg()
642 writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG); in vfe_set_realign_cfg()
656 vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); in vfe_reg_update()
661 writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); in vfe_reg_update()
670 vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id); in vfe_reg_update_clear()
674 enum vfe_line_id line_id, u8 enable) in vfe_enable_irq_wm_line() argument
681 if (enable) { in vfe_enable_irq_wm_line()
691 enum vfe_line_id line_id, u8 enable) in vfe_enable_irq_pix_line() argument
693 struct vfe_output *output = &vfe->line[line_id].output; in vfe_enable_irq_pix_line() local
704 for (i = 0; i < output->wm_num; i++) { in vfe_enable_irq_pix_line()
705 irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]); in vfe_enable_irq_pix_line()
706 comp_mask |= (1 << output->wm_idx[i]) << comp * 8; in vfe_enable_irq_pix_line()
709 if (enable) { in vfe_enable_irq_pix_line()
734 writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG); in vfe_set_demux_cfg()
737 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0); in vfe_set_demux_cfg()
740 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1); in vfe_set_demux_cfg()
742 switch (line->fmt[MSM_VFE_PAD_SINK].code) { in vfe_set_demux_cfg()
762 writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG); in vfe_set_demux_cfg()
763 writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); in vfe_set_demux_cfg()
768 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; in vfe_set_scale_cfg()
770 u16 input, output; in vfe_set_scale_cfg() local
774 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG); in vfe_set_scale_cfg()
776 input = line->fmt[MSM_VFE_PAD_SINK].width - 1; in vfe_set_scale_cfg()
777 output = line->compose.width - 1; in vfe_set_scale_cfg()
778 reg = (output << 16) | input; in vfe_set_scale_cfg()
779 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE); in vfe_set_scale_cfg()
781 interp_reso = vfe_calc_interp_reso(input, output); in vfe_set_scale_cfg()
782 phase_mult = input * (1 << (14 + interp_reso)) / output; in vfe_set_scale_cfg()
784 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE); in vfe_set_scale_cfg()
786 input = line->fmt[MSM_VFE_PAD_SINK].height - 1; in vfe_set_scale_cfg()
787 output = line->compose.height - 1; in vfe_set_scale_cfg()
788 reg = (output << 16) | input; in vfe_set_scale_cfg()
789 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE); in vfe_set_scale_cfg()
791 interp_reso = vfe_calc_interp_reso(input, output); in vfe_set_scale_cfg()
792 phase_mult = input * (1 << (14 + interp_reso)) / output; in vfe_set_scale_cfg()
794 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE); in vfe_set_scale_cfg()
796 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); in vfe_set_scale_cfg()
798 input = line->fmt[MSM_VFE_PAD_SINK].width - 1; in vfe_set_scale_cfg()
799 output = line->compose.width / 2 - 1; in vfe_set_scale_cfg()
800 reg = (output << 16) | input; in vfe_set_scale_cfg()
801 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); in vfe_set_scale_cfg()
803 interp_reso = vfe_calc_interp_reso(input, output); in vfe_set_scale_cfg()
804 phase_mult = input * (1 << (14 + interp_reso)) / output; in vfe_set_scale_cfg()
806 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); in vfe_set_scale_cfg()
808 input = line->fmt[MSM_VFE_PAD_SINK].height - 1; in vfe_set_scale_cfg()
809 output = line->compose.height - 1; in vfe_set_scale_cfg()
811 output = line->compose.height / 2 - 1; in vfe_set_scale_cfg()
812 reg = (output << 16) | input; in vfe_set_scale_cfg()
813 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); in vfe_set_scale_cfg()
815 interp_reso = vfe_calc_interp_reso(input, output); in vfe_set_scale_cfg()
816 phase_mult = input * (1 << (14 + interp_reso)) / output; in vfe_set_scale_cfg()
818 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); in vfe_set_scale_cfg()
823 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; in vfe_set_crop_cfg()
827 first = line->crop.left; in vfe_set_crop_cfg()
828 last = line->crop.left + line->crop.width - 1; in vfe_set_crop_cfg()
830 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH); in vfe_set_crop_cfg()
832 first = line->crop.top; in vfe_set_crop_cfg()
833 last = line->crop.top + line->crop.height - 1; in vfe_set_crop_cfg()
835 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT); in vfe_set_crop_cfg()
837 first = line->crop.left / 2; in vfe_set_crop_cfg()
838 last = line->crop.left / 2 + line->crop.width / 2 - 1; in vfe_set_crop_cfg()
840 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH); in vfe_set_crop_cfg()
842 first = line->crop.top; in vfe_set_crop_cfg()
843 last = line->crop.top + line->crop.height - 1; in vfe_set_crop_cfg()
845 first = line->crop.top / 2; in vfe_set_crop_cfg()
846 last = line->crop.top / 2 + line->crop.height / 2 - 1; in vfe_set_crop_cfg()
849 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT); in vfe_set_crop_cfg()
858 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG); in vfe_set_clamp_cfg()
864 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); in vfe_set_clamp_cfg()
867 static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) in vfe_set_cgc_override() argument
876 switch (line->fmt[MSM_VFE_PAD_SINK].code) { in vfe_set_camif_cfg()
893 writel_relaxed(val, vfe->base + VFE_0_CORE_CFG); in vfe_set_camif_cfg()
895 val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; in vfe_set_camif_cfg()
896 val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16; in vfe_set_camif_cfg()
897 writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG); in vfe_set_camif_cfg()
899 val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; in vfe_set_camif_cfg()
900 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG); in vfe_set_camif_cfg()
902 val = line->fmt[MSM_VFE_PAD_SINK].height - 1; in vfe_set_camif_cfg()
903 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG); in vfe_set_camif_cfg()
906 writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG); in vfe_set_camif_cfg()
909 writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN); in vfe_set_camif_cfg()
912 writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN); in vfe_set_camif_cfg()
918 writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG); in vfe_set_camif_cfg()
921 static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable) in vfe_set_camif_cmd() argument
926 writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); in vfe_set_camif_cmd()
931 if (enable) in vfe_set_camif_cmd()
936 writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); in vfe_set_camif_cmd()
939 static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) in vfe_set_module_cfg() argument
946 if (enable) { in vfe_set_module_cfg()
960 ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS, in vfe_camif_wait_for_stop()
972 * vfe_isr - VFE module interrupt handler
984 vfe->ops->isr_read(vfe, &value0, &value1); in vfe_isr()
986 dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", in vfe_isr()
990 vfe->isr_ops.reset_ack(vfe); in vfe_isr()
993 vfe->ops->violation_read(vfe); in vfe_isr()
996 vfe->isr_ops.halt_ack(vfe); in vfe_isr()
998 for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) in vfe_isr()
1000 vfe->isr_ops.reg_update(vfe, i); in vfe_isr()
1003 vfe->isr_ops.sof(vfe, VFE_LINE_PIX); in vfe_isr()
1007 vfe->isr_ops.sof(vfe, i); in vfe_isr()
1011 vfe->isr_ops.comp_done(vfe, i); in vfe_isr()
1012 for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++) in vfe_isr()
1013 if (vfe->wm_output_map[j] == VFE_LINE_PIX) in vfe_isr()
1019 vfe->isr_ops.wm_done(vfe, i); in vfe_isr()
1026 /* On VFE4.8 the ub-size is the same on both instances */ in vfe_get_ub_size()
1030 static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) in vfe_wm_enable() argument
1032 if (enable) in vfe_wm_enable()
1034 vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); in vfe_wm_enable()
1037 vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); in vfe_wm_enable()
1050 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); in vfe_set_qos()
1051 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); in vfe_set_qos()
1052 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); in vfe_set_qos()
1053 writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); in vfe_set_qos()
1054 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); in vfe_set_qos()
1055 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); in vfe_set_qos()
1056 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); in vfe_set_qos()
1057 writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); in vfe_set_qos()
1065 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); in vfe_set_ds()
1066 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); in vfe_set_ds()
1067 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); in vfe_set_ds()
1068 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); in vfe_set_ds()
1069 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); in vfe_set_ds()
1070 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); in vfe_set_ds()
1071 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); in vfe_set_ds()
1072 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); in vfe_set_ds()
1073 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); in vfe_set_ds()
1074 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); in vfe_set_ds()
1075 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); in vfe_set_ds()
1076 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); in vfe_set_ds()
1077 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); in vfe_set_ds()
1078 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); in vfe_set_ds()
1079 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); in vfe_set_ds()
1080 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); in vfe_set_ds()
1081 writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); in vfe_set_ds()
1086 *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); in vfe_isr_read()
1087 *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); in vfe_isr_read()
1089 writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); in vfe_isr_read()
1090 writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); in vfe_isr_read()
1094 writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); in vfe_isr_read()
1098 * vfe_pm_domain_off - Disable power domains specific to this VFE.
1103 struct camss *camss = vfe->camss; in vfe_pm_domain_off()
1105 device_link_del(camss->genpd_link[vfe->id]); in vfe_pm_domain_off()
1109 * vfe_pm_domain_on - Enable power domains specific to this VFE.
1114 struct camss *camss = vfe->camss; in vfe_pm_domain_on()
1115 enum vfe_line_id id = vfe->id; in vfe_pm_domain_on()
1117 camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS | in vfe_pm_domain_on()
1120 if (!camss->genpd_link[id]) { in vfe_pm_domain_on()
1121 dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id); in vfe_pm_domain_on()
1122 return -EINVAL; in vfe_pm_domain_on()
1130 u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); in vfe_violation_read()
1174 vfe->isr_ops = vfe_isr_ops_gen1; in vfe_subdev_init()
1175 vfe->ops_gen1 = &vfe_ops_gen1_4_8; in vfe_subdev_init()
1176 vfe->video_ops = vfe_video_ops_gen1; in vfe_subdev_init()
1178 vfe->line_num = VFE_LINE_NUM_GEN1; in vfe_subdev_init()