linux/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013-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/*
  27 * Pre-requisites: headers required by header of this unit
  28 */
  29
  30#include "hw_translate_dce120.h"
  31
  32#include "dm_services.h"
  33#include "include/gpio_types.h"
  34#include "../hw_translate.h"
  35
  36#include "dce/dce_12_0_offset.h"
  37#include "dce/dce_12_0_sh_mask.h"
  38#include "soc15_hw_ip.h"
  39#include "vega10_ip_offset.h"
  40
  41/* begin *********************
  42 * macros to expend register list macro defined in HW object header file */
  43
  44#define BASE_INNER(seg) \
  45        DCE_BASE__INST0_SEG ## seg
  46
  47/* compile time expand base address. */
  48#define BASE(seg) \
  49        BASE_INNER(seg)
  50
  51#define REG(reg_name)\
  52                BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name
  53
  54#define REGI(reg_name, block, id)\
  55        BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
  56                                mm ## block ## id ## _ ## reg_name
  57
  58/* macros to expend register list macro defined in HW object header file
  59 * end *********************/
  60
  61static bool offset_to_id(
  62        uint32_t offset,
  63        uint32_t mask,
  64        enum gpio_id *id,
  65        uint32_t *en)
  66{
  67        switch (offset) {
  68        /* GENERIC */
  69        case REG(DC_GPIO_GENERIC_A):
  70                *id = GPIO_ID_GENERIC;
  71                switch (mask) {
  72                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
  73                        *en = GPIO_GENERIC_A;
  74                        return true;
  75                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
  76                        *en = GPIO_GENERIC_B;
  77                        return true;
  78                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
  79                        *en = GPIO_GENERIC_C;
  80                        return true;
  81                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
  82                        *en = GPIO_GENERIC_D;
  83                        return true;
  84                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
  85                        *en = GPIO_GENERIC_E;
  86                        return true;
  87                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
  88                        *en = GPIO_GENERIC_F;
  89                        return true;
  90                case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
  91                        *en = GPIO_GENERIC_G;
  92                        return true;
  93                default:
  94                        ASSERT_CRITICAL(false);
  95                        return false;
  96                }
  97        break;
  98        /* HPD */
  99        case REG(DC_GPIO_HPD_A):
 100                *id = GPIO_ID_HPD;
 101                switch (mask) {
 102                case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
 103                        *en = GPIO_HPD_1;
 104                        return true;
 105                case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
 106                        *en = GPIO_HPD_2;
 107                        return true;
 108                case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
 109                        *en = GPIO_HPD_3;
 110                        return true;
 111                case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
 112                        *en = GPIO_HPD_4;
 113                        return true;
 114                case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
 115                        *en = GPIO_HPD_5;
 116                        return true;
 117                case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
 118                        *en = GPIO_HPD_6;
 119                        return true;
 120                default:
 121                        ASSERT_CRITICAL(false);
 122                        return false;
 123                }
 124        break;
 125        /* SYNCA */
 126        case REG(DC_GPIO_SYNCA_A):
 127                *id = GPIO_ID_SYNC;
 128                switch (mask) {
 129                case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
 130                        *en = GPIO_SYNC_HSYNC_A;
 131                        return true;
 132                case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
 133                        *en = GPIO_SYNC_VSYNC_A;
 134                        return true;
 135                default:
 136                        ASSERT_CRITICAL(false);
 137                        return false;
 138                }
 139        break;
 140        /* REG(DC_GPIO_GENLK_MASK */
 141        case REG(DC_GPIO_GENLK_A):
 142                *id = GPIO_ID_GSL;
 143                switch (mask) {
 144                case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
 145                        *en = GPIO_GSL_GENLOCK_CLOCK;
 146                        return true;
 147                case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
 148                        *en = GPIO_GSL_GENLOCK_VSYNC;
 149                        return true;
 150                case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
 151                        *en = GPIO_GSL_SWAPLOCK_A;
 152                        return true;
 153                case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
 154                        *en = GPIO_GSL_SWAPLOCK_B;
 155                        return true;
 156                default:
 157                        ASSERT_CRITICAL(false);
 158                        return false;
 159                }
 160        break;
 161        /* DDC */
 162        /* we don't care about the GPIO_ID for DDC
 163         * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
 164         * directly in the create method */
 165        case REG(DC_GPIO_DDC1_A):
 166                *en = GPIO_DDC_LINE_DDC1;
 167                return true;
 168        case REG(DC_GPIO_DDC2_A):
 169                *en = GPIO_DDC_LINE_DDC2;
 170                return true;
 171        case REG(DC_GPIO_DDC3_A):
 172                *en = GPIO_DDC_LINE_DDC3;
 173                return true;
 174        case REG(DC_GPIO_DDC4_A):
 175                *en = GPIO_DDC_LINE_DDC4;
 176                return true;
 177        case REG(DC_GPIO_DDC5_A):
 178                *en = GPIO_DDC_LINE_DDC5;
 179                return true;
 180        case REG(DC_GPIO_DDC6_A):
 181                *en = GPIO_DDC_LINE_DDC6;
 182                return true;
 183        case REG(DC_GPIO_DDCVGA_A):
 184                *en = GPIO_DDC_LINE_DDC_VGA;
 185                return true;
 186        /* GPIO_I2CPAD */
 187        case REG(DC_GPIO_I2CPAD_A):
 188                *en = GPIO_DDC_LINE_I2C_PAD;
 189                return true;
 190        /* Not implemented */
 191        case REG(DC_GPIO_PWRSEQ_A):
 192        case REG(DC_GPIO_PAD_STRENGTH_1):
 193        case REG(DC_GPIO_PAD_STRENGTH_2):
 194        case REG(DC_GPIO_DEBUG):
 195                return false;
 196        /* UNEXPECTED */
 197        default:
 198                ASSERT_CRITICAL(false);
 199                return false;
 200        }
 201}
 202
 203static bool id_to_offset(
 204        enum gpio_id id,
 205        uint32_t en,
 206        struct gpio_pin_info *info)
 207{
 208        bool result = true;
 209
 210        switch (id) {
 211        case GPIO_ID_DDC_DATA:
 212                info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 213                switch (en) {
 214                case GPIO_DDC_LINE_DDC1:
 215                        info->offset = REG(DC_GPIO_DDC1_A);
 216                break;
 217                case GPIO_DDC_LINE_DDC2:
 218                        info->offset = REG(DC_GPIO_DDC2_A);
 219                break;
 220                case GPIO_DDC_LINE_DDC3:
 221                        info->offset = REG(DC_GPIO_DDC3_A);
 222                break;
 223                case GPIO_DDC_LINE_DDC4:
 224                        info->offset = REG(DC_GPIO_DDC4_A);
 225                break;
 226                case GPIO_DDC_LINE_DDC5:
 227                        info->offset = REG(DC_GPIO_DDC5_A);
 228                break;
 229                case GPIO_DDC_LINE_DDC6:
 230                        info->offset = REG(DC_GPIO_DDC6_A);
 231                break;
 232                case GPIO_DDC_LINE_DDC_VGA:
 233                        info->offset = REG(DC_GPIO_DDCVGA_A);
 234                break;
 235                case GPIO_DDC_LINE_I2C_PAD:
 236                        info->offset = REG(DC_GPIO_I2CPAD_A);
 237                break;
 238                default:
 239                        ASSERT_CRITICAL(false);
 240                        result = false;
 241                }
 242        break;
 243        case GPIO_ID_DDC_CLOCK:
 244                info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
 245                switch (en) {
 246                case GPIO_DDC_LINE_DDC1:
 247                        info->offset = REG(DC_GPIO_DDC1_A);
 248                break;
 249                case GPIO_DDC_LINE_DDC2:
 250                        info->offset = REG(DC_GPIO_DDC2_A);
 251                break;
 252                case GPIO_DDC_LINE_DDC3:
 253                        info->offset = REG(DC_GPIO_DDC3_A);
 254                break;
 255                case GPIO_DDC_LINE_DDC4:
 256                        info->offset = REG(DC_GPIO_DDC4_A);
 257                break;
 258                case GPIO_DDC_LINE_DDC5:
 259                        info->offset = REG(DC_GPIO_DDC5_A);
 260                break;
 261                case GPIO_DDC_LINE_DDC6:
 262                        info->offset = REG(DC_GPIO_DDC6_A);
 263                break;
 264                case GPIO_DDC_LINE_DDC_VGA:
 265                        info->offset = REG(DC_GPIO_DDCVGA_A);
 266                break;
 267                case GPIO_DDC_LINE_I2C_PAD:
 268                        info->offset = REG(DC_GPIO_I2CPAD_A);
 269                break;
 270                default:
 271                        ASSERT_CRITICAL(false);
 272                        result = false;
 273                }
 274        break;
 275        case GPIO_ID_GENERIC:
 276                info->offset = REG(DC_GPIO_GENERIC_A);
 277                switch (en) {
 278                case GPIO_GENERIC_A:
 279                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
 280                break;
 281                case GPIO_GENERIC_B:
 282                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
 283                break;
 284                case GPIO_GENERIC_C:
 285                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
 286                break;
 287                case GPIO_GENERIC_D:
 288                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
 289                break;
 290                case GPIO_GENERIC_E:
 291                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
 292                break;
 293                case GPIO_GENERIC_F:
 294                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
 295                break;
 296                case GPIO_GENERIC_G:
 297                        info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
 298                break;
 299                default:
 300                        ASSERT_CRITICAL(false);
 301                        result = false;
 302                }
 303        break;
 304        case GPIO_ID_HPD:
 305                info->offset = REG(DC_GPIO_HPD_A);
 306                switch (en) {
 307                case GPIO_HPD_1:
 308                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
 309                break;
 310                case GPIO_HPD_2:
 311                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
 312                break;
 313                case GPIO_HPD_3:
 314                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
 315                break;
 316                case GPIO_HPD_4:
 317                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
 318                break;
 319                case GPIO_HPD_5:
 320                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
 321                break;
 322                case GPIO_HPD_6:
 323                        info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
 324                break;
 325                default:
 326                        ASSERT_CRITICAL(false);
 327                        result = false;
 328                }
 329        break;
 330        case GPIO_ID_SYNC:
 331                switch (en) {
 332                case GPIO_SYNC_HSYNC_A:
 333                        info->offset = REG(DC_GPIO_SYNCA_A);
 334                        info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
 335                break;
 336                case GPIO_SYNC_VSYNC_A:
 337                        info->offset = REG(DC_GPIO_SYNCA_A);
 338                        info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
 339                break;
 340                case GPIO_SYNC_HSYNC_B:
 341                case GPIO_SYNC_VSYNC_B:
 342                default:
 343                        ASSERT_CRITICAL(false);
 344                        result = false;
 345                }
 346        break;
 347        case GPIO_ID_GSL:
 348                switch (en) {
 349                case GPIO_GSL_GENLOCK_CLOCK:
 350                        info->offset = REG(DC_GPIO_GENLK_A);
 351                        info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
 352                break;
 353                case GPIO_GSL_GENLOCK_VSYNC:
 354                        info->offset = REG(DC_GPIO_GENLK_A);
 355                        info->mask =
 356                                DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
 357                break;
 358                case GPIO_GSL_SWAPLOCK_A:
 359                        info->offset = REG(DC_GPIO_GENLK_A);
 360                        info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
 361                break;
 362                case GPIO_GSL_SWAPLOCK_B:
 363                        info->offset = REG(DC_GPIO_GENLK_A);
 364                        info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
 365                break;
 366                default:
 367                        ASSERT_CRITICAL(false);
 368                        result = false;
 369                }
 370        break;
 371        case GPIO_ID_VIP_PAD:
 372        default:
 373                ASSERT_CRITICAL(false);
 374                result = false;
 375        }
 376
 377        if (result) {
 378                info->offset_y = info->offset + 2;
 379                info->offset_en = info->offset + 1;
 380                info->offset_mask = info->offset - 1;
 381
 382                info->mask_y = info->mask;
 383                info->mask_en = info->mask;
 384                info->mask_mask = info->mask;
 385        }
 386
 387        return result;
 388}
 389
 390/* function table */
 391static const struct hw_translate_funcs funcs = {
 392        .offset_to_id = offset_to_id,
 393        .id_to_offset = id_to_offset,
 394};
 395
 396/*
 397 * dal_hw_translate_dce120_init
 398 *
 399 * @brief
 400 * Initialize Hw translate function pointers.
 401 *
 402 * @param
 403 * struct hw_translate *tr - [out] struct of function pointers
 404 *
 405 */
 406void dal_hw_translate_dce120_init(struct hw_translate *tr)
 407{
 408        tr->funcs = &funcs;
 409}
 410