Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 #include "include/gpio_types.h"
0028 #include "hw_gpio.h"
0029 
0030 #include "reg_helper.h"
0031 #include "gpio_regs.h"
0032 
0033 #undef FN
0034 #define FN(reg_name, field_name) \
0035     gpio->regs->field_name ## _shift, gpio->regs->field_name ## _mask
0036 
0037 #define CTX \
0038     gpio->base.ctx
0039 #define REG(reg)\
0040     (gpio->regs->reg)
0041 
0042 static void store_registers(
0043     struct hw_gpio *gpio)
0044 {
0045     REG_GET(MASK_reg, MASK, &gpio->store.mask);
0046     REG_GET(A_reg, A, &gpio->store.a);
0047     REG_GET(EN_reg, EN, &gpio->store.en);
0048     /* TODO store GPIO_MUX_CONTROL if we ever use it */
0049 }
0050 
0051 static void restore_registers(
0052     struct hw_gpio *gpio)
0053 {
0054     REG_UPDATE(MASK_reg, MASK, gpio->store.mask);
0055     REG_UPDATE(A_reg, A, gpio->store.a);
0056     REG_UPDATE(EN_reg, EN, gpio->store.en);
0057     /* TODO restore GPIO_MUX_CONTROL if we ever use it */
0058 }
0059 
0060 bool dal_hw_gpio_open(
0061     struct hw_gpio_pin *ptr,
0062     enum gpio_mode mode)
0063 {
0064     struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
0065 
0066     store_registers(pin);
0067 
0068     ptr->opened = (dal_hw_gpio_config_mode(pin, mode) == GPIO_RESULT_OK);
0069 
0070     return ptr->opened;
0071 }
0072 
0073 enum gpio_result dal_hw_gpio_get_value(
0074     const struct hw_gpio_pin *ptr,
0075     uint32_t *value)
0076 {
0077     const struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);
0078 
0079     enum gpio_result result = GPIO_RESULT_OK;
0080 
0081     switch (ptr->mode) {
0082     case GPIO_MODE_INPUT:
0083     case GPIO_MODE_OUTPUT:
0084     case GPIO_MODE_HARDWARE:
0085     case GPIO_MODE_FAST_OUTPUT:
0086         REG_GET(Y_reg, Y, value);
0087         break;
0088     default:
0089         result = GPIO_RESULT_NON_SPECIFIC_ERROR;
0090     }
0091 
0092     return result;
0093 }
0094 
0095 enum gpio_result dal_hw_gpio_set_value(
0096     const struct hw_gpio_pin *ptr,
0097     uint32_t value)
0098 {
0099     struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);
0100 
0101     /* This is the public interface
0102      * where the input comes from client, not shifted yet
0103      * (because client does not know the shifts). */
0104 
0105     switch (ptr->mode) {
0106     case GPIO_MODE_OUTPUT:
0107         REG_UPDATE(A_reg, A, value);
0108         return GPIO_RESULT_OK;
0109     case GPIO_MODE_FAST_OUTPUT:
0110         /* We use (EN) to faster switch (used in DDC GPIO).
0111          * So (A) is grounded, output is driven by (EN = 0)
0112          * to pull the line down (output == 0) and (EN=1)
0113          * then output is tri-state */
0114         REG_UPDATE(EN_reg, EN, ~value);
0115         return GPIO_RESULT_OK;
0116     default:
0117         return GPIO_RESULT_NON_SPECIFIC_ERROR;
0118     }
0119 }
0120 
0121 enum gpio_result dal_hw_gpio_change_mode(
0122     struct hw_gpio_pin *ptr,
0123     enum gpio_mode mode)
0124 {
0125     struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
0126 
0127     return dal_hw_gpio_config_mode(pin, mode);
0128 }
0129 
0130 void dal_hw_gpio_close(
0131     struct hw_gpio_pin *ptr)
0132 {
0133     struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
0134 
0135     restore_registers(pin);
0136 
0137     ptr->mode = GPIO_MODE_UNKNOWN;
0138     ptr->opened = false;
0139 }
0140 
0141 enum gpio_result dal_hw_gpio_config_mode(
0142     struct hw_gpio *gpio,
0143     enum gpio_mode mode)
0144 {
0145     gpio->base.mode = mode;
0146 
0147     switch (mode) {
0148     case GPIO_MODE_INPUT:
0149         /* turn off output enable, act as input pin;
0150          * program the pin as GPIO, mask out signal driven by HW */
0151         REG_UPDATE(EN_reg, EN, 0);
0152         REG_UPDATE(MASK_reg, MASK, 1);
0153         return GPIO_RESULT_OK;
0154     case GPIO_MODE_OUTPUT:
0155         /* turn on output enable, act as output pin;
0156          * program the pin as GPIO, mask out signal driven by HW */
0157         REG_UPDATE(A_reg, A, 0);
0158         REG_UPDATE(MASK_reg, MASK, 1);
0159         return GPIO_RESULT_OK;
0160     case GPIO_MODE_FAST_OUTPUT:
0161         /* grounding the A register then use the EN register bit
0162          * will have faster effect on the rise time */
0163         REG_UPDATE(A_reg, A, 0);
0164         REG_UPDATE(MASK_reg, MASK, 1);
0165         return GPIO_RESULT_OK;
0166     case GPIO_MODE_HARDWARE:
0167         /* program the pin as tri-state, pin is driven by HW */
0168         REG_UPDATE(MASK_reg, MASK, 0);
0169         return GPIO_RESULT_OK;
0170     case GPIO_MODE_INTERRUPT:
0171         /* Interrupt mode supported only by HPD (IrqGpio) pins. */
0172         REG_UPDATE(MASK_reg, MASK, 0);
0173         return GPIO_RESULT_OK;
0174     default:
0175         return GPIO_RESULT_NON_SPECIFIC_ERROR;
0176     }
0177 }
0178 
0179 void dal_hw_gpio_construct(
0180     struct hw_gpio *pin,
0181     enum gpio_id id,
0182     uint32_t en,
0183     struct dc_context *ctx)
0184 {
0185     pin->base.ctx = ctx;
0186     pin->base.id = id;
0187     pin->base.en = en;
0188     pin->base.mode = GPIO_MODE_UNKNOWN;
0189     pin->base.opened = false;
0190 
0191     pin->store.mask = 0;
0192     pin->store.a = 0;
0193     pin->store.en = 0;
0194     pin->store.mux = 0;
0195 
0196     pin->mux_supported = false;
0197 }
0198 
0199 void dal_hw_gpio_destruct(
0200     struct hw_gpio *pin)
0201 {
0202     ASSERT(!pin->base.opened);
0203 }