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