linux/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.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 "type_support.h"
  19#include "queue_access.h"
  20#include "ia_css_circbuf.h"
  21#include "sp.h"
  22#include "assert_support.h"
  23
  24int ia_css_queue_load(
  25    struct ia_css_queue *rdesc,
  26    ia_css_circbuf_desc_t *cb_desc,
  27    uint32_t ignore_desc_flags)
  28{
  29        if (!rdesc || !cb_desc)
  30                return -EINVAL;
  31
  32        if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
  33                assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX);
  34
  35                if (0 == (ignore_desc_flags & QUEUE_IGNORE_SIZE_FLAG)) {
  36                        cb_desc->size = sp_dmem_load_uint8(rdesc->proc_id,
  37                                                           rdesc->desc.remote.cb_desc_addr
  38                                                           + offsetof(ia_css_circbuf_desc_t, size));
  39
  40                        if (cb_desc->size == 0) {
  41                                /* Adding back the workaround which was removed
  42                                   while refactoring queues. When reading size
  43                                   through sp_dmem_load_*, sometimes we get back
  44                                   the value as zero. This causes division by 0
  45                                   exception as the size is used in a modular
  46                                   division operation. */
  47                                return -EDOM;
  48                        }
  49                }
  50
  51                if (0 == (ignore_desc_flags & QUEUE_IGNORE_START_FLAG))
  52                        cb_desc->start = sp_dmem_load_uint8(rdesc->proc_id,
  53                                                            rdesc->desc.remote.cb_desc_addr
  54                                                            + offsetof(ia_css_circbuf_desc_t, start));
  55
  56                if (0 == (ignore_desc_flags & QUEUE_IGNORE_END_FLAG))
  57                        cb_desc->end = sp_dmem_load_uint8(rdesc->proc_id,
  58                                                          rdesc->desc.remote.cb_desc_addr
  59                                                          + offsetof(ia_css_circbuf_desc_t, end));
  60
  61                if (0 == (ignore_desc_flags & QUEUE_IGNORE_STEP_FLAG))
  62                        cb_desc->step = sp_dmem_load_uint8(rdesc->proc_id,
  63                                                           rdesc->desc.remote.cb_desc_addr
  64                                                           + offsetof(ia_css_circbuf_desc_t, step));
  65
  66        } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
  67                /* doing DMA transfer of entire structure */
  68                hmm_load(rdesc->desc.remote.cb_desc_addr,
  69                          (void *)cb_desc,
  70                          sizeof(ia_css_circbuf_desc_t));
  71        } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
  72                /* Not supported yet */
  73                return -ENOTSUPP;
  74        }
  75
  76        return 0;
  77}
  78
  79int ia_css_queue_store(
  80    struct ia_css_queue *rdesc,
  81    ia_css_circbuf_desc_t *cb_desc,
  82    uint32_t ignore_desc_flags)
  83{
  84        if (!rdesc || !cb_desc)
  85                return -EINVAL;
  86
  87        if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
  88                assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX);
  89
  90                if (0 == (ignore_desc_flags & QUEUE_IGNORE_SIZE_FLAG))
  91                        sp_dmem_store_uint8(rdesc->proc_id,
  92                                            rdesc->desc.remote.cb_desc_addr
  93                                            + offsetof(ia_css_circbuf_desc_t, size),
  94                                            cb_desc->size);
  95
  96                if (0 == (ignore_desc_flags & QUEUE_IGNORE_START_FLAG))
  97                        sp_dmem_store_uint8(rdesc->proc_id,
  98                                            rdesc->desc.remote.cb_desc_addr
  99                                            + offsetof(ia_css_circbuf_desc_t, start),
 100                                            cb_desc->start);
 101
 102                if (0 == (ignore_desc_flags & QUEUE_IGNORE_END_FLAG))
 103                        sp_dmem_store_uint8(rdesc->proc_id,
 104                                            rdesc->desc.remote.cb_desc_addr
 105                                            + offsetof(ia_css_circbuf_desc_t, end),
 106                                            cb_desc->end);
 107
 108                if (0 == (ignore_desc_flags & QUEUE_IGNORE_STEP_FLAG))
 109                        sp_dmem_store_uint8(rdesc->proc_id,
 110                                            rdesc->desc.remote.cb_desc_addr
 111                                            + offsetof(ia_css_circbuf_desc_t, step),
 112                                            cb_desc->step);
 113        } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
 114                /* doing DMA transfer of entire structure */
 115                hmm_store(rdesc->desc.remote.cb_desc_addr,
 116                           (void *)cb_desc,
 117                           sizeof(ia_css_circbuf_desc_t));
 118        } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
 119                /* Not supported yet */
 120                return -ENOTSUPP;
 121        }
 122
 123        return 0;
 124}
 125
 126int ia_css_queue_item_load(
 127    struct ia_css_queue *rdesc,
 128    u8 position,
 129    ia_css_circbuf_elem_t *item)
 130{
 131        if (!rdesc || !item)
 132                return -EINVAL;
 133
 134        if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
 135                sp_dmem_load(rdesc->proc_id,
 136                             rdesc->desc.remote.cb_elems_addr
 137                             + position * sizeof(ia_css_circbuf_elem_t),
 138                             item,
 139                             sizeof(ia_css_circbuf_elem_t));
 140        } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
 141                hmm_load(rdesc->desc.remote.cb_elems_addr
 142                          + position * sizeof(ia_css_circbuf_elem_t),
 143                          (void *)item,
 144                          sizeof(ia_css_circbuf_elem_t));
 145        } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
 146                /* Not supported yet */
 147                return -ENOTSUPP;
 148        }
 149
 150        return 0;
 151}
 152
 153int ia_css_queue_item_store(
 154    struct ia_css_queue *rdesc,
 155    u8 position,
 156    ia_css_circbuf_elem_t *item)
 157{
 158        if (!rdesc || !item)
 159                return -EINVAL;
 160
 161        if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
 162                sp_dmem_store(rdesc->proc_id,
 163                              rdesc->desc.remote.cb_elems_addr
 164                              + position * sizeof(ia_css_circbuf_elem_t),
 165                              item,
 166                              sizeof(ia_css_circbuf_elem_t));
 167        } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
 168                hmm_store(rdesc->desc.remote.cb_elems_addr
 169                           + position * sizeof(ia_css_circbuf_elem_t),
 170                           (void *)item,
 171                           sizeof(ia_css_circbuf_elem_t));
 172        } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
 173                /* Not supported yet */
 174                return -ENOTSUPP;
 175        }
 176
 177        return 0;
 178}
 179