linux/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Support for Intel Camera Imaging ISP subsystem.
   4 * Copyright (c) 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#ifndef __MATH_SUPPORT_H
  17#define __MATH_SUPPORT_H
  18
  19#include <linux/kernel.h> /* Override the definition of max/min from linux kernel*/
  20
  21#define IS_ODD(a)            ((a) & 0x1)
  22#define IS_EVEN(a)           (!IS_ODD(a))
  23
  24/* force a value to a lower even value */
  25#define EVEN_FLOOR(x)        ((x) & ~1)
  26
  27/* ISP2401 */
  28/* If the number is odd, find the next even number */
  29#define EVEN_CEIL(x)         ((IS_ODD(x)) ? ((x) + 1) : (x))
  30
  31/* A => B */
  32#define IMPLIES(a, b)        (!(a) || (b))
  33
  34/* for preprocessor and array sizing use MIN and MAX
  35   otherwise use min and max */
  36#define MAX(a, b)            (((a) > (b)) ? (a) : (b))
  37#define MIN(a, b)            (((a) < (b)) ? (a) : (b))
  38
  39#define ROUND_DIV(a, b)      (((b) != 0) ? ((a) + ((b) >> 1)) / (b) : 0)
  40#define CEIL_DIV(a, b)       (((b) != 0) ? ((a) + (b) - 1) / (b) : 0)
  41#define CEIL_MUL(a, b)       (CEIL_DIV(a, b) * (b))
  42#define CEIL_MUL2(a, b)      (((a) + (b) - 1) & ~((b) - 1))
  43#define CEIL_SHIFT(a, b)     (((a) + (1 << (b)) - 1) >> (b))
  44#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b))
  45#define ROUND_HALF_DOWN_DIV(a, b)       (((b) != 0) ? ((a) + (b / 2) - 1) / (b) : 0)
  46#define ROUND_HALF_DOWN_MUL(a, b)       (ROUND_HALF_DOWN_DIV(a, b) * (b))
  47
  48/*To Find next power of 2 number from x */
  49#define bit2(x)            ((x)      | ((x) >> 1))
  50#define bit4(x)            (bit2(x)  | (bit2(x) >> 2))
  51#define bit8(x)            (bit4(x)  | (bit4(x) >> 4))
  52#define bit16(x)           (bit8(x)  | (bit8(x) >> 8))
  53#define bit32(x)           (bit16(x) | (bit16(x) >> 16))
  54#define NEXT_POWER_OF_2(x) (bit32(x - 1) + 1)
  55
  56/* min and max should not be macros as they will evaluate their arguments twice.
  57   if you really need a macro (e.g. for CPP or for initializing an array)
  58   use MIN() and MAX(), otherwise use min() and max().
  59
  60*/
  61
  62#if !defined(PIPE_GENERATION)
  63
  64/*
  65This macro versions are added back as we are mixing types in usage of inline.
  66This causes corner cases of calculations to be incorrect due to conversions
  67between signed and unsigned variables or overflows.
  68Before the addition of the inline functions, max, min and ceil_div were macros
  69and therefore adding them back.
  70
  71Leaving out the other math utility functions as they are newly added
  72*/
  73
  74#define ceil_div(a, b)          (CEIL_DIV(a, b))
  75
  76static inline unsigned int ceil_mul(unsigned int a, unsigned int b)
  77{
  78        return CEIL_MUL(a, b);
  79}
  80
  81static inline unsigned int ceil_mul2(unsigned int a, unsigned int b)
  82{
  83        return CEIL_MUL2(a, b);
  84}
  85
  86static inline unsigned int ceil_shift(unsigned int a, unsigned int b)
  87{
  88        return CEIL_SHIFT(a, b);
  89}
  90
  91static inline unsigned int ceil_shift_mul(unsigned int a, unsigned int b)
  92{
  93        return CEIL_SHIFT_MUL(a, b);
  94}
  95
  96/* ISP2401 */
  97static inline unsigned int round_half_down_div(unsigned int a, unsigned int b)
  98{
  99        return ROUND_HALF_DOWN_DIV(a, b);
 100}
 101
 102/* ISP2401 */
 103static inline unsigned int round_half_down_mul(unsigned int a, unsigned int b)
 104{
 105        return ROUND_HALF_DOWN_MUL(a, b);
 106}
 107
 108/* @brief Next Power of Two
 109 *
 110 *  @param[in] unsigned number
 111 *
 112 *  @return next power of two
 113 *
 114 * This function rounds input to the nearest power of 2 (2^x)
 115 * towards infinity
 116 *
 117 * Input Range: 0 .. 2^(8*sizeof(int)-1)
 118 *
 119 * IF input is a power of 2
 120 *     out = in
 121 * OTHERWISE
 122 *     out = 2^(ceil(log2(in))
 123 *
 124 */
 125
 126static inline unsigned int ceil_pow2(unsigned int a)
 127{
 128        if (a == 0) {
 129                return 1;
 130        }
 131        /* IF input is already a power of two*/
 132        else if ((!((a) & ((a) - 1)))) {
 133                return a;
 134        } else {
 135                unsigned int v = a;
 136
 137                v |= v >> 1;
 138                v |= v >> 2;
 139                v |= v >> 4;
 140                v |= v >> 8;
 141                v |= v >> 16;
 142                return (v + 1);
 143        }
 144}
 145
 146#endif /* !defined(PIPE_GENERATION) */
 147
 148/*
 149 * For SP and ISP, SDK provides the definition of OP_std_modadd.
 150 * We need it only for host
 151 */
 152#define OP_std_modadd(base, offset, size) ((base + offset) % (size))
 153
 154#endif /* __MATH_SUPPORT_H */
 155