1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * camss-vfe.c 4 * 5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 6 * 7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. 8 * Copyright (C) 2015-2018 Linaro Ltd. 9 */ 10 #include <linux/clk.h> 11 #include <linux/completion.h> 12 #include <linux/interrupt.h> 13 #include <linux/iommu.h> 14 #include <linux/mutex.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_domain.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/spinlock_types.h> 20 #include <linux/spinlock.h> 21 #include <media/media-entity.h> 22 #include <media/v4l2-device.h> 23 #include <media/v4l2-subdev.h> 24 25 #include "camss-vfe.h" 26 #include "camss.h" 27 28 #define MSM_VFE_NAME "msm_vfe" 29 30 /* VFE reset timeout */ 31 #define VFE_RESET_TIMEOUT_MS 50 32 33 #define SCALER_RATIO_MAX 16 34 35 #define VFE_HW_VERSION 0x0 36 #define HW_VERSION_STEPPING 0 37 #define HW_VERSION_REVISION 16 38 #define HW_VERSION_GENERATION 28 39 40 static const struct camss_format_info formats_rdi_8x16[] = { 41 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1, 42 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 43 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1, 44 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 45 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1, 46 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 47 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1, 48 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 49 { MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1, 50 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 51 { MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1, 52 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 53 { MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1, 54 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 55 { MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1, 56 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 57 { MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1, 58 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 59 { MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1, 60 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 61 { MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1, 62 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 63 { MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1, 64 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 65 { MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1, 66 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 67 { MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1, 68 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 69 { MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1, 70 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 71 { MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1, 72 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 73 { MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1, 74 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 75 }; 76 77 static const struct camss_format_info formats_rdi_8x96[] = { 78 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1, 79 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 80 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1, 81 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 82 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1, 83 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 84 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1, 85 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 86 { MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1, 87 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 88 { MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1, 89 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 90 { MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1, 91 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 92 { MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1, 93 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 94 { MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1, 95 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 96 { MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1, 97 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 98 { MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1, 99 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 100 { MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1, 101 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 102 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1, 103 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 104 { MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1, 105 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 106 { MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1, 107 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 108 { MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1, 109 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 110 { MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1, 111 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 112 { MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1, 113 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 114 { MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1, 115 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 116 { MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1, 117 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 118 { MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1, 119 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 120 { MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1, 121 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 122 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1, 123 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 124 }; 125 126 static const struct camss_format_info formats_rdi_845[] = { 127 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1, 128 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 129 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1, 130 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 131 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1, 132 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 133 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1, 134 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 135 { MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1, 136 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 137 { MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1, 138 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 139 { MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1, 140 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 141 { MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1, 142 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 143 { MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1, 144 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 145 { MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1, 146 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 147 { MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1, 148 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 149 { MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1, 150 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 151 { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1, 152 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 153 { MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1, 154 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 155 { MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1, 156 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 157 { MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1, 158 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 159 { MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1, 160 PER_PLANE_DATA(0, 1, 1, 1, 1, 12) }, 161 { MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1, 162 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 163 { MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1, 164 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 165 { MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1, 166 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 167 { MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1, 168 PER_PLANE_DATA(0, 1, 1, 1, 1, 14) }, 169 { MEDIA_BUS_FMT_Y8_1X8, 8, V4L2_PIX_FMT_GREY, 1, 170 PER_PLANE_DATA(0, 1, 1, 1, 1, 8) }, 171 { MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1, 172 PER_PLANE_DATA(0, 1, 1, 1, 1, 10) }, 173 { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1, 174 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 175 }; 176 177 static const struct camss_format_info formats_pix_8x16[] = { 178 { MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 179 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 180 { MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 181 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 182 { MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 183 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 184 { MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 185 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 186 { MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 187 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 188 { MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 189 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 190 { MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 191 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 192 { MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 193 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 194 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 195 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 196 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 197 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 198 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 199 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 200 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 201 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 202 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 203 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 204 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 205 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 206 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 207 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 208 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 209 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 210 }; 211 212 static const struct camss_format_info formats_pix_8x96[] = { 213 { MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 214 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 215 { MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 216 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 217 { MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 218 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 219 { MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1, 220 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 221 { MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 222 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 223 { MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 224 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 225 { MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 226 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 227 { MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1, 228 PER_PLANE_DATA(0, 1, 1, 2, 3, 8) }, 229 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 230 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 231 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 232 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 233 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 234 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 235 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1, 236 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 237 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 238 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 239 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 240 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 241 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 242 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 243 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1, 244 PER_PLANE_DATA(0, 1, 1, 1, 2, 8) }, 245 { MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1, 246 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 247 { MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1, 248 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 249 { MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1, 250 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 251 { MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1, 252 PER_PLANE_DATA(0, 1, 1, 1, 1, 16) }, 253 }; 254 255 const struct camss_formats vfe_formats_rdi_8x16 = { 256 .nformats = ARRAY_SIZE(formats_rdi_8x16), 257 .formats = formats_rdi_8x16 258 }; 259 260 const struct camss_formats vfe_formats_pix_8x16 = { 261 .nformats = ARRAY_SIZE(formats_pix_8x16), 262 .formats = formats_pix_8x16 263 }; 264 265 const struct camss_formats vfe_formats_rdi_8x96 = { 266 .nformats = ARRAY_SIZE(formats_rdi_8x96), 267 .formats = formats_rdi_8x96 268 }; 269 270 const struct camss_formats vfe_formats_pix_8x96 = { 271 .nformats = ARRAY_SIZE(formats_pix_8x96), 272 .formats = formats_pix_8x96 273 }; 274 275 const struct camss_formats vfe_formats_rdi_845 = { 276 .nformats = ARRAY_SIZE(formats_rdi_845), 277 .formats = formats_rdi_845 278 }; 279 280 /* TODO: Replace with pix formats */ 281 const struct camss_formats vfe_formats_pix_845 = { 282 .nformats = ARRAY_SIZE(formats_rdi_845), 283 .formats = formats_rdi_845 284 }; 285 286 static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, 287 unsigned int index, u32 src_req_code) 288 { 289 struct vfe_device *vfe = to_vfe(line); 290 291 switch (vfe->camss->res->version) { 292 case CAMSS_8x16: 293 case CAMSS_8x53: 294 switch (sink_code) { 295 case MEDIA_BUS_FMT_YUYV8_1X16: 296 { 297 u32 src_code[] = { 298 MEDIA_BUS_FMT_YUYV8_1X16, 299 MEDIA_BUS_FMT_YUYV8_1_5X8, 300 }; 301 302 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 303 index, src_req_code); 304 } 305 case MEDIA_BUS_FMT_YVYU8_1X16: 306 { 307 u32 src_code[] = { 308 MEDIA_BUS_FMT_YVYU8_1X16, 309 MEDIA_BUS_FMT_YVYU8_1_5X8, 310 }; 311 312 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 313 index, src_req_code); 314 } 315 case MEDIA_BUS_FMT_UYVY8_1X16: 316 { 317 u32 src_code[] = { 318 MEDIA_BUS_FMT_UYVY8_1X16, 319 MEDIA_BUS_FMT_UYVY8_1_5X8, 320 }; 321 322 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 323 index, src_req_code); 324 } 325 case MEDIA_BUS_FMT_VYUY8_1X16: 326 { 327 u32 src_code[] = { 328 MEDIA_BUS_FMT_VYUY8_1X16, 329 MEDIA_BUS_FMT_VYUY8_1_5X8, 330 }; 331 332 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 333 index, src_req_code); 334 } 335 default: 336 if (index > 0) 337 return 0; 338 339 return sink_code; 340 } 341 break; 342 case CAMSS_660: 343 case CAMSS_2290: 344 case CAMSS_7280: 345 case CAMSS_8x96: 346 case CAMSS_8250: 347 case CAMSS_8280XP: 348 case CAMSS_8300: 349 case CAMSS_845: 350 case CAMSS_8550: 351 case CAMSS_8775P: 352 case CAMSS_X1E80100: 353 switch (sink_code) { 354 case MEDIA_BUS_FMT_YUYV8_1X16: 355 { 356 u32 src_code[] = { 357 MEDIA_BUS_FMT_YUYV8_1X16, 358 MEDIA_BUS_FMT_YVYU8_1X16, 359 MEDIA_BUS_FMT_UYVY8_1X16, 360 MEDIA_BUS_FMT_VYUY8_1X16, 361 MEDIA_BUS_FMT_YUYV8_1_5X8, 362 }; 363 364 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 365 index, src_req_code); 366 } 367 case MEDIA_BUS_FMT_YVYU8_1X16: 368 { 369 u32 src_code[] = { 370 MEDIA_BUS_FMT_YVYU8_1X16, 371 MEDIA_BUS_FMT_YUYV8_1X16, 372 MEDIA_BUS_FMT_UYVY8_1X16, 373 MEDIA_BUS_FMT_VYUY8_1X16, 374 MEDIA_BUS_FMT_YVYU8_1_5X8, 375 }; 376 377 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 378 index, src_req_code); 379 } 380 case MEDIA_BUS_FMT_UYVY8_1X16: 381 { 382 u32 src_code[] = { 383 MEDIA_BUS_FMT_UYVY8_1X16, 384 MEDIA_BUS_FMT_YUYV8_1X16, 385 MEDIA_BUS_FMT_YVYU8_1X16, 386 MEDIA_BUS_FMT_VYUY8_1X16, 387 MEDIA_BUS_FMT_UYVY8_1_5X8, 388 }; 389 390 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 391 index, src_req_code); 392 } 393 case MEDIA_BUS_FMT_VYUY8_1X16: 394 { 395 u32 src_code[] = { 396 MEDIA_BUS_FMT_VYUY8_1X16, 397 MEDIA_BUS_FMT_YUYV8_1X16, 398 MEDIA_BUS_FMT_YVYU8_1X16, 399 MEDIA_BUS_FMT_UYVY8_1X16, 400 MEDIA_BUS_FMT_VYUY8_1_5X8, 401 }; 402 403 return camss_format_find_code(src_code, ARRAY_SIZE(src_code), 404 index, src_req_code); 405 } 406 default: 407 if (index > 0) 408 return 0; 409 410 return sink_code; 411 } 412 break; 413 default: 414 WARN(1, "Unsupported HW version: %x\n", 415 vfe->camss->res->version); 416 break; 417 } 418 return 0; 419 } 420 421 /* 422 * vfe_hw_version - Process write master done interrupt 423 * @vfe: VFE Device 424 * 425 * Return vfe hw version 426 */ 427 u32 vfe_hw_version(struct vfe_device *vfe) 428 { 429 u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION); 430 431 u32 gen = (hw_version >> HW_VERSION_GENERATION) & 0xF; 432 u32 rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF; 433 u32 step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF; 434 435 dev_dbg(vfe->camss->dev, "VFE:%d HW Version = %u.%u.%u\n", 436 vfe->id, gen, rev, step); 437 438 return hw_version; 439 } 440 441 /* 442 * vfe_buf_done - Process write master done interrupt 443 * @vfe: VFE Device 444 * @wm: Write master id 445 */ 446 void vfe_buf_done(struct vfe_device *vfe, int wm) 447 { 448 struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]]; 449 const struct vfe_hw_ops *ops = vfe->res->hw_ops; 450 struct camss_buffer *ready_buf; 451 struct vfe_output *output; 452 unsigned long flags; 453 u32 index; 454 u64 ts = ktime_get_ns(); 455 456 spin_lock_irqsave(&vfe->output_lock, flags); 457 458 if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { 459 dev_err_ratelimited(vfe->camss->dev, 460 "Received wm done for unmapped index\n"); 461 goto out_unlock; 462 } 463 output = &vfe->line[vfe->wm_output_map[wm]].output; 464 465 ready_buf = output->buf[0]; 466 if (!ready_buf) { 467 dev_err_ratelimited(vfe->camss->dev, 468 "Missing ready buf %d!\n", output->state); 469 goto out_unlock; 470 } 471 472 ready_buf->vb.vb2_buf.timestamp = ts; 473 ready_buf->vb.sequence = output->sequence++; 474 475 index = 0; 476 output->buf[0] = output->buf[1]; 477 if (output->buf[0]) 478 index = 1; 479 480 output->buf[index] = vfe_buf_get_pending(output); 481 482 if (output->buf[index]) { 483 ops->vfe_wm_update(vfe, output->wm_idx[0], 484 output->buf[index]->addr[0], 485 line); 486 ops->reg_update(vfe, line->id); 487 } else { 488 output->gen2.active_num--; 489 } 490 491 spin_unlock_irqrestore(&vfe->output_lock, flags); 492 493 vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); 494 495 return; 496 497 out_unlock: 498 spin_unlock_irqrestore(&vfe->output_lock, flags); 499 } 500 501 int vfe_enable_output_v2(struct vfe_line *line) 502 { 503 struct vfe_device *vfe = to_vfe(line); 504 struct vfe_output *output = &line->output; 505 const struct vfe_hw_ops *ops = vfe->res->hw_ops; 506 struct media_pad *sensor_pad; 507 unsigned long flags; 508 unsigned int frame_skip = 0; 509 unsigned int i; 510 511 sensor_pad = camss_find_sensor_pad(&line->subdev.entity); 512 if (sensor_pad) { 513 struct v4l2_subdev *subdev = 514 media_entity_to_v4l2_subdev(sensor_pad->entity); 515 516 v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip); 517 /* Max frame skip is 29 frames */ 518 if (frame_skip > VFE_FRAME_DROP_VAL - 1) 519 frame_skip = VFE_FRAME_DROP_VAL - 1; 520 } 521 522 spin_lock_irqsave(&vfe->output_lock, flags); 523 524 ops->reg_update_clear(vfe, line->id); 525 526 if (output->state > VFE_OUTPUT_RESERVED) { 527 dev_err(vfe->camss->dev, 528 "Output is not in reserved state %d\n", 529 output->state); 530 spin_unlock_irqrestore(&vfe->output_lock, flags); 531 return -EINVAL; 532 } 533 534 WARN_ON(output->gen2.active_num); 535 536 output->state = VFE_OUTPUT_ON; 537 538 output->sequence = 0; 539 output->wait_reg_update = 0; 540 reinit_completion(&output->reg_update); 541 542 ops->vfe_wm_start(vfe, output->wm_idx[0], line); 543 544 for (i = 0; i < 2; i++) { 545 output->buf[i] = vfe_buf_get_pending(output); 546 if (!output->buf[i]) 547 break; 548 output->gen2.active_num++; 549 ops->vfe_wm_update(vfe, output->wm_idx[0], 550 output->buf[i]->addr[0], line); 551 ops->reg_update(vfe, line->id); 552 } 553 554 spin_unlock_irqrestore(&vfe->output_lock, flags); 555 556 return 0; 557 } 558 559 /* 560 * vfe_queue_buffer_v2 - Add empty buffer 561 * @vid: Video device structure 562 * @buf: Buffer to be enqueued 563 * 564 * Add an empty buffer - depending on the current number of buffers it will be 565 * put in pending buffer queue or directly given to the hardware to be filled. 566 * 567 * Return 0 on success or a negative error code otherwise 568 */ 569 int vfe_queue_buffer_v2(struct camss_video *vid, 570 struct camss_buffer *buf) 571 { 572 struct vfe_line *line = container_of(vid, struct vfe_line, video_out); 573 struct vfe_device *vfe = to_vfe(line); 574 const struct vfe_hw_ops *ops = vfe->res->hw_ops; 575 struct vfe_output *output; 576 unsigned long flags; 577 578 output = &line->output; 579 580 spin_lock_irqsave(&vfe->output_lock, flags); 581 582 if (output->state == VFE_OUTPUT_ON && 583 output->gen2.active_num < 2) { 584 output->buf[output->gen2.active_num++] = buf; 585 ops->vfe_wm_update(vfe, output->wm_idx[0], 586 buf->addr[0], line); 587 ops->reg_update(vfe, line->id); 588 } else { 589 vfe_buf_add_pending(output, buf); 590 } 591 592 spin_unlock_irqrestore(&vfe->output_lock, flags); 593 594 return 0; 595 } 596 597 /* 598 * vfe_enable_v2 - Enable streaming on VFE line 599 * @line: VFE line 600 * 601 * Return 0 on success or a negative error code otherwise 602 */ 603 int vfe_enable_v2(struct vfe_line *line) 604 { 605 struct vfe_device *vfe = to_vfe(line); 606 const struct vfe_hw_ops *ops = vfe->res->hw_ops; 607 int ret; 608 609 mutex_lock(&vfe->stream_lock); 610 611 if (vfe->res->hw_ops->enable_irq) 612 ops->enable_irq(vfe); 613 614 vfe->stream_count++; 615 616 mutex_unlock(&vfe->stream_lock); 617 618 ret = vfe_get_output_v2(line); 619 if (ret < 0) 620 goto error_get_output; 621 622 ret = vfe_enable_output_v2(line); 623 if (ret < 0) 624 goto error_enable_output; 625 626 vfe->was_streaming = 1; 627 628 return 0; 629 630 error_enable_output: 631 vfe_put_output(line); 632 633 error_get_output: 634 mutex_lock(&vfe->stream_lock); 635 636 vfe->stream_count--; 637 638 mutex_unlock(&vfe->stream_lock); 639 640 return ret; 641 } 642 643 /* 644 * vfe_get_output_v2 - Get vfe output port for corresponding VFE line 645 * @line: VFE line 646 * 647 * Return 0 on success or a negative error code otherwise 648 */ 649 int vfe_get_output_v2(struct vfe_line *line) 650 { 651 struct vfe_device *vfe = to_vfe(line); 652 struct vfe_output *output; 653 unsigned long flags; 654 655 spin_lock_irqsave(&vfe->output_lock, flags); 656 657 output = &line->output; 658 if (output->state > VFE_OUTPUT_RESERVED) { 659 dev_err(vfe->camss->dev, "Output is running\n"); 660 goto error; 661 } 662 663 output->wm_num = 1; 664 665 /* Correspondence between VFE line number and WM number. 666 * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3 667 * Note this 1:1 mapping will not work for PIX streams. 668 */ 669 output->wm_idx[0] = line->id; 670 vfe->wm_output_map[line->id] = line->id; 671 672 output->drop_update_idx = 0; 673 674 spin_unlock_irqrestore(&vfe->output_lock, flags); 675 676 return 0; 677 678 error: 679 spin_unlock_irqrestore(&vfe->output_lock, flags); 680 output->state = VFE_OUTPUT_OFF; 681 682 return -EINVAL; 683 } 684 685 int vfe_reset(struct vfe_device *vfe) 686 { 687 unsigned long time; 688 689 reinit_completion(&vfe->reset_complete); 690 691 vfe->res->hw_ops->global_reset(vfe); 692 693 time = wait_for_completion_timeout(&vfe->reset_complete, 694 msecs_to_jiffies(VFE_RESET_TIMEOUT_MS)); 695 if (!time) { 696 dev_err(vfe->camss->dev, "VFE reset timeout\n"); 697 return -EIO; 698 } 699 700 return 0; 701 } 702 703 static void vfe_init_outputs(struct vfe_device *vfe) 704 { 705 int i; 706 707 for (i = 0; i < vfe->res->line_num; i++) { 708 struct vfe_output *output = &vfe->line[i].output; 709 710 output->state = VFE_OUTPUT_OFF; 711 output->buf[0] = NULL; 712 output->buf[1] = NULL; 713 INIT_LIST_HEAD(&output->pending_bufs); 714 } 715 } 716 717 static void vfe_reset_output_maps(struct vfe_device *vfe) 718 { 719 int i; 720 721 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) 722 vfe->wm_output_map[i] = VFE_LINE_NONE; 723 } 724 725 int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) 726 { 727 int ret = -EBUSY; 728 int i; 729 730 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) { 731 if (vfe->wm_output_map[i] == VFE_LINE_NONE) { 732 vfe->wm_output_map[i] = line_id; 733 ret = i; 734 break; 735 } 736 } 737 738 return ret; 739 } 740 741 int vfe_release_wm(struct vfe_device *vfe, u8 wm) 742 { 743 if (wm >= ARRAY_SIZE(vfe->wm_output_map)) 744 return -EINVAL; 745 746 vfe->wm_output_map[wm] = VFE_LINE_NONE; 747 748 return 0; 749 } 750 751 struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output) 752 { 753 struct camss_buffer *buffer = NULL; 754 755 if (!list_empty(&output->pending_bufs)) { 756 buffer = list_first_entry(&output->pending_bufs, 757 struct camss_buffer, 758 queue); 759 list_del(&buffer->queue); 760 } 761 762 return buffer; 763 } 764 765 void vfe_buf_add_pending(struct vfe_output *output, 766 struct camss_buffer *buffer) 767 { 768 INIT_LIST_HEAD(&buffer->queue); 769 list_add_tail(&buffer->queue, &output->pending_bufs); 770 } 771 772 /* 773 * vfe_buf_flush_pending - Flush all pending buffers. 774 * @output: VFE output 775 * @state: vb2 buffer state 776 */ 777 static void vfe_buf_flush_pending(struct vfe_output *output, 778 enum vb2_buffer_state state) 779 { 780 struct camss_buffer *buf; 781 struct camss_buffer *t; 782 783 list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) { 784 vb2_buffer_done(&buf->vb.vb2_buf, state); 785 list_del(&buf->queue); 786 } 787 } 788 789 int vfe_put_output(struct vfe_line *line) 790 { 791 struct vfe_device *vfe = to_vfe(line); 792 struct vfe_output *output = &line->output; 793 unsigned long flags; 794 unsigned int i; 795 796 spin_lock_irqsave(&vfe->output_lock, flags); 797 798 for (i = 0; i < output->wm_num; i++) 799 vfe_release_wm(vfe, output->wm_idx[i]); 800 801 output->state = VFE_OUTPUT_OFF; 802 803 spin_unlock_irqrestore(&vfe->output_lock, flags); 804 return 0; 805 } 806 807 static int vfe_disable_output(struct vfe_line *line) 808 { 809 struct vfe_device *vfe = to_vfe(line); 810 struct vfe_output *output = &line->output; 811 unsigned long flags; 812 unsigned int i; 813 814 spin_lock_irqsave(&vfe->output_lock, flags); 815 for (i = 0; i < output->wm_num; i++) 816 vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]); 817 output->gen2.active_num = 0; 818 spin_unlock_irqrestore(&vfe->output_lock, flags); 819 820 return vfe_reset(vfe); 821 } 822 823 /* 824 * vfe_disable - Disable streaming on VFE line 825 * @line: VFE line 826 * 827 * Return 0 on success or a negative error code otherwise 828 */ 829 int vfe_disable(struct vfe_line *line) 830 { 831 struct vfe_device *vfe = to_vfe(line); 832 int ret; 833 834 ret = vfe_disable_output(line); 835 if (ret) 836 goto error; 837 838 vfe_put_output(line); 839 840 mutex_lock(&vfe->stream_lock); 841 842 vfe->stream_count--; 843 844 mutex_unlock(&vfe->stream_lock); 845 846 error: 847 return ret; 848 } 849 850 /** 851 * vfe_isr_comp_done() - Process composite image done interrupt 852 * @vfe: VFE Device 853 * @comp: Composite image id 854 */ 855 void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp) 856 { 857 unsigned int i; 858 859 for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) 860 if (vfe->wm_output_map[i] == VFE_LINE_PIX) { 861 vfe->isr_ops.wm_done(vfe, i); 862 break; 863 } 864 } 865 866 void vfe_isr_reset_ack(struct vfe_device *vfe) 867 { 868 complete(&vfe->reset_complete); 869 } 870 871 /* 872 * vfe_pm_domain_off - Disable power domains specific to this VFE. 873 * @vfe: VFE Device 874 */ 875 void vfe_pm_domain_off(struct vfe_device *vfe) 876 { 877 if (!vfe->genpd) 878 return; 879 880 device_link_del(vfe->genpd_link); 881 vfe->genpd_link = NULL; 882 } 883 884 /* 885 * vfe_pm_domain_on - Enable power domains specific to this VFE. 886 * @vfe: VFE Device 887 */ 888 int vfe_pm_domain_on(struct vfe_device *vfe) 889 { 890 struct camss *camss = vfe->camss; 891 892 if (!vfe->genpd) 893 return 0; 894 895 vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, 896 DL_FLAG_STATELESS | 897 DL_FLAG_PM_RUNTIME | 898 DL_FLAG_RPM_ACTIVE); 899 if (!vfe->genpd_link) 900 return -EINVAL; 901 902 return 0; 903 } 904 905 static int vfe_match_clock_names(struct vfe_device *vfe, 906 struct camss_clock *clock) 907 { 908 char vfe_name[7]; /* vfeXXX\0 */ 909 char vfe_lite_name[12]; /* vfe_liteXXX\0 */ 910 911 snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id); 912 snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id); 913 914 return (!strcmp(clock->name, vfe_name) || 915 !strcmp(clock->name, vfe_lite_name) || 916 !strcmp(clock->name, "vfe_lite") || 917 !strcmp(clock->name, "camnoc_axi")); 918 } 919 920 /* 921 * vfe_check_clock_levels - Calculate and set clock rates on VFE module 922 * @clock: clocks data 923 * 924 * Return false if there is no non-zero clock level and true otherwise. 925 */ 926 static bool vfe_check_clock_levels(struct camss_clock *clock) 927 { 928 int i; 929 930 for (i = 0; i < clock->nfreqs; i++) 931 if (clock->freq[i]) 932 return true; 933 return false; 934 } 935 936 /* 937 * vfe_set_clock_rates - Calculate and set clock rates on VFE module 938 * @vfe: VFE device 939 * 940 * Return 0 on success or a negative error code otherwise 941 */ 942 static int vfe_set_clock_rates(struct vfe_device *vfe) 943 { 944 struct device *dev = vfe->camss->dev; 945 u64 pixel_clock[VFE_LINE_NUM_MAX]; 946 int i, j; 947 int ret; 948 949 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { 950 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, 951 &pixel_clock[i]); 952 if (ret) 953 pixel_clock[i] = 0; 954 } 955 956 for (i = 0; i < vfe->nclocks; i++) { 957 struct camss_clock *clock = &vfe->clock[i]; 958 959 if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) { 960 u64 min_rate = 0; 961 long rate; 962 963 for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) { 964 u32 tmp; 965 u8 bpp; 966 967 if (j == VFE_LINE_PIX) { 968 tmp = pixel_clock[j]; 969 } else { 970 struct vfe_line *l = &vfe->line[j]; 971 972 bpp = camss_format_get_bpp(l->formats, 973 l->nformats, 974 l->fmt[MSM_VFE_PAD_SINK].code); 975 tmp = pixel_clock[j] * bpp / 64; 976 } 977 978 if (min_rate < tmp) 979 min_rate = tmp; 980 } 981 982 camss_add_clock_margin(&min_rate); 983 984 for (j = 0; j < clock->nfreqs; j++) 985 if (min_rate < clock->freq[j]) 986 break; 987 988 if (j == clock->nfreqs) { 989 dev_err(dev, 990 "Pixel clock is too high for VFE"); 991 return -EINVAL; 992 } 993 994 /* if sensor pixel clock is not available */ 995 /* set highest possible VFE clock rate */ 996 if (min_rate == 0) 997 j = clock->nfreqs - 1; 998 999 rate = clk_round_rate(clock->clk, clock->freq[j]); 1000 if (rate < 0) { 1001 dev_err(dev, "clk round rate failed: %ld\n", 1002 rate); 1003 return -EINVAL; 1004 } 1005 1006 ret = clk_set_rate(clock->clk, rate); 1007 if (ret < 0) { 1008 dev_err(dev, "clk set rate failed: %d\n", ret); 1009 return ret; 1010 } 1011 } 1012 } 1013 1014 return 0; 1015 } 1016 1017 /* 1018 * vfe_check_clock_rates - Check current clock rates on VFE module 1019 * @vfe: VFE device 1020 * 1021 * Return 0 if current clock rates are suitable for a new pipeline 1022 * or a negative error code otherwise 1023 */ 1024 static int vfe_check_clock_rates(struct vfe_device *vfe) 1025 { 1026 u64 pixel_clock[VFE_LINE_NUM_MAX]; 1027 int i, j; 1028 int ret; 1029 1030 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { 1031 ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, 1032 &pixel_clock[i]); 1033 if (ret) 1034 pixel_clock[i] = 0; 1035 } 1036 1037 for (i = 0; i < vfe->nclocks; i++) { 1038 struct camss_clock *clock = &vfe->clock[i]; 1039 1040 if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) { 1041 u64 min_rate = 0; 1042 unsigned long rate; 1043 1044 for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) { 1045 u32 tmp; 1046 u8 bpp; 1047 1048 if (j == VFE_LINE_PIX) { 1049 tmp = pixel_clock[j]; 1050 } else { 1051 struct vfe_line *l = &vfe->line[j]; 1052 1053 bpp = camss_format_get_bpp(l->formats, 1054 l->nformats, 1055 l->fmt[MSM_VFE_PAD_SINK].code); 1056 tmp = pixel_clock[j] * bpp / 64; 1057 } 1058 1059 if (min_rate < tmp) 1060 min_rate = tmp; 1061 } 1062 1063 camss_add_clock_margin(&min_rate); 1064 1065 rate = clk_get_rate(clock->clk); 1066 if (rate < min_rate) 1067 return -EBUSY; 1068 } 1069 } 1070 1071 return 0; 1072 } 1073 1074 /* 1075 * vfe_get - Power up and reset VFE module 1076 * @vfe: VFE Device 1077 * 1078 * Return 0 on success or a negative error code otherwise 1079 */ 1080 int vfe_get(struct vfe_device *vfe) 1081 { 1082 int ret; 1083 1084 mutex_lock(&vfe->power_lock); 1085 1086 if (vfe->power_count == 0) { 1087 ret = vfe->res->hw_ops->pm_domain_on(vfe); 1088 if (ret < 0) 1089 goto error_pm_domain; 1090 1091 ret = pm_runtime_resume_and_get(vfe->camss->dev); 1092 if (ret < 0) 1093 goto error_domain_off; 1094 1095 ret = vfe_set_clock_rates(vfe); 1096 if (ret < 0) 1097 goto error_pm_runtime_get; 1098 1099 ret = camss_enable_clocks(vfe->nclocks, vfe->clock, 1100 vfe->camss->dev); 1101 if (ret < 0) 1102 goto error_pm_runtime_get; 1103 1104 ret = vfe_reset(vfe); 1105 if (ret < 0) 1106 goto error_reset; 1107 1108 vfe_reset_output_maps(vfe); 1109 1110 vfe_init_outputs(vfe); 1111 1112 vfe->res->hw_ops->hw_version(vfe); 1113 } else { 1114 ret = vfe_check_clock_rates(vfe); 1115 if (ret < 0) 1116 goto error_pm_domain; 1117 } 1118 vfe->power_count++; 1119 1120 mutex_unlock(&vfe->power_lock); 1121 1122 return 0; 1123 1124 error_reset: 1125 camss_disable_clocks(vfe->nclocks, vfe->clock); 1126 1127 error_pm_runtime_get: 1128 pm_runtime_put_sync(vfe->camss->dev); 1129 error_domain_off: 1130 vfe->res->hw_ops->pm_domain_off(vfe); 1131 1132 error_pm_domain: 1133 mutex_unlock(&vfe->power_lock); 1134 1135 return ret; 1136 } 1137 1138 /* 1139 * vfe_put - Power down VFE module 1140 * @vfe: VFE Device 1141 */ 1142 void vfe_put(struct vfe_device *vfe) 1143 { 1144 mutex_lock(&vfe->power_lock); 1145 1146 if (vfe->power_count == 0) { 1147 dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n"); 1148 goto exit; 1149 } else if (vfe->power_count == 1) { 1150 if (vfe->was_streaming) { 1151 vfe->was_streaming = 0; 1152 vfe->res->hw_ops->vfe_halt(vfe); 1153 } 1154 camss_disable_clocks(vfe->nclocks, vfe->clock); 1155 pm_runtime_put_sync(vfe->camss->dev); 1156 vfe->res->hw_ops->pm_domain_off(vfe); 1157 } 1158 1159 vfe->power_count--; 1160 1161 exit: 1162 mutex_unlock(&vfe->power_lock); 1163 } 1164 1165 /* 1166 * vfe_flush_buffers - Return all vb2 buffers 1167 * @vid: Video device structure 1168 * @state: vb2 buffer state of the returned buffers 1169 * 1170 * Return all buffers to vb2. This includes queued pending buffers (still 1171 * unused) and any buffers given to the hardware but again still not used. 1172 * 1173 * Return 0 on success or a negative error code otherwise 1174 */ 1175 int vfe_flush_buffers(struct camss_video *vid, 1176 enum vb2_buffer_state state) 1177 { 1178 struct vfe_line *line = container_of(vid, struct vfe_line, video_out); 1179 struct vfe_device *vfe = to_vfe(line); 1180 struct vfe_output *output; 1181 unsigned long flags; 1182 1183 output = &line->output; 1184 1185 spin_lock_irqsave(&vfe->output_lock, flags); 1186 1187 vfe_buf_flush_pending(output, state); 1188 1189 if (output->buf[0]) 1190 vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); 1191 1192 if (output->buf[1]) 1193 vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); 1194 1195 if (output->last_buffer) { 1196 vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); 1197 output->last_buffer = NULL; 1198 } 1199 1200 spin_unlock_irqrestore(&vfe->output_lock, flags); 1201 1202 return 0; 1203 } 1204 1205 /* 1206 * vfe_set_power - Power on/off VFE module 1207 * @sd: VFE V4L2 subdevice 1208 * @on: Requested power state 1209 * 1210 * Return 0 on success or a negative error code otherwise 1211 */ 1212 static int vfe_set_power(struct v4l2_subdev *sd, int on) 1213 { 1214 struct vfe_line *line = v4l2_get_subdevdata(sd); 1215 struct vfe_device *vfe = to_vfe(line); 1216 int ret; 1217 1218 if (on) { 1219 ret = vfe_get(vfe); 1220 if (ret < 0) 1221 return ret; 1222 } else { 1223 vfe_put(vfe); 1224 } 1225 1226 return 0; 1227 } 1228 1229 /* 1230 * vfe_set_stream - Enable/disable streaming on VFE module 1231 * @sd: VFE V4L2 subdevice 1232 * @enable: Requested streaming state 1233 * 1234 * Main configuration of VFE module is triggered here. 1235 * 1236 * Return 0 on success or a negative error code otherwise 1237 */ 1238 static int vfe_set_stream(struct v4l2_subdev *sd, int enable) 1239 { 1240 struct vfe_line *line = v4l2_get_subdevdata(sd); 1241 struct vfe_device *vfe = to_vfe(line); 1242 int ret; 1243 1244 if (enable) { 1245 line->output.state = VFE_OUTPUT_RESERVED; 1246 ret = vfe->res->hw_ops->vfe_enable(line); 1247 if (ret < 0) 1248 dev_err(vfe->camss->dev, 1249 "Failed to enable vfe outputs\n"); 1250 } else { 1251 ret = vfe->res->hw_ops->vfe_disable(line); 1252 if (ret < 0) 1253 dev_err(vfe->camss->dev, 1254 "Failed to disable vfe outputs\n"); 1255 } 1256 1257 return ret; 1258 } 1259 1260 /* 1261 * __vfe_get_format - Get pointer to format structure 1262 * @line: VFE line 1263 * @sd_state: V4L2 subdev state 1264 * @pad: pad from which format is requested 1265 * @which: TRY or ACTIVE format 1266 * 1267 * Return pointer to TRY or ACTIVE format structure 1268 */ 1269 static struct v4l2_mbus_framefmt * 1270 __vfe_get_format(struct vfe_line *line, 1271 struct v4l2_subdev_state *sd_state, 1272 unsigned int pad, 1273 enum v4l2_subdev_format_whence which) 1274 { 1275 if (which == V4L2_SUBDEV_FORMAT_TRY) 1276 return v4l2_subdev_state_get_format(sd_state, pad); 1277 1278 return &line->fmt[pad]; 1279 } 1280 1281 /* 1282 * __vfe_get_compose - Get pointer to compose selection structure 1283 * @line: VFE line 1284 * @sd_state: V4L2 subdev state 1285 * @which: TRY or ACTIVE format 1286 * 1287 * Return pointer to TRY or ACTIVE compose rectangle structure 1288 */ 1289 static struct v4l2_rect * 1290 __vfe_get_compose(struct vfe_line *line, 1291 struct v4l2_subdev_state *sd_state, 1292 enum v4l2_subdev_format_whence which) 1293 { 1294 if (which == V4L2_SUBDEV_FORMAT_TRY) 1295 return v4l2_subdev_state_get_compose(sd_state, 1296 MSM_VFE_PAD_SINK); 1297 1298 return &line->compose; 1299 } 1300 1301 /* 1302 * __vfe_get_crop - Get pointer to crop selection structure 1303 * @line: VFE line 1304 * @sd_state: V4L2 subdev state 1305 * @which: TRY or ACTIVE format 1306 * 1307 * Return pointer to TRY or ACTIVE crop rectangle structure 1308 */ 1309 static struct v4l2_rect * 1310 __vfe_get_crop(struct vfe_line *line, 1311 struct v4l2_subdev_state *sd_state, 1312 enum v4l2_subdev_format_whence which) 1313 { 1314 if (which == V4L2_SUBDEV_FORMAT_TRY) 1315 return v4l2_subdev_state_get_crop(sd_state, MSM_VFE_PAD_SRC); 1316 1317 return &line->crop; 1318 } 1319 1320 /* 1321 * vfe_try_format - Handle try format by pad subdev method 1322 * @line: VFE line 1323 * @sd_state: V4L2 subdev state 1324 * @pad: pad on which format is requested 1325 * @fmt: pointer to v4l2 format structure 1326 * @which: wanted subdev format 1327 */ 1328 static void vfe_try_format(struct vfe_line *line, 1329 struct v4l2_subdev_state *sd_state, 1330 unsigned int pad, 1331 struct v4l2_mbus_framefmt *fmt, 1332 enum v4l2_subdev_format_whence which) 1333 { 1334 unsigned int i; 1335 u32 code; 1336 1337 switch (pad) { 1338 case MSM_VFE_PAD_SINK: 1339 /* Set format on sink pad */ 1340 1341 for (i = 0; i < line->nformats; i++) 1342 if (fmt->code == line->formats[i].code) 1343 break; 1344 1345 /* If not found, use UYVY as default */ 1346 if (i >= line->nformats) 1347 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; 1348 1349 fmt->width = clamp_t(u32, fmt->width, 1, 8191); 1350 fmt->height = clamp_t(u32, fmt->height, 1, 8191); 1351 1352 fmt->field = V4L2_FIELD_NONE; 1353 fmt->colorspace = V4L2_COLORSPACE_SRGB; 1354 1355 break; 1356 1357 case MSM_VFE_PAD_SRC: 1358 /* Set and return a format same as sink pad */ 1359 code = fmt->code; 1360 1361 *fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, 1362 which); 1363 1364 fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); 1365 1366 if (line->id == VFE_LINE_PIX) { 1367 struct v4l2_rect *rect; 1368 1369 rect = __vfe_get_crop(line, sd_state, which); 1370 1371 fmt->width = rect->width; 1372 fmt->height = rect->height; 1373 } 1374 1375 break; 1376 } 1377 1378 fmt->colorspace = V4L2_COLORSPACE_SRGB; 1379 } 1380 1381 /* 1382 * vfe_try_compose - Handle try compose selection by pad subdev method 1383 * @line: VFE line 1384 * @sd_state: V4L2 subdev state 1385 * @rect: pointer to v4l2 rect structure 1386 * @which: wanted subdev format 1387 */ 1388 static void vfe_try_compose(struct vfe_line *line, 1389 struct v4l2_subdev_state *sd_state, 1390 struct v4l2_rect *rect, 1391 enum v4l2_subdev_format_whence which) 1392 { 1393 struct v4l2_mbus_framefmt *fmt; 1394 1395 fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which); 1396 1397 if (rect->width > fmt->width) 1398 rect->width = fmt->width; 1399 1400 if (rect->height > fmt->height) 1401 rect->height = fmt->height; 1402 1403 if (fmt->width > rect->width * SCALER_RATIO_MAX) 1404 rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / 1405 SCALER_RATIO_MAX; 1406 1407 rect->width &= ~0x1; 1408 1409 if (fmt->height > rect->height * SCALER_RATIO_MAX) 1410 rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / 1411 SCALER_RATIO_MAX; 1412 1413 if (rect->width < 16) 1414 rect->width = 16; 1415 1416 if (rect->height < 4) 1417 rect->height = 4; 1418 } 1419 1420 /* 1421 * vfe_try_crop - Handle try crop selection by pad subdev method 1422 * @line: VFE line 1423 * @sd_state: V4L2 subdev state 1424 * @rect: pointer to v4l2 rect structure 1425 * @which: wanted subdev format 1426 */ 1427 static void vfe_try_crop(struct vfe_line *line, 1428 struct v4l2_subdev_state *sd_state, 1429 struct v4l2_rect *rect, 1430 enum v4l2_subdev_format_whence which) 1431 { 1432 struct v4l2_rect *compose; 1433 1434 compose = __vfe_get_compose(line, sd_state, which); 1435 1436 if (rect->width > compose->width) 1437 rect->width = compose->width; 1438 1439 if (rect->width + rect->left > compose->width) 1440 rect->left = compose->width - rect->width; 1441 1442 if (rect->height > compose->height) 1443 rect->height = compose->height; 1444 1445 if (rect->height + rect->top > compose->height) 1446 rect->top = compose->height - rect->height; 1447 1448 /* wm in line based mode writes multiple of 16 horizontally */ 1449 rect->left += (rect->width & 0xf) >> 1; 1450 rect->width &= ~0xf; 1451 1452 if (rect->width < 16) { 1453 rect->left = 0; 1454 rect->width = 16; 1455 } 1456 1457 if (rect->height < 4) { 1458 rect->top = 0; 1459 rect->height = 4; 1460 } 1461 } 1462 1463 /* 1464 * vfe_enum_mbus_code - Handle pixel format enumeration 1465 * @sd: VFE V4L2 subdevice 1466 * @sd_state: V4L2 subdev state 1467 * @code: pointer to v4l2_subdev_mbus_code_enum structure 1468 * 1469 * return -EINVAL or zero on success 1470 */ 1471 static int vfe_enum_mbus_code(struct v4l2_subdev *sd, 1472 struct v4l2_subdev_state *sd_state, 1473 struct v4l2_subdev_mbus_code_enum *code) 1474 { 1475 struct vfe_line *line = v4l2_get_subdevdata(sd); 1476 1477 if (code->pad == MSM_VFE_PAD_SINK) { 1478 if (code->index >= line->nformats) 1479 return -EINVAL; 1480 1481 code->code = line->formats[code->index].code; 1482 } else { 1483 struct v4l2_mbus_framefmt *sink_fmt; 1484 1485 sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, 1486 code->which); 1487 1488 code->code = vfe_src_pad_code(line, sink_fmt->code, 1489 code->index, 0); 1490 if (!code->code) 1491 return -EINVAL; 1492 } 1493 1494 return 0; 1495 } 1496 1497 /* 1498 * vfe_enum_frame_size - Handle frame size enumeration 1499 * @sd: VFE V4L2 subdevice 1500 * @sd_state: V4L2 subdev state 1501 * @fse: pointer to v4l2_subdev_frame_size_enum structure 1502 * 1503 * Return -EINVAL or zero on success 1504 */ 1505 static int vfe_enum_frame_size(struct v4l2_subdev *sd, 1506 struct v4l2_subdev_state *sd_state, 1507 struct v4l2_subdev_frame_size_enum *fse) 1508 { 1509 struct vfe_line *line = v4l2_get_subdevdata(sd); 1510 struct v4l2_mbus_framefmt format; 1511 1512 if (fse->index != 0) 1513 return -EINVAL; 1514 1515 format.code = fse->code; 1516 format.width = 1; 1517 format.height = 1; 1518 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); 1519 fse->min_width = format.width; 1520 fse->min_height = format.height; 1521 1522 if (format.code != fse->code) 1523 return -EINVAL; 1524 1525 format.code = fse->code; 1526 format.width = -1; 1527 format.height = -1; 1528 vfe_try_format(line, sd_state, fse->pad, &format, fse->which); 1529 fse->max_width = format.width; 1530 fse->max_height = format.height; 1531 1532 return 0; 1533 } 1534 1535 /* 1536 * vfe_get_format - Handle get format by pads subdev method 1537 * @sd: VFE V4L2 subdevice 1538 * @sd_state: V4L2 subdev state 1539 * @fmt: pointer to v4l2 subdev format structure 1540 * 1541 * Return -EINVAL or zero on success 1542 */ 1543 static int vfe_get_format(struct v4l2_subdev *sd, 1544 struct v4l2_subdev_state *sd_state, 1545 struct v4l2_subdev_format *fmt) 1546 { 1547 struct vfe_line *line = v4l2_get_subdevdata(sd); 1548 struct v4l2_mbus_framefmt *format; 1549 1550 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); 1551 if (format == NULL) 1552 return -EINVAL; 1553 1554 fmt->format = *format; 1555 1556 return 0; 1557 } 1558 1559 static int vfe_set_selection(struct v4l2_subdev *sd, 1560 struct v4l2_subdev_state *sd_state, 1561 struct v4l2_subdev_selection *sel); 1562 1563 /* 1564 * vfe_set_format - Handle set format by pads subdev method 1565 * @sd: VFE V4L2 subdevice 1566 * @sd_state: V4L2 subdev state 1567 * @fmt: pointer to v4l2 subdev format structure 1568 * 1569 * Return -EINVAL or zero on success 1570 */ 1571 static int vfe_set_format(struct v4l2_subdev *sd, 1572 struct v4l2_subdev_state *sd_state, 1573 struct v4l2_subdev_format *fmt) 1574 { 1575 struct vfe_line *line = v4l2_get_subdevdata(sd); 1576 struct v4l2_mbus_framefmt *format; 1577 1578 format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); 1579 if (format == NULL) 1580 return -EINVAL; 1581 1582 vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); 1583 *format = fmt->format; 1584 1585 if (fmt->pad == MSM_VFE_PAD_SINK) { 1586 struct v4l2_subdev_selection sel = { 0 }; 1587 int ret; 1588 1589 /* Propagate the format from sink to source */ 1590 format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC, 1591 fmt->which); 1592 1593 *format = fmt->format; 1594 vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format, 1595 fmt->which); 1596 1597 if (line->id != VFE_LINE_PIX) 1598 return 0; 1599 1600 /* Reset sink pad compose selection */ 1601 sel.which = fmt->which; 1602 sel.pad = MSM_VFE_PAD_SINK; 1603 sel.target = V4L2_SEL_TGT_COMPOSE; 1604 sel.r.width = fmt->format.width; 1605 sel.r.height = fmt->format.height; 1606 ret = vfe_set_selection(sd, sd_state, &sel); 1607 if (ret < 0) 1608 return ret; 1609 } 1610 1611 return 0; 1612 } 1613 1614 /* 1615 * vfe_get_selection - Handle get selection by pads subdev method 1616 * @sd: VFE V4L2 subdevice 1617 * @sd_state: V4L2 subdev state 1618 * @sel: pointer to v4l2 subdev selection structure 1619 * 1620 * Return -EINVAL or zero on success 1621 */ 1622 static int vfe_get_selection(struct v4l2_subdev *sd, 1623 struct v4l2_subdev_state *sd_state, 1624 struct v4l2_subdev_selection *sel) 1625 { 1626 struct vfe_line *line = v4l2_get_subdevdata(sd); 1627 struct v4l2_subdev_format fmt = { 0 }; 1628 struct v4l2_rect *rect; 1629 int ret; 1630 1631 if (line->id != VFE_LINE_PIX) 1632 return -EINVAL; 1633 1634 if (sel->pad == MSM_VFE_PAD_SINK) 1635 switch (sel->target) { 1636 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 1637 fmt.pad = sel->pad; 1638 fmt.which = sel->which; 1639 ret = vfe_get_format(sd, sd_state, &fmt); 1640 if (ret < 0) 1641 return ret; 1642 1643 sel->r.left = 0; 1644 sel->r.top = 0; 1645 sel->r.width = fmt.format.width; 1646 sel->r.height = fmt.format.height; 1647 break; 1648 case V4L2_SEL_TGT_COMPOSE: 1649 rect = __vfe_get_compose(line, sd_state, sel->which); 1650 if (rect == NULL) 1651 return -EINVAL; 1652 1653 sel->r = *rect; 1654 break; 1655 default: 1656 return -EINVAL; 1657 } 1658 else if (sel->pad == MSM_VFE_PAD_SRC) 1659 switch (sel->target) { 1660 case V4L2_SEL_TGT_CROP_BOUNDS: 1661 rect = __vfe_get_compose(line, sd_state, sel->which); 1662 if (rect == NULL) 1663 return -EINVAL; 1664 1665 sel->r.left = rect->left; 1666 sel->r.top = rect->top; 1667 sel->r.width = rect->width; 1668 sel->r.height = rect->height; 1669 break; 1670 case V4L2_SEL_TGT_CROP: 1671 rect = __vfe_get_crop(line, sd_state, sel->which); 1672 if (rect == NULL) 1673 return -EINVAL; 1674 1675 sel->r = *rect; 1676 break; 1677 default: 1678 return -EINVAL; 1679 } 1680 1681 return 0; 1682 } 1683 1684 /* 1685 * vfe_set_selection - Handle set selection by pads subdev method 1686 * @sd: VFE V4L2 subdevice 1687 * @sd_state: V4L2 subdev state 1688 * @sel: pointer to v4l2 subdev selection structure 1689 * 1690 * Return -EINVAL or zero on success 1691 */ 1692 static int vfe_set_selection(struct v4l2_subdev *sd, 1693 struct v4l2_subdev_state *sd_state, 1694 struct v4l2_subdev_selection *sel) 1695 { 1696 struct vfe_line *line = v4l2_get_subdevdata(sd); 1697 struct v4l2_rect *rect; 1698 int ret; 1699 1700 if (line->id != VFE_LINE_PIX) 1701 return -EINVAL; 1702 1703 if (sel->target == V4L2_SEL_TGT_COMPOSE && 1704 sel->pad == MSM_VFE_PAD_SINK) { 1705 struct v4l2_subdev_selection crop = { 0 }; 1706 1707 rect = __vfe_get_compose(line, sd_state, sel->which); 1708 if (rect == NULL) 1709 return -EINVAL; 1710 1711 vfe_try_compose(line, sd_state, &sel->r, sel->which); 1712 *rect = sel->r; 1713 1714 /* Reset source crop selection */ 1715 crop.which = sel->which; 1716 crop.pad = MSM_VFE_PAD_SRC; 1717 crop.target = V4L2_SEL_TGT_CROP; 1718 crop.r = *rect; 1719 ret = vfe_set_selection(sd, sd_state, &crop); 1720 } else if (sel->target == V4L2_SEL_TGT_CROP && 1721 sel->pad == MSM_VFE_PAD_SRC) { 1722 struct v4l2_subdev_format fmt = { 0 }; 1723 1724 rect = __vfe_get_crop(line, sd_state, sel->which); 1725 if (rect == NULL) 1726 return -EINVAL; 1727 1728 vfe_try_crop(line, sd_state, &sel->r, sel->which); 1729 *rect = sel->r; 1730 1731 /* Reset source pad format width and height */ 1732 fmt.which = sel->which; 1733 fmt.pad = MSM_VFE_PAD_SRC; 1734 ret = vfe_get_format(sd, sd_state, &fmt); 1735 if (ret < 0) 1736 return ret; 1737 1738 fmt.format.width = rect->width; 1739 fmt.format.height = rect->height; 1740 ret = vfe_set_format(sd, sd_state, &fmt); 1741 } else { 1742 ret = -EINVAL; 1743 } 1744 1745 return ret; 1746 } 1747 1748 /* 1749 * vfe_init_formats - Initialize formats on all pads 1750 * @sd: VFE V4L2 subdevice 1751 * @fh: V4L2 subdev file handle 1752 * 1753 * Initialize all pad formats with default values. 1754 * 1755 * Return 0 on success or a negative error code otherwise 1756 */ 1757 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 1758 { 1759 struct v4l2_subdev_format format = { 1760 .pad = MSM_VFE_PAD_SINK, 1761 .which = fh ? V4L2_SUBDEV_FORMAT_TRY : 1762 V4L2_SUBDEV_FORMAT_ACTIVE, 1763 .format = { 1764 .code = MEDIA_BUS_FMT_UYVY8_1X16, 1765 .width = 1920, 1766 .height = 1080 1767 } 1768 }; 1769 1770 return vfe_set_format(sd, fh ? fh->state : NULL, &format); 1771 } 1772 1773 /* 1774 * msm_vfe_subdev_init - Initialize VFE device structure and resources 1775 * @vfe: VFE device 1776 * @res: VFE module resources table 1777 * 1778 * Return 0 on success or a negative error code otherwise 1779 */ 1780 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, 1781 const struct camss_subdev_resources *res, u8 id) 1782 { 1783 struct device *dev = camss->dev; 1784 struct platform_device *pdev = to_platform_device(dev); 1785 int i, j; 1786 int ret; 1787 1788 if (!res->vfe.line_num) 1789 return -EINVAL; 1790 1791 vfe->res = &res->vfe; 1792 vfe->res->hw_ops->subdev_init(dev, vfe); 1793 1794 /* Power domain */ 1795 1796 if (res->vfe.pd_name) { 1797 vfe->genpd = dev_pm_domain_attach_by_name(camss->dev, 1798 res->vfe.pd_name); 1799 if (IS_ERR(vfe->genpd)) { 1800 ret = PTR_ERR(vfe->genpd); 1801 return ret; 1802 } 1803 } 1804 1805 if (!vfe->genpd && res->vfe.has_pd) { 1806 /* 1807 * Legacy magic index. 1808 * Requires 1809 * power-domain = <VFE_X>, 1810 * <VFE_Y>, 1811 * <TITAN_TOP> 1812 * id must correspondng to the index of the VFE which must 1813 * come before the TOP GDSC. VFE Lite has no individually 1814 * collapasible domain which is why id < vfe_num is a valid 1815 * check. 1816 */ 1817 vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id); 1818 if (IS_ERR(vfe->genpd)) 1819 return PTR_ERR(vfe->genpd); 1820 } 1821 1822 /* Memory */ 1823 1824 vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); 1825 if (IS_ERR(vfe->base)) { 1826 dev_err(dev, "could not map memory\n"); 1827 return PTR_ERR(vfe->base); 1828 } 1829 1830 /* Interrupt */ 1831 1832 ret = platform_get_irq_byname(pdev, res->interrupt[0]); 1833 if (ret < 0) 1834 return ret; 1835 1836 vfe->irq = ret; 1837 snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", 1838 dev_name(dev), MSM_VFE_NAME, id); 1839 ret = devm_request_irq(dev, vfe->irq, vfe->res->hw_ops->isr, 1840 IRQF_TRIGGER_RISING, vfe->irq_name, vfe); 1841 if (ret < 0) { 1842 dev_err(dev, "request_irq failed: %d\n", ret); 1843 return ret; 1844 } 1845 1846 /* Clocks */ 1847 1848 vfe->nclocks = 0; 1849 while (res->clock[vfe->nclocks]) 1850 vfe->nclocks++; 1851 1852 vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), 1853 GFP_KERNEL); 1854 if (!vfe->clock) 1855 return -ENOMEM; 1856 1857 for (i = 0; i < vfe->nclocks; i++) { 1858 struct camss_clock *clock = &vfe->clock[i]; 1859 1860 clock->clk = devm_clk_get(dev, res->clock[i]); 1861 if (IS_ERR(clock->clk)) 1862 return PTR_ERR(clock->clk); 1863 1864 clock->name = res->clock[i]; 1865 1866 clock->nfreqs = 0; 1867 while (res->clock_rate[i][clock->nfreqs]) 1868 clock->nfreqs++; 1869 1870 if (!clock->nfreqs) { 1871 clock->freq = NULL; 1872 continue; 1873 } 1874 1875 clock->freq = devm_kcalloc(dev, 1876 clock->nfreqs, 1877 sizeof(*clock->freq), 1878 GFP_KERNEL); 1879 if (!clock->freq) 1880 return -ENOMEM; 1881 1882 for (j = 0; j < clock->nfreqs; j++) 1883 clock->freq[j] = res->clock_rate[i][j]; 1884 } 1885 1886 mutex_init(&vfe->power_lock); 1887 vfe->power_count = 0; 1888 1889 mutex_init(&vfe->stream_lock); 1890 vfe->stream_count = 0; 1891 1892 spin_lock_init(&vfe->output_lock); 1893 1894 vfe->camss = camss; 1895 vfe->id = id; 1896 vfe->reg_update = 0; 1897 1898 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) { 1899 struct vfe_line *l = &vfe->line[i]; 1900 1901 l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1902 l->video_out.camss = camss; 1903 l->id = i; 1904 init_completion(&l->output.sof); 1905 init_completion(&l->output.reg_update); 1906 1907 if (i == VFE_LINE_PIX) { 1908 l->nformats = res->vfe.formats_pix->nformats; 1909 l->formats = res->vfe.formats_pix->formats; 1910 } else { 1911 l->nformats = res->vfe.formats_rdi->nformats; 1912 l->formats = res->vfe.formats_rdi->formats; 1913 } 1914 } 1915 1916 init_completion(&vfe->reset_complete); 1917 init_completion(&vfe->halt_complete); 1918 1919 return 0; 1920 } 1921 1922 /* 1923 * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages 1924 * @vfe: VFE device 1925 */ 1926 void msm_vfe_genpd_cleanup(struct vfe_device *vfe) 1927 { 1928 if (vfe->genpd_link) 1929 device_link_del(vfe->genpd_link); 1930 1931 if (vfe->genpd) 1932 dev_pm_domain_detach(vfe->genpd, true); 1933 } 1934 1935 /* 1936 * vfe_link_setup - Setup VFE connections 1937 * @entity: Pointer to media entity structure 1938 * @local: Pointer to local pad 1939 * @remote: Pointer to remote pad 1940 * @flags: Link flags 1941 * 1942 * Return 0 on success 1943 */ 1944 static int vfe_link_setup(struct media_entity *entity, 1945 const struct media_pad *local, 1946 const struct media_pad *remote, u32 flags) 1947 { 1948 if (flags & MEDIA_LNK_FL_ENABLED) 1949 if (media_pad_remote_pad_first(local)) 1950 return -EBUSY; 1951 1952 return 0; 1953 } 1954 1955 static const struct v4l2_subdev_core_ops vfe_core_ops = { 1956 .s_power = vfe_set_power, 1957 }; 1958 1959 static const struct v4l2_subdev_video_ops vfe_video_ops = { 1960 .s_stream = vfe_set_stream, 1961 }; 1962 1963 static const struct v4l2_subdev_pad_ops vfe_pad_ops = { 1964 .enum_mbus_code = vfe_enum_mbus_code, 1965 .enum_frame_size = vfe_enum_frame_size, 1966 .get_fmt = vfe_get_format, 1967 .set_fmt = vfe_set_format, 1968 .get_selection = vfe_get_selection, 1969 .set_selection = vfe_set_selection, 1970 }; 1971 1972 static const struct v4l2_subdev_ops vfe_v4l2_ops = { 1973 .core = &vfe_core_ops, 1974 .video = &vfe_video_ops, 1975 .pad = &vfe_pad_ops, 1976 }; 1977 1978 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = { 1979 .open = vfe_init_formats, 1980 }; 1981 1982 static const struct media_entity_operations vfe_media_ops = { 1983 .link_setup = vfe_link_setup, 1984 .link_validate = v4l2_subdev_link_validate, 1985 }; 1986 1987 static int vfe_bpl_align(struct vfe_device *vfe) 1988 { 1989 int ret = 8; 1990 1991 switch (vfe->camss->res->version) { 1992 case CAMSS_7280: 1993 case CAMSS_8250: 1994 case CAMSS_8280XP: 1995 case CAMSS_8300: 1996 case CAMSS_845: 1997 case CAMSS_8550: 1998 case CAMSS_8775P: 1999 case CAMSS_X1E80100: 2000 ret = 16; 2001 break; 2002 default: 2003 break; 2004 } 2005 2006 return ret; 2007 } 2008 2009 /* 2010 * msm_vfe_register_entities - Register subdev node for VFE module 2011 * @vfe: VFE device 2012 * @v4l2_dev: V4L2 device 2013 * 2014 * Initialize and register a subdev node for the VFE module. Then 2015 * call msm_video_register() to register the video device node which 2016 * will be connected to this subdev node. Then actually create the 2017 * media link between them. 2018 * 2019 * Return 0 on success or a negative error code otherwise 2020 */ 2021 int msm_vfe_register_entities(struct vfe_device *vfe, 2022 struct v4l2_device *v4l2_dev) 2023 { 2024 struct device *dev = vfe->camss->dev; 2025 struct v4l2_subdev *sd; 2026 struct media_pad *pads; 2027 struct camss_video *video_out; 2028 int ret; 2029 int i; 2030 2031 for (i = 0; i < vfe->res->line_num; i++) { 2032 char name[32]; 2033 2034 sd = &vfe->line[i].subdev; 2035 pads = vfe->line[i].pads; 2036 video_out = &vfe->line[i].video_out; 2037 2038 v4l2_subdev_init(sd, &vfe_v4l2_ops); 2039 sd->internal_ops = &vfe_v4l2_internal_ops; 2040 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 2041 if (i == VFE_LINE_PIX) 2042 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", 2043 MSM_VFE_NAME, vfe->id, "pix"); 2044 else 2045 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", 2046 MSM_VFE_NAME, vfe->id, "rdi", i); 2047 2048 v4l2_set_subdevdata(sd, &vfe->line[i]); 2049 2050 ret = vfe_init_formats(sd, NULL); 2051 if (ret < 0) { 2052 dev_err(dev, "Failed to init format: %d\n", ret); 2053 goto error_init; 2054 } 2055 2056 pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 2057 pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; 2058 2059 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; 2060 sd->entity.ops = &vfe_media_ops; 2061 ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, 2062 pads); 2063 if (ret < 0) { 2064 dev_err(dev, "Failed to init media entity: %d\n", ret); 2065 goto error_init; 2066 } 2067 2068 ret = v4l2_device_register_subdev(v4l2_dev, sd); 2069 if (ret < 0) { 2070 dev_err(dev, "Failed to register subdev: %d\n", ret); 2071 goto error_reg_subdev; 2072 } 2073 2074 video_out->ops = &vfe->video_ops; 2075 video_out->bpl_alignment = vfe_bpl_align(vfe); 2076 video_out->line_based = 0; 2077 if (i == VFE_LINE_PIX) { 2078 video_out->bpl_alignment = 16; 2079 video_out->line_based = 1; 2080 } 2081 2082 video_out->nformats = vfe->line[i].nformats; 2083 video_out->formats = vfe->line[i].formats; 2084 2085 snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d", 2086 MSM_VFE_NAME, vfe->id, "video", i); 2087 ret = msm_video_register(video_out, v4l2_dev, name); 2088 if (ret < 0) { 2089 dev_err(dev, "Failed to register video node: %d\n", 2090 ret); 2091 goto error_reg_video; 2092 } 2093 2094 ret = media_create_pad_link( 2095 &sd->entity, MSM_VFE_PAD_SRC, 2096 &video_out->vdev.entity, 0, 2097 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 2098 if (ret < 0) { 2099 dev_err(dev, "Failed to link %s->%s entities: %d\n", 2100 sd->entity.name, video_out->vdev.entity.name, 2101 ret); 2102 goto error_link; 2103 } 2104 } 2105 2106 return 0; 2107 2108 error_link: 2109 msm_video_unregister(video_out); 2110 2111 error_reg_video: 2112 v4l2_device_unregister_subdev(sd); 2113 2114 error_reg_subdev: 2115 media_entity_cleanup(&sd->entity); 2116 2117 error_init: 2118 for (i--; i >= 0; i--) { 2119 sd = &vfe->line[i].subdev; 2120 video_out = &vfe->line[i].video_out; 2121 2122 msm_video_unregister(video_out); 2123 v4l2_device_unregister_subdev(sd); 2124 media_entity_cleanup(&sd->entity); 2125 } 2126 2127 return ret; 2128 } 2129 2130 /* 2131 * msm_vfe_unregister_entities - Unregister VFE module subdev node 2132 * @vfe: VFE device 2133 */ 2134 void msm_vfe_unregister_entities(struct vfe_device *vfe) 2135 { 2136 int i; 2137 2138 mutex_destroy(&vfe->power_lock); 2139 mutex_destroy(&vfe->stream_lock); 2140 2141 for (i = 0; i < vfe->res->line_num; i++) { 2142 struct v4l2_subdev *sd = &vfe->line[i].subdev; 2143 struct camss_video *video_out = &vfe->line[i].video_out; 2144 2145 msm_video_unregister(video_out); 2146 v4l2_device_unregister_subdev(sd); 2147 media_entity_cleanup(&sd->entity); 2148 } 2149 } 2150 2151 bool vfe_is_lite(struct vfe_device *vfe) 2152 { 2153 return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite; 2154 } 2155