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 
0028 #include "include/gpio_interface.h"
0029 #include "include/gpio_types.h"
0030 #include "hw_gpio.h"
0031 #include "hw_hpd.h"
0032 
0033 #include "reg_helper.h"
0034 #include "hpd_regs.h"
0035 
0036 #undef FN
0037 #define FN(reg_name, field_name) \
0038     hpd->shifts->field_name, hpd->masks->field_name
0039 
0040 #define CTX \
0041     hpd->base.base.ctx
0042 #define REG(reg)\
0043     (hpd->regs->reg)
0044 
0045 struct gpio;
0046 
0047 static void dal_hw_hpd_destruct(
0048     struct hw_hpd *pin)
0049 {
0050     dal_hw_gpio_destruct(&pin->base);
0051 }
0052 
0053 static void dal_hw_hpd_destroy(
0054     struct hw_gpio_pin **ptr)
0055 {
0056     struct hw_hpd *hpd = HW_HPD_FROM_BASE(*ptr);
0057 
0058     dal_hw_hpd_destruct(hpd);
0059 
0060     kfree(hpd);
0061 
0062     *ptr = NULL;
0063 }
0064 
0065 static enum gpio_result get_value(
0066     const struct hw_gpio_pin *ptr,
0067     uint32_t *value)
0068 {
0069     struct hw_hpd *hpd = HW_HPD_FROM_BASE(ptr);
0070     uint32_t hpd_delayed = 0;
0071 
0072     /* in Interrupt mode we ask for SENSE bit */
0073 
0074     if (ptr->mode == GPIO_MODE_INTERRUPT) {
0075 
0076         REG_GET(int_status,
0077             DC_HPD_SENSE_DELAYED, &hpd_delayed);
0078 
0079         *value = hpd_delayed;
0080         return GPIO_RESULT_OK;
0081     }
0082 
0083     /* in any other modes, operate as normal GPIO */
0084 
0085     return dal_hw_gpio_get_value(ptr, value);
0086 }
0087 
0088 static enum gpio_result set_config(
0089     struct hw_gpio_pin *ptr,
0090     const struct gpio_config_data *config_data)
0091 {
0092     struct hw_hpd *hpd = HW_HPD_FROM_BASE(ptr);
0093 
0094     if (!config_data)
0095         return GPIO_RESULT_INVALID_DATA;
0096 
0097     REG_UPDATE_2(toggle_filt_cntl,
0098         DC_HPD_CONNECT_INT_DELAY, config_data->config.hpd.delay_on_connect / 10,
0099         DC_HPD_DISCONNECT_INT_DELAY, config_data->config.hpd.delay_on_disconnect / 10);
0100 
0101     return GPIO_RESULT_OK;
0102 }
0103 
0104 static const struct hw_gpio_pin_funcs funcs = {
0105     .destroy = dal_hw_hpd_destroy,
0106     .open = dal_hw_gpio_open,
0107     .get_value = get_value,
0108     .set_value = dal_hw_gpio_set_value,
0109     .set_config = set_config,
0110     .change_mode = dal_hw_gpio_change_mode,
0111     .close = dal_hw_gpio_close,
0112 };
0113 
0114 static void dal_hw_hpd_construct(
0115     struct hw_hpd *pin,
0116     enum gpio_id id,
0117     uint32_t en,
0118     struct dc_context *ctx)
0119 {
0120     dal_hw_gpio_construct(&pin->base, id, en, ctx);
0121     pin->base.base.funcs = &funcs;
0122 }
0123 
0124 void dal_hw_hpd_init(
0125     struct hw_hpd **hw_hpd,
0126     struct dc_context *ctx,
0127     enum gpio_id id,
0128     uint32_t en)
0129 {
0130     if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) {
0131         ASSERT_CRITICAL(false);
0132         *hw_hpd = NULL;
0133     }
0134 
0135     *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL);
0136     if (!*hw_hpd) {
0137         ASSERT_CRITICAL(false);
0138         return;
0139     }
0140 
0141     dal_hw_hpd_construct(*hw_hpd, id, en, ctx);
0142 }
0143 
0144 struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio)
0145 {
0146     struct hw_hpd *hw_hpd = dal_gpio_get_hpd(gpio);
0147 
0148     return &hw_hpd->base.base;
0149 }