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