linux/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Support for Intel Camera Imaging ISP subsystem.
   4 * Copyright (c) 2010 - 2015, Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 */
  15
  16#include "hmm.h"
  17
  18#include "ia_css_pipeline.h"
  19#include "ia_css_isp_param.h"
  20
  21/* Set functions for parameter memory descriptors */
  22
  23void
  24ia_css_isp_param_set_mem_init(
  25    struct ia_css_isp_param_host_segments *mem_init,
  26    enum ia_css_param_class pclass,
  27    enum ia_css_isp_memories mem,
  28    char *address, size_t size)
  29{
  30        mem_init->params[pclass][mem].address = address;
  31        mem_init->params[pclass][mem].size = (uint32_t)size;
  32}
  33
  34void
  35ia_css_isp_param_set_css_mem_init(
  36    struct ia_css_isp_param_css_segments *mem_init,
  37    enum ia_css_param_class pclass,
  38    enum ia_css_isp_memories mem,
  39    ia_css_ptr address, size_t size)
  40{
  41        mem_init->params[pclass][mem].address = address;
  42        mem_init->params[pclass][mem].size = (uint32_t)size;
  43}
  44
  45void
  46ia_css_isp_param_set_isp_mem_init(
  47    struct ia_css_isp_param_isp_segments *mem_init,
  48    enum ia_css_param_class pclass,
  49    enum ia_css_isp_memories mem,
  50    u32 address, size_t size)
  51{
  52        mem_init->params[pclass][mem].address = address;
  53        mem_init->params[pclass][mem].size = (uint32_t)size;
  54}
  55
  56/* Get functions for parameter memory descriptors */
  57const struct ia_css_host_data *
  58ia_css_isp_param_get_mem_init(
  59    const struct ia_css_isp_param_host_segments *mem_init,
  60    enum ia_css_param_class pclass,
  61    enum ia_css_isp_memories mem)
  62{
  63        return &mem_init->params[pclass][mem];
  64}
  65
  66const struct ia_css_data *
  67ia_css_isp_param_get_css_mem_init(
  68    const struct ia_css_isp_param_css_segments *mem_init,
  69    enum ia_css_param_class pclass,
  70    enum ia_css_isp_memories mem)
  71{
  72        return &mem_init->params[pclass][mem];
  73}
  74
  75const struct ia_css_isp_data *
  76ia_css_isp_param_get_isp_mem_init(
  77    const struct ia_css_isp_param_isp_segments *mem_init,
  78    enum ia_css_param_class pclass,
  79    enum ia_css_isp_memories mem)
  80{
  81        return &mem_init->params[pclass][mem];
  82}
  83
  84void
  85ia_css_init_memory_interface(
  86    struct ia_css_isp_param_css_segments *isp_mem_if,
  87    const struct ia_css_isp_param_host_segments *mem_params,
  88    const struct ia_css_isp_param_css_segments *css_params)
  89{
  90        unsigned int pclass, mem;
  91
  92        for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
  93                memset(isp_mem_if->params[pclass], 0, sizeof(isp_mem_if->params[pclass]));
  94                for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
  95                        if (!mem_params->params[pclass][mem].address)
  96                                continue;
  97                        isp_mem_if->params[pclass][mem].size = mem_params->params[pclass][mem].size;
  98                        if (pclass != IA_CSS_PARAM_CLASS_PARAM)
  99                                isp_mem_if->params[pclass][mem].address =
 100                                    css_params->params[pclass][mem].address;
 101                }
 102        }
 103}
 104
 105int
 106ia_css_isp_param_allocate_isp_parameters(
 107    struct ia_css_isp_param_host_segments *mem_params,
 108    struct ia_css_isp_param_css_segments *css_params,
 109    const struct ia_css_isp_param_isp_segments *mem_initializers) {
 110        int err = 0;
 111        unsigned int mem, pclass;
 112
 113        pclass = IA_CSS_PARAM_CLASS_PARAM;
 114        for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++)
 115        {
 116                for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
 117                        u32 size = 0;
 118
 119                        if (mem_initializers)
 120                                size = mem_initializers->params[pclass][mem].size;
 121                        mem_params->params[pclass][mem].size = size;
 122                        mem_params->params[pclass][mem].address = NULL;
 123                        css_params->params[pclass][mem].size = size;
 124                        css_params->params[pclass][mem].address = 0x0;
 125                        if (size) {
 126                                mem_params->params[pclass][mem].address = kvcalloc(1,
 127                                                                                   size,
 128                                                                                   GFP_KERNEL);
 129                                if (!mem_params->params[pclass][mem].address) {
 130                                        err = -ENOMEM;
 131                                        goto cleanup;
 132                                }
 133                                if (pclass != IA_CSS_PARAM_CLASS_PARAM) {
 134                                        css_params->params[pclass][mem].address = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0);
 135                                        if (!css_params->params[pclass][mem].address) {
 136                                                err = -ENOMEM;
 137                                                goto cleanup;
 138                                        }
 139                                }
 140                        }
 141                }
 142        }
 143        return err;
 144cleanup:
 145        ia_css_isp_param_destroy_isp_parameters(mem_params, css_params);
 146        return err;
 147}
 148
 149void
 150ia_css_isp_param_destroy_isp_parameters(
 151    struct ia_css_isp_param_host_segments *mem_params,
 152    struct ia_css_isp_param_css_segments *css_params)
 153{
 154        unsigned int mem, pclass;
 155
 156        for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
 157                for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
 158                        kvfree(mem_params->params[pclass][mem].address);
 159                        if (css_params->params[pclass][mem].address)
 160                                hmm_free(css_params->params[pclass][mem].address);
 161                        mem_params->params[pclass][mem].address = NULL;
 162                        css_params->params[pclass][mem].address = 0x0;
 163                }
 164        }
 165}
 166
 167void
 168ia_css_isp_param_load_fw_params(
 169    const char *fw,
 170    union ia_css_all_memory_offsets *mem_offsets,
 171    const struct ia_css_isp_param_memory_offsets *memory_offsets,
 172    bool init)
 173{
 174        unsigned int pclass;
 175
 176        for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
 177                mem_offsets->array[pclass].ptr = NULL;
 178                if (init)
 179                        mem_offsets->array[pclass].ptr = (void *)(fw + memory_offsets->offsets[pclass]);
 180        }
 181}
 182
 183int
 184ia_css_isp_param_copy_isp_mem_if_to_ddr(
 185    struct ia_css_isp_param_css_segments *ddr,
 186    const struct ia_css_isp_param_host_segments *host,
 187    enum ia_css_param_class pclass) {
 188        unsigned int mem;
 189
 190        for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++)
 191        {
 192                size_t       size         = host->params[pclass][mem].size;
 193                ia_css_ptr ddr_mem_ptr  = ddr->params[pclass][mem].address;
 194                char        *host_mem_ptr = host->params[pclass][mem].address;
 195
 196                if (size != ddr->params[pclass][mem].size)
 197                        return -EINVAL;
 198                if (!size)
 199                        continue;
 200                hmm_store(ddr_mem_ptr, host_mem_ptr, size);
 201        }
 202        return 0;
 203}
 204
 205void
 206ia_css_isp_param_enable_pipeline(
 207    const struct ia_css_isp_param_host_segments *mem_params)
 208{
 209        /* By protocol b0 of the mandatory uint32_t first field of the
 210           input parameter is a disable bit*/
 211        short dmem_offset = 0;
 212
 213        if (mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].size == 0)
 214                return;
 215
 216        *(uint32_t *)
 217        &mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].address[dmem_offset]
 218            = 0x0;
 219}
 220