root/drivers/gpu/drm/amd/display/dc/gpio/hw_gpio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. store_registers
  2. restore_registers
  3. dal_hw_gpio_open
  4. dal_hw_gpio_get_value
  5. dal_hw_gpio_set_value
  6. dal_hw_gpio_change_mode
  7. dal_hw_gpio_close
  8. dal_hw_gpio_config_mode
  9. dal_hw_gpio_construct
  10. dal_hw_gpio_destruct

   1 /*
   2  * Copyright 2012-15 Advanced Micro Devices, Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: AMD
  23  *
  24  */
  25 
  26 #include "dm_services.h"
  27 #include "include/gpio_types.h"
  28 #include "hw_gpio.h"
  29 
  30 #include "reg_helper.h"
  31 #include "gpio_regs.h"
  32 
  33 #undef FN
  34 #define FN(reg_name, field_name) \
  35         gpio->regs->field_name ## _shift, gpio->regs->field_name ## _mask
  36 
  37 #define CTX \
  38         gpio->base.ctx
  39 #define REG(reg)\
  40         (gpio->regs->reg)
  41 
  42 static void store_registers(
  43         struct hw_gpio *gpio)
  44 {
  45         REG_GET(MASK_reg, MASK, &gpio->store.mask);
  46         REG_GET(A_reg, A, &gpio->store.a);
  47         REG_GET(EN_reg, EN, &gpio->store.en);
  48         /* TODO store GPIO_MUX_CONTROL if we ever use it */
  49 }
  50 
  51 static void restore_registers(
  52         struct hw_gpio *gpio)
  53 {
  54         REG_UPDATE(MASK_reg, MASK, gpio->store.mask);
  55         REG_UPDATE(A_reg, A, gpio->store.a);
  56         REG_UPDATE(EN_reg, EN, gpio->store.en);
  57         /* TODO restore GPIO_MUX_CONTROL if we ever use it */
  58 }
  59 
  60 bool dal_hw_gpio_open(
  61         struct hw_gpio_pin *ptr,
  62         enum gpio_mode mode)
  63 {
  64         struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
  65 
  66         store_registers(pin);
  67 
  68         ptr->opened = (dal_hw_gpio_config_mode(pin, mode) == GPIO_RESULT_OK);
  69 
  70         return ptr->opened;
  71 }
  72 
  73 enum gpio_result dal_hw_gpio_get_value(
  74         const struct hw_gpio_pin *ptr,
  75         uint32_t *value)
  76 {
  77         const struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);
  78 
  79         enum gpio_result result = GPIO_RESULT_OK;
  80 
  81         switch (ptr->mode) {
  82         case GPIO_MODE_INPUT:
  83         case GPIO_MODE_OUTPUT:
  84         case GPIO_MODE_HARDWARE:
  85         case GPIO_MODE_FAST_OUTPUT:
  86                 REG_GET(Y_reg, Y, value);
  87                 break;
  88         default:
  89                 result = GPIO_RESULT_NON_SPECIFIC_ERROR;
  90         }
  91 
  92         return result;
  93 }
  94 
  95 enum gpio_result dal_hw_gpio_set_value(
  96         const struct hw_gpio_pin *ptr,
  97         uint32_t value)
  98 {
  99         struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);
 100 
 101         /* This is the public interface
 102          * where the input comes from client, not shifted yet
 103          * (because client does not know the shifts). */
 104 
 105         switch (ptr->mode) {
 106         case GPIO_MODE_OUTPUT:
 107                 REG_UPDATE(A_reg, A, value);
 108                 return GPIO_RESULT_OK;
 109         case GPIO_MODE_FAST_OUTPUT:
 110                 /* We use (EN) to faster switch (used in DDC GPIO).
 111                  * So (A) is grounded, output is driven by (EN = 0)
 112                  * to pull the line down (output == 0) and (EN=1)
 113                  * then output is tri-state */
 114                 REG_UPDATE(EN_reg, EN, ~value);
 115                 return GPIO_RESULT_OK;
 116         default:
 117                 return GPIO_RESULT_NON_SPECIFIC_ERROR;
 118         }
 119 }
 120 
 121 enum gpio_result dal_hw_gpio_change_mode(
 122         struct hw_gpio_pin *ptr,
 123         enum gpio_mode mode)
 124 {
 125         struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
 126 
 127         return dal_hw_gpio_config_mode(pin, mode);
 128 }
 129 
 130 void dal_hw_gpio_close(
 131         struct hw_gpio_pin *ptr)
 132 {
 133         struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
 134 
 135         restore_registers(pin);
 136 
 137         ptr->mode = GPIO_MODE_UNKNOWN;
 138         ptr->opened = false;
 139 }
 140 
 141 enum gpio_result dal_hw_gpio_config_mode(
 142         struct hw_gpio *gpio,
 143         enum gpio_mode mode)
 144 {
 145         gpio->base.mode = mode;
 146 
 147         switch (mode) {
 148         case GPIO_MODE_INPUT:
 149                 /* turn off output enable, act as input pin;
 150                  * program the pin as GPIO, mask out signal driven by HW */
 151                 REG_UPDATE(EN_reg, EN, 0);
 152                 REG_UPDATE(MASK_reg, MASK, 1);
 153                 return GPIO_RESULT_OK;
 154         case GPIO_MODE_OUTPUT:
 155                 /* turn on output enable, act as output pin;
 156                  * program the pin as GPIO, mask out signal driven by HW */
 157                 REG_UPDATE(A_reg, A, 0);
 158                 REG_UPDATE(MASK_reg, MASK, 1);
 159                 return GPIO_RESULT_OK;
 160         case GPIO_MODE_FAST_OUTPUT:
 161                 /* grounding the A register then use the EN register bit
 162                  * will have faster effect on the rise time */
 163                 REG_UPDATE(A_reg, A, 0);
 164                 REG_UPDATE(MASK_reg, MASK, 1);
 165                 return GPIO_RESULT_OK;
 166         case GPIO_MODE_HARDWARE:
 167                 /* program the pin as tri-state, pin is driven by HW */
 168                 REG_UPDATE(MASK_reg, MASK, 0);
 169                 return GPIO_RESULT_OK;
 170         case GPIO_MODE_INTERRUPT:
 171                 /* Interrupt mode supported only by HPD (IrqGpio) pins. */
 172                 REG_UPDATE(MASK_reg, MASK, 0);
 173                 return GPIO_RESULT_OK;
 174         default:
 175                 return GPIO_RESULT_NON_SPECIFIC_ERROR;
 176         }
 177 }
 178 
 179 void dal_hw_gpio_construct(
 180         struct hw_gpio *pin,
 181         enum gpio_id id,
 182         uint32_t en,
 183         struct dc_context *ctx)
 184 {
 185         pin->base.ctx = ctx;
 186         pin->base.id = id;
 187         pin->base.en = en;
 188         pin->base.mode = GPIO_MODE_UNKNOWN;
 189         pin->base.opened = false;
 190 
 191         pin->store.mask = 0;
 192         pin->store.a = 0;
 193         pin->store.en = 0;
 194         pin->store.mux = 0;
 195 
 196         pin->mux_supported = false;
 197 }
 198 
 199 void dal_hw_gpio_destruct(
 200         struct hw_gpio *pin)
 201 {
 202         ASSERT(!pin->base.opened);
 203 }

/* [<][>][^][v][top][bottom][index][help] */