1 /* 2 * Support for Intel Camera Imaging ISP subsystem. 3 * Copyright (c) 2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 */ 14 15 #include "ia_css_vf.host.h" 16 #include <assert_support.h> 17 #include <ia_css_err.h> 18 #include <ia_css_frame.h> 19 #include <ia_css_frame_public.h> 20 #include <ia_css_pipeline.h> 21 #define IA_CSS_INCLUDE_CONFIGURATIONS 22 #include "ia_css_isp_configs.h" 23 24 #include "isp.h" 25 26 void 27 ia_css_vf_config( 28 struct sh_css_isp_vf_isp_config *to, 29 const struct ia_css_vf_configuration *from, 30 unsigned int size) 31 { 32 unsigned int elems_a = ISP_VEC_NELEMS; 33 34 (void)size; 35 to->vf_downscale_bits = from->vf_downscale_bits; 36 to->enable = from->info != NULL; 37 38 if (from->info) { 39 ia_css_frame_info_to_frame_sp_info(&to->info, from->info); 40 ia_css_dma_configure_from_info(&to->dma.port_b, from->info); 41 to->dma.width_a_over_b = elems_a / to->dma.port_b.elems; 42 43 /* Assume divisiblity here, may need to generalize to fixed point. */ 44 assert(elems_a % to->dma.port_b.elems == 0); 45 } 46 } 47 48 /* compute the log2 of the downscale factor needed to get closest 49 * to the requested viewfinder resolution on the upper side. The output cannot 50 * be smaller than the requested viewfinder resolution. 51 */ 52 int 53 sh_css_vf_downscale_log2( 54 const struct ia_css_frame_info *out_info, 55 const struct ia_css_frame_info *vf_info, 56 unsigned int *downscale_log2) { 57 unsigned int ds_log2 = 0; 58 unsigned int out_width; 59 60 if ((!out_info) | (!vf_info)) 61 return -EINVAL; 62 63 out_width = out_info->res.width; 64 65 if (out_width == 0) 66 return -EINVAL; 67 68 /* downscale until width smaller than the viewfinder width. We don't 69 * test for the height since the vmem buffers only put restrictions on 70 * the width of a line, not on the number of lines in a frame. 71 */ 72 while (out_width >= vf_info->res.width) 73 { 74 ds_log2++; 75 out_width /= 2; 76 } 77 /* now width is smaller, so we go up one step */ 78 if ((ds_log2 > 0) && (out_width < ia_css_binary_max_vf_width())) 79 ds_log2--; 80 /* TODO: use actual max input resolution of vf_pp binary */ 81 if ((out_info->res.width >> ds_log2) >= 2 * ia_css_binary_max_vf_width()) 82 return -EINVAL; 83 *downscale_log2 = ds_log2; 84 return 0; 85 } 86 87 static int 88 configure_kernel( 89 const struct ia_css_binary_info *info, 90 const struct ia_css_frame_info *out_info, 91 const struct ia_css_frame_info *vf_info, 92 unsigned int *downscale_log2, 93 struct ia_css_vf_configuration *config) { 94 int err; 95 unsigned int vf_log_ds = 0; 96 97 /* First compute value */ 98 if (vf_info) 99 { 100 err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds); 101 if (err) 102 return err; 103 } 104 vf_log_ds = min(vf_log_ds, info->vf_dec.max_log_downscale); 105 *downscale_log2 = vf_log_ds; 106 107 /* Then store it in isp config section */ 108 config->vf_downscale_bits = vf_log_ds; 109 return 0; 110 } 111 112 static void 113 configure_dma( 114 struct ia_css_vf_configuration *config, 115 const struct ia_css_frame_info *vf_info) 116 { 117 config->info = vf_info; 118 } 119 120 int 121 ia_css_vf_configure( 122 const struct ia_css_binary *binary, 123 const struct ia_css_frame_info *out_info, 124 struct ia_css_frame_info *vf_info, 125 unsigned int *downscale_log2) { 126 int err; 127 struct ia_css_vf_configuration config; 128 const struct ia_css_binary_info *info = &binary->info->sp; 129 130 err = configure_kernel(info, out_info, vf_info, downscale_log2, &config); 131 configure_dma(&config, vf_info); 132 133 if (vf_info) 134 vf_info->raw_bit_depth = info->dma.vfdec_bits_per_pixel; 135 ia_css_configure_vf(binary, &config); 136 137 return 0; 138 } 139