14562236bSHarry Wentland /*
24562236bSHarry Wentland * Copyright 2012-15 Advanced Micro Devices, Inc.
34562236bSHarry Wentland *
44562236bSHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a
54562236bSHarry Wentland * copy of this software and associated documentation files (the "Software"),
64562236bSHarry Wentland * to deal in the Software without restriction, including without limitation
74562236bSHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84562236bSHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the
94562236bSHarry Wentland * Software is furnished to do so, subject to the following conditions:
104562236bSHarry Wentland *
114562236bSHarry Wentland * The above copyright notice and this permission notice shall be included in
124562236bSHarry Wentland * all copies or substantial portions of the Software.
134562236bSHarry Wentland *
144562236bSHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154562236bSHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164562236bSHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
174562236bSHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
184562236bSHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
194562236bSHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
204562236bSHarry Wentland * OTHER DEALINGS IN THE SOFTWARE.
214562236bSHarry Wentland *
224562236bSHarry Wentland * Authors: AMD
234562236bSHarry Wentland *
244562236bSHarry Wentland */
254562236bSHarry Wentland
264562236bSHarry Wentland #include "dm_services.h"
274562236bSHarry Wentland
2891db9311SSu Sung Chung #include "include/gpio_interface.h"
294562236bSHarry Wentland #include "include/gpio_types.h"
304562236bSHarry Wentland #include "hw_gpio.h"
314562236bSHarry Wentland #include "hw_hpd.h"
324562236bSHarry Wentland
334562236bSHarry Wentland #include "reg_helper.h"
344562236bSHarry Wentland #include "hpd_regs.h"
354562236bSHarry Wentland
364562236bSHarry Wentland #undef FN
374562236bSHarry Wentland #define FN(reg_name, field_name) \
384562236bSHarry Wentland hpd->shifts->field_name, hpd->masks->field_name
394562236bSHarry Wentland
404562236bSHarry Wentland #define CTX \
414562236bSHarry Wentland hpd->base.base.ctx
424562236bSHarry Wentland #define REG(reg)\
434562236bSHarry Wentland (hpd->regs->reg)
444562236bSHarry Wentland
4591db9311SSu Sung Chung struct gpio;
4691db9311SSu Sung Chung
dal_hw_hpd_destruct(struct hw_hpd * pin)474562236bSHarry Wentland static void dal_hw_hpd_destruct(
484562236bSHarry Wentland struct hw_hpd *pin)
494562236bSHarry Wentland {
504562236bSHarry Wentland dal_hw_gpio_destruct(&pin->base);
514562236bSHarry Wentland }
524562236bSHarry Wentland
dal_hw_hpd_destroy(struct hw_gpio_pin ** ptr)53d9e32672SAnthony Koo static void dal_hw_hpd_destroy(
544562236bSHarry Wentland struct hw_gpio_pin **ptr)
554562236bSHarry Wentland {
564562236bSHarry Wentland struct hw_hpd *hpd = HW_HPD_FROM_BASE(*ptr);
574562236bSHarry Wentland
58d9e32672SAnthony Koo dal_hw_hpd_destruct(hpd);
594562236bSHarry Wentland
602004f45eSHarry Wentland kfree(hpd);
614562236bSHarry Wentland
624562236bSHarry Wentland *ptr = NULL;
634562236bSHarry Wentland }
644562236bSHarry Wentland
get_value(const struct hw_gpio_pin * ptr,uint32_t * value)654562236bSHarry Wentland static enum gpio_result get_value(
664562236bSHarry Wentland const struct hw_gpio_pin *ptr,
674562236bSHarry Wentland uint32_t *value)
684562236bSHarry Wentland {
694562236bSHarry Wentland struct hw_hpd *hpd = HW_HPD_FROM_BASE(ptr);
704562236bSHarry Wentland uint32_t hpd_delayed = 0;
714562236bSHarry Wentland
724562236bSHarry Wentland /* in Interrupt mode we ask for SENSE bit */
734562236bSHarry Wentland
744562236bSHarry Wentland if (ptr->mode == GPIO_MODE_INTERRUPT) {
754562236bSHarry Wentland
764562236bSHarry Wentland REG_GET(int_status,
774562236bSHarry Wentland DC_HPD_SENSE_DELAYED, &hpd_delayed);
784562236bSHarry Wentland
794562236bSHarry Wentland *value = hpd_delayed;
804562236bSHarry Wentland return GPIO_RESULT_OK;
814562236bSHarry Wentland }
824562236bSHarry Wentland
834562236bSHarry Wentland /* in any other modes, operate as normal GPIO */
844562236bSHarry Wentland
854562236bSHarry Wentland return dal_hw_gpio_get_value(ptr, value);
864562236bSHarry Wentland }
874562236bSHarry Wentland
set_config(struct hw_gpio_pin * ptr,const struct gpio_config_data * config_data)884562236bSHarry Wentland static enum gpio_result set_config(
894562236bSHarry Wentland struct hw_gpio_pin *ptr,
904562236bSHarry Wentland const struct gpio_config_data *config_data)
914562236bSHarry Wentland {
924562236bSHarry Wentland struct hw_hpd *hpd = HW_HPD_FROM_BASE(ptr);
934562236bSHarry Wentland
944562236bSHarry Wentland if (!config_data)
954562236bSHarry Wentland return GPIO_RESULT_INVALID_DATA;
964562236bSHarry Wentland
974562236bSHarry Wentland REG_UPDATE_2(toggle_filt_cntl,
984562236bSHarry Wentland DC_HPD_CONNECT_INT_DELAY, config_data->config.hpd.delay_on_connect / 10,
994562236bSHarry Wentland DC_HPD_DISCONNECT_INT_DELAY, config_data->config.hpd.delay_on_disconnect / 10);
1004562236bSHarry Wentland
1014562236bSHarry Wentland return GPIO_RESULT_OK;
1024562236bSHarry Wentland }
1034562236bSHarry Wentland
1044562236bSHarry Wentland static const struct hw_gpio_pin_funcs funcs = {
105d9e32672SAnthony Koo .destroy = dal_hw_hpd_destroy,
1064562236bSHarry Wentland .open = dal_hw_gpio_open,
1074562236bSHarry Wentland .get_value = get_value,
1084562236bSHarry Wentland .set_value = dal_hw_gpio_set_value,
1094562236bSHarry Wentland .set_config = set_config,
1104562236bSHarry Wentland .change_mode = dal_hw_gpio_change_mode,
1114562236bSHarry Wentland .close = dal_hw_gpio_close,
1124562236bSHarry Wentland };
1134562236bSHarry Wentland
dal_hw_hpd_construct(struct hw_hpd * pin,enum gpio_id id,uint32_t en,struct dc_context * ctx)114d9e32672SAnthony Koo static void dal_hw_hpd_construct(
115d9e32672SAnthony Koo struct hw_hpd *pin,
1164562236bSHarry Wentland enum gpio_id id,
1174562236bSHarry Wentland uint32_t en,
1184562236bSHarry Wentland struct dc_context *ctx)
1194562236bSHarry Wentland {
120d9e32672SAnthony Koo dal_hw_gpio_construct(&pin->base, id, en, ctx);
121d9e32672SAnthony Koo pin->base.base.funcs = &funcs;
1224562236bSHarry Wentland }
1234562236bSHarry Wentland
dal_hw_hpd_init(struct hw_hpd ** hw_hpd,struct dc_context * ctx,enum gpio_id id,uint32_t en)12491db9311SSu Sung Chung void dal_hw_hpd_init(
12591db9311SSu Sung Chung struct hw_hpd **hw_hpd,
1264562236bSHarry Wentland struct dc_context *ctx,
1274562236bSHarry Wentland enum gpio_id id,
1284562236bSHarry Wentland uint32_t en)
1294562236bSHarry Wentland {
130*82c94233SAlex Hung if (en > GPIO_DDC_LINE_MAX) {
1310e1c42fdSDave Airlie ASSERT_CRITICAL(false);
13291db9311SSu Sung Chung *hw_hpd = NULL;
1330e1c42fdSDave Airlie }
1340e1c42fdSDave Airlie
13591db9311SSu Sung Chung *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL);
13691db9311SSu Sung Chung if (!*hw_hpd) {
1370e1c42fdSDave Airlie ASSERT_CRITICAL(false);
13891db9311SSu Sung Chung return;
1390e1c42fdSDave Airlie }
1400e1c42fdSDave Airlie
141d9e32672SAnthony Koo dal_hw_hpd_construct(*hw_hpd, id, en, ctx);
1424562236bSHarry Wentland }
1434562236bSHarry Wentland
dal_hw_hpd_get_pin(struct gpio * gpio)14491db9311SSu Sung Chung struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio)
14591db9311SSu Sung Chung {
14691db9311SSu Sung Chung struct hw_hpd *hw_hpd = dal_gpio_get_hpd(gpio);
14791db9311SSu Sung Chung
14891db9311SSu Sung Chung return &hw_hpd->base.base;
1494562236bSHarry Wentland }
150