linux/drivers/hte/hte-tegra194.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2021-2022 NVIDIA Corporation
   4 *
   5 * Author: Dipen Patel <dipenp@nvidia.com>
   6 */
   7
   8#include <linux/err.h>
   9#include <linux/io.h>
  10#include <linux/module.h>
  11#include <linux/slab.h>
  12#include <linux/stat.h>
  13#include <linux/interrupt.h>
  14#include <linux/of.h>
  15#include <linux/of_device.h>
  16#include <linux/platform_device.h>
  17#include <linux/hte.h>
  18#include <linux/uaccess.h>
  19#include <linux/gpio/driver.h>
  20#include <linux/gpio/consumer.h>
  21
  22#define HTE_SUSPEND     0
  23
  24/* HTE source clock TSC is 31.25MHz */
  25#define HTE_TS_CLK_RATE_HZ      31250000ULL
  26#define HTE_CLK_RATE_NS         32
  27#define HTE_TS_NS_SHIFT __builtin_ctz(HTE_CLK_RATE_NS)
  28
  29#define NV_AON_SLICE_INVALID    -1
  30#define NV_LINES_IN_SLICE       32
  31
  32/* AON HTE line map For slice 1 */
  33#define NV_AON_HTE_SLICE1_IRQ_GPIO_28   12
  34#define NV_AON_HTE_SLICE1_IRQ_GPIO_29   13
  35
  36/* AON HTE line map For slice 2 */
  37#define NV_AON_HTE_SLICE2_IRQ_GPIO_0    0
  38#define NV_AON_HTE_SLICE2_IRQ_GPIO_1    1
  39#define NV_AON_HTE_SLICE2_IRQ_GPIO_2    2
  40#define NV_AON_HTE_SLICE2_IRQ_GPIO_3    3
  41#define NV_AON_HTE_SLICE2_IRQ_GPIO_4    4
  42#define NV_AON_HTE_SLICE2_IRQ_GPIO_5    5
  43#define NV_AON_HTE_SLICE2_IRQ_GPIO_6    6
  44#define NV_AON_HTE_SLICE2_IRQ_GPIO_7    7
  45#define NV_AON_HTE_SLICE2_IRQ_GPIO_8    8
  46#define NV_AON_HTE_SLICE2_IRQ_GPIO_9    9
  47#define NV_AON_HTE_SLICE2_IRQ_GPIO_10   10
  48#define NV_AON_HTE_SLICE2_IRQ_GPIO_11   11
  49#define NV_AON_HTE_SLICE2_IRQ_GPIO_12   12
  50#define NV_AON_HTE_SLICE2_IRQ_GPIO_13   13
  51#define NV_AON_HTE_SLICE2_IRQ_GPIO_14   14
  52#define NV_AON_HTE_SLICE2_IRQ_GPIO_15   15
  53#define NV_AON_HTE_SLICE2_IRQ_GPIO_16   16
  54#define NV_AON_HTE_SLICE2_IRQ_GPIO_17   17
  55#define NV_AON_HTE_SLICE2_IRQ_GPIO_18   18
  56#define NV_AON_HTE_SLICE2_IRQ_GPIO_19   19
  57#define NV_AON_HTE_SLICE2_IRQ_GPIO_20   20
  58#define NV_AON_HTE_SLICE2_IRQ_GPIO_21   21
  59#define NV_AON_HTE_SLICE2_IRQ_GPIO_22   22
  60#define NV_AON_HTE_SLICE2_IRQ_GPIO_23   23
  61#define NV_AON_HTE_SLICE2_IRQ_GPIO_24   24
  62#define NV_AON_HTE_SLICE2_IRQ_GPIO_25   25
  63#define NV_AON_HTE_SLICE2_IRQ_GPIO_26   26
  64#define NV_AON_HTE_SLICE2_IRQ_GPIO_27   27
  65
  66#define HTE_TECTRL              0x0
  67#define HTE_TETSCH              0x4
  68#define HTE_TETSCL              0x8
  69#define HTE_TESRC               0xC
  70#define HTE_TECCV               0x10
  71#define HTE_TEPCV               0x14
  72#define HTE_TECMD               0x1C
  73#define HTE_TESTATUS            0x20
  74#define HTE_SLICE0_TETEN        0x40
  75#define HTE_SLICE1_TETEN        0x60
  76
  77#define HTE_SLICE_SIZE          (HTE_SLICE1_TETEN - HTE_SLICE0_TETEN)
  78
  79#define HTE_TECTRL_ENABLE_ENABLE        0x1
  80
  81#define HTE_TECTRL_OCCU_SHIFT           0x8
  82#define HTE_TECTRL_INTR_SHIFT           0x1
  83#define HTE_TECTRL_INTR_ENABLE          0x1
  84
  85#define HTE_TESRC_SLICE_SHIFT           16
  86#define HTE_TESRC_SLICE_DEFAULT_MASK    0xFF
  87
  88#define HTE_TECMD_CMD_POP               0x1
  89
  90#define HTE_TESTATUS_OCCUPANCY_SHIFT    8
  91#define HTE_TESTATUS_OCCUPANCY_MASK     0xFF
  92
  93enum tegra_hte_type {
  94        HTE_TEGRA_TYPE_GPIO = 1U << 0,
  95        HTE_TEGRA_TYPE_LIC = 1U << 1,
  96};
  97
  98struct hte_slices {
  99        u32 r_val;
 100        unsigned long flags;
 101        /* to prevent lines mapped to same slice updating its register */
 102        spinlock_t s_lock;
 103};
 104
 105struct tegra_hte_line_mapped {
 106        int slice;
 107        u32 bit_index;
 108};
 109
 110struct tegra_hte_line_data {
 111        unsigned long flags;
 112        void *data;
 113};
 114
 115struct tegra_hte_data {
 116        enum tegra_hte_type type;
 117        u32 map_sz;
 118        u32 sec_map_sz;
 119        const struct tegra_hte_line_mapped *map;
 120        const struct tegra_hte_line_mapped *sec_map;
 121};
 122
 123struct tegra_hte_soc {
 124        int hte_irq;
 125        u32 itr_thrshld;
 126        u32 conf_rval;
 127        struct hte_slices *sl;
 128        const struct tegra_hte_data *prov_data;
 129        struct tegra_hte_line_data *line_data;
 130        struct hte_chip *chip;
 131        struct gpio_chip *c;
 132        void __iomem *regs;
 133};
 134
 135static const struct tegra_hte_line_mapped tegra194_aon_gpio_map[] = {
 136        /* gpio, slice, bit_index */
 137        /* AA port */
 138        [0]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_11},
 139        [1]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_10},
 140        [2]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_9},
 141        [3]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_8},
 142        [4]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_7},
 143        [5]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_6},
 144        [6]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_5},
 145        [7]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_4},
 146        /* BB port */
 147        [8]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_3},
 148        [9]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_2},
 149        [10] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_1},
 150        [11] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_0},
 151        /* CC port */
 152        [12] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_22},
 153        [13] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_21},
 154        [14] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_20},
 155        [15] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_19},
 156        [16] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_18},
 157        [17] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_17},
 158        [18] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_16},
 159        [19] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_15},
 160        /* DD port */
 161        [20] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_14},
 162        [21] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_13},
 163        [22] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_12},
 164        /* EE port */
 165        [23] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_29},
 166        [24] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_28},
 167        [25] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_27},
 168        [26] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_26},
 169        [27] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_25},
 170        [28] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_24},
 171        [29] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_23},
 172};
 173
 174static const struct tegra_hte_line_mapped tegra194_aon_gpio_sec_map[] = {
 175        /* gpio, slice, bit_index */
 176        /* AA port */
 177        [0]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_11},
 178        [1]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_10},
 179        [2]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_9},
 180        [3]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_8},
 181        [4]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_7},
 182        [5]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_6},
 183        [6]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_5},
 184        [7]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_4},
 185        /* BB port */
 186        [8]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_3},
 187        [9]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_2},
 188        [10] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_1},
 189        [11] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_0},
 190        [12]  = {NV_AON_SLICE_INVALID, 0},
 191        [13]  = {NV_AON_SLICE_INVALID, 0},
 192        [14] = {NV_AON_SLICE_INVALID, 0},
 193        [15] = {NV_AON_SLICE_INVALID, 0},
 194        /* CC port */
 195        [16] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_22},
 196        [17] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_21},
 197        [18] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_20},
 198        [19] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_19},
 199        [20] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_18},
 200        [21] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_17},
 201        [22] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_16},
 202        [23] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_15},
 203        /* DD port */
 204        [24] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_14},
 205        [25] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_13},
 206        [26] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_12},
 207        [27] = {NV_AON_SLICE_INVALID, 0},
 208        [28] = {NV_AON_SLICE_INVALID, 0},
 209        [29] = {NV_AON_SLICE_INVALID, 0},
 210        [30] = {NV_AON_SLICE_INVALID, 0},
 211        [31] = {NV_AON_SLICE_INVALID, 0},
 212        /* EE port */
 213        [32] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_29},
 214        [33] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_28},
 215        [34] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_27},
 216        [35] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_26},
 217        [36] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_25},
 218        [37] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_24},
 219        [38] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_23},
 220        [39] = {NV_AON_SLICE_INVALID, 0},
 221};
 222
 223static const struct tegra_hte_data aon_hte = {
 224        .map_sz = ARRAY_SIZE(tegra194_aon_gpio_map),
 225        .map = tegra194_aon_gpio_map,
 226        .sec_map_sz = ARRAY_SIZE(tegra194_aon_gpio_sec_map),
 227        .sec_map = tegra194_aon_gpio_sec_map,
 228        .type = HTE_TEGRA_TYPE_GPIO,
 229};
 230
 231static const struct tegra_hte_data lic_hte = {
 232        .map_sz = 0,
 233        .map = NULL,
 234        .type = HTE_TEGRA_TYPE_LIC,
 235};
 236
 237static inline u32 tegra_hte_readl(struct tegra_hte_soc *hte, u32 reg)
 238{
 239        return readl(hte->regs + reg);
 240}
 241
 242static inline void tegra_hte_writel(struct tegra_hte_soc *hte, u32 reg,
 243                                    u32 val)
 244{
 245        writel(val, hte->regs + reg);
 246}
 247
 248static int tegra_hte_map_to_line_id(u32 eid,
 249                                    const struct tegra_hte_line_mapped *m,
 250                                    u32 map_sz, u32 *mapped)
 251{
 252
 253        if (m) {
 254                if (eid > map_sz)
 255                        return -EINVAL;
 256                if (m[eid].slice == NV_AON_SLICE_INVALID)
 257                        return -EINVAL;
 258
 259                *mapped = (m[eid].slice << 5) + m[eid].bit_index;
 260        } else {
 261                *mapped = eid;
 262        }
 263
 264        return 0;
 265}
 266
 267static int tegra_hte_line_xlate(struct hte_chip *gc,
 268                                const struct of_phandle_args *args,
 269                                struct hte_ts_desc *desc, u32 *xlated_id)
 270{
 271        int ret = 0;
 272        u32 line_id;
 273        struct tegra_hte_soc *gs;
 274        const struct tegra_hte_line_mapped *map = NULL;
 275        u32 map_sz = 0;
 276
 277        if (!gc || !desc || !xlated_id)
 278                return -EINVAL;
 279
 280        if (args) {
 281                if (gc->of_hte_n_cells < 1)
 282                        return -EINVAL;
 283
 284                if (args->args_count != gc->of_hte_n_cells)
 285                        return -EINVAL;
 286
 287                desc->attr.line_id = args->args[0];
 288        }
 289
 290        gs = gc->data;
 291        if (!gs || !gs->prov_data)
 292                return -EINVAL;
 293
 294        /*
 295         *
 296         * There are two paths GPIO consumers can take as follows:
 297         * 1) The consumer (gpiolib-cdev for example) which uses GPIO global
 298         * number which gets assigned run time.
 299         * 2) The consumer passing GPIO from the DT which is assigned
 300         * statically for example by using TEGRA194_AON_GPIO gpio DT binding.
 301         *
 302         * The code below addresses both the consumer use cases and maps into
 303         * HTE/GTE namespace.
 304         */
 305        if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO && !args) {
 306                line_id = desc->attr.line_id - gs->c->base;
 307                map = gs->prov_data->map;
 308                map_sz = gs->prov_data->map_sz;
 309        } else if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO && args) {
 310                line_id = desc->attr.line_id;
 311                map = gs->prov_data->sec_map;
 312                map_sz = gs->prov_data->sec_map_sz;
 313        } else {
 314                line_id = desc->attr.line_id;
 315        }
 316
 317        ret = tegra_hte_map_to_line_id(line_id, map, map_sz, xlated_id);
 318        if (ret < 0) {
 319                dev_err(gc->dev, "line_id:%u mapping failed\n",
 320                        desc->attr.line_id);
 321                return ret;
 322        }
 323
 324        if (*xlated_id > gc->nlines)
 325                return -EINVAL;
 326
 327        dev_dbg(gc->dev, "requested id:%u, xlated id:%u\n",
 328                desc->attr.line_id, *xlated_id);
 329
 330        return 0;
 331}
 332
 333static int tegra_hte_line_xlate_plat(struct hte_chip *gc,
 334                                     struct hte_ts_desc *desc, u32 *xlated_id)
 335{
 336        return tegra_hte_line_xlate(gc, NULL, desc, xlated_id);
 337}
 338
 339static int tegra_hte_en_dis_common(struct hte_chip *chip, u32 line_id, bool en)
 340{
 341        u32 slice, sl_bit_shift, line_bit, val, reg;
 342        struct tegra_hte_soc *gs;
 343
 344        sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
 345
 346        if (!chip)
 347                return -EINVAL;
 348
 349        gs = chip->data;
 350
 351        if (line_id > chip->nlines) {
 352                dev_err(chip->dev,
 353                        "line id: %u is not supported by this controller\n",
 354                        line_id);
 355                return -EINVAL;
 356        }
 357
 358        slice = line_id >> sl_bit_shift;
 359        line_bit = line_id & (HTE_SLICE_SIZE - 1);
 360        reg = (slice << sl_bit_shift) + HTE_SLICE0_TETEN;
 361
 362        spin_lock(&gs->sl[slice].s_lock);
 363
 364        if (test_bit(HTE_SUSPEND, &gs->sl[slice].flags)) {
 365                spin_unlock(&gs->sl[slice].s_lock);
 366                dev_dbg(chip->dev, "device suspended");
 367                return -EBUSY;
 368        }
 369
 370        val = tegra_hte_readl(gs, reg);
 371        if (en)
 372                val = val | (1 << line_bit);
 373        else
 374                val = val & (~(1 << line_bit));
 375        tegra_hte_writel(gs, reg, val);
 376
 377        spin_unlock(&gs->sl[slice].s_lock);
 378
 379        dev_dbg(chip->dev, "line: %u, slice %u, line_bit %u, reg:0x%x\n",
 380                line_id, slice, line_bit, reg);
 381
 382        return 0;
 383}
 384
 385static int tegra_hte_enable(struct hte_chip *chip, u32 line_id)
 386{
 387        if (!chip)
 388                return -EINVAL;
 389
 390        return tegra_hte_en_dis_common(chip, line_id, true);
 391}
 392
 393static int tegra_hte_disable(struct hte_chip *chip, u32 line_id)
 394{
 395        if (!chip)
 396                return -EINVAL;
 397
 398        return tegra_hte_en_dis_common(chip, line_id, false);
 399}
 400
 401static int tegra_hte_request(struct hte_chip *chip, struct hte_ts_desc *desc,
 402                             u32 line_id)
 403{
 404        int ret;
 405        struct tegra_hte_soc *gs;
 406        struct hte_line_attr *attr;
 407
 408        if (!chip || !chip->data || !desc)
 409                return -EINVAL;
 410
 411        gs = chip->data;
 412        attr = &desc->attr;
 413
 414        if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
 415                if (!attr->line_data)
 416                        return -EINVAL;
 417
 418                ret = gpiod_enable_hw_timestamp_ns(attr->line_data,
 419                                                   attr->edge_flags);
 420                if (ret)
 421                        return ret;
 422
 423                gs->line_data[line_id].data = attr->line_data;
 424                gs->line_data[line_id].flags = attr->edge_flags;
 425        }
 426
 427        return tegra_hte_en_dis_common(chip, line_id, true);
 428}
 429
 430static int tegra_hte_release(struct hte_chip *chip, struct hte_ts_desc *desc,
 431                             u32 line_id)
 432{
 433        struct tegra_hte_soc *gs;
 434        struct hte_line_attr *attr;
 435        int ret;
 436
 437        if (!chip || !chip->data || !desc)
 438                return -EINVAL;
 439
 440        gs = chip->data;
 441        attr = &desc->attr;
 442
 443        if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
 444                ret = gpiod_disable_hw_timestamp_ns(attr->line_data,
 445                                                    gs->line_data[line_id].flags);
 446                if (ret)
 447                        return ret;
 448
 449                gs->line_data[line_id].data = NULL;
 450                gs->line_data[line_id].flags = 0;
 451        }
 452
 453        return tegra_hte_en_dis_common(chip, line_id, false);
 454}
 455
 456static int tegra_hte_clk_src_info(struct hte_chip *chip,
 457                                  struct hte_clk_info *ci)
 458{
 459        (void)chip;
 460
 461        if (!ci)
 462                return -EINVAL;
 463
 464        ci->hz = HTE_TS_CLK_RATE_HZ;
 465        ci->type = CLOCK_MONOTONIC;
 466
 467        return 0;
 468}
 469
 470static int tegra_hte_get_level(struct tegra_hte_soc *gs, u32 line_id)
 471{
 472        struct gpio_desc *desc;
 473
 474        if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
 475                desc = gs->line_data[line_id].data;
 476                if (desc)
 477                        return gpiod_get_raw_value(desc);
 478        }
 479
 480        return -1;
 481}
 482
 483static void tegra_hte_read_fifo(struct tegra_hte_soc *gs)
 484{
 485        u32 tsh, tsl, src, pv, cv, acv, slice, bit_index, line_id;
 486        u64 tsc;
 487        struct hte_ts_data el;
 488
 489        while ((tegra_hte_readl(gs, HTE_TESTATUS) >>
 490                HTE_TESTATUS_OCCUPANCY_SHIFT) &
 491                HTE_TESTATUS_OCCUPANCY_MASK) {
 492                tsh = tegra_hte_readl(gs, HTE_TETSCH);
 493                tsl = tegra_hte_readl(gs, HTE_TETSCL);
 494                tsc = (((u64)tsh << 32) | tsl);
 495
 496                src = tegra_hte_readl(gs, HTE_TESRC);
 497                slice = (src >> HTE_TESRC_SLICE_SHIFT) &
 498                            HTE_TESRC_SLICE_DEFAULT_MASK;
 499
 500                pv = tegra_hte_readl(gs, HTE_TEPCV);
 501                cv = tegra_hte_readl(gs, HTE_TECCV);
 502                acv = pv ^ cv;
 503                while (acv) {
 504                        bit_index = __builtin_ctz(acv);
 505                        line_id = bit_index + (slice << 5);
 506                        el.tsc = tsc << HTE_TS_NS_SHIFT;
 507                        el.raw_level = tegra_hte_get_level(gs, line_id);
 508                        hte_push_ts_ns(gs->chip, line_id, &el);
 509                        acv &= ~BIT(bit_index);
 510                }
 511                tegra_hte_writel(gs, HTE_TECMD, HTE_TECMD_CMD_POP);
 512        }
 513}
 514
 515static irqreturn_t tegra_hte_isr(int irq, void *dev_id)
 516{
 517        struct tegra_hte_soc *gs = dev_id;
 518        (void)irq;
 519
 520        tegra_hte_read_fifo(gs);
 521
 522        return IRQ_HANDLED;
 523}
 524
 525static bool tegra_hte_match_from_linedata(const struct hte_chip *chip,
 526                                          const struct hte_ts_desc *hdesc)
 527{
 528        struct tegra_hte_soc *hte_dev = chip->data;
 529
 530        if (!hte_dev || (hte_dev->prov_data->type != HTE_TEGRA_TYPE_GPIO))
 531                return false;
 532
 533        return hte_dev->c == gpiod_to_chip(hdesc->attr.line_data);
 534}
 535
 536static const struct of_device_id tegra_hte_of_match[] = {
 537        { .compatible = "nvidia,tegra194-gte-lic", .data = &lic_hte},
 538        { .compatible = "nvidia,tegra194-gte-aon", .data = &aon_hte},
 539        { }
 540};
 541MODULE_DEVICE_TABLE(of, tegra_hte_of_match);
 542
 543static const struct hte_ops g_ops = {
 544        .request = tegra_hte_request,
 545        .release = tegra_hte_release,
 546        .enable = tegra_hte_enable,
 547        .disable = tegra_hte_disable,
 548        .get_clk_src_info = tegra_hte_clk_src_info,
 549};
 550
 551static void tegra_gte_disable(void *data)
 552{
 553        struct platform_device *pdev = data;
 554        struct tegra_hte_soc *gs = dev_get_drvdata(&pdev->dev);
 555
 556        tegra_hte_writel(gs, HTE_TECTRL, 0);
 557}
 558
 559static int tegra_get_gpiochip_from_name(struct gpio_chip *chip, void *data)
 560{
 561        return !strcmp(chip->label, data);
 562}
 563
 564static int tegra_hte_probe(struct platform_device *pdev)
 565{
 566        int ret;
 567        u32 i, slices, val = 0;
 568        u32 nlines;
 569        struct device *dev;
 570        struct tegra_hte_soc *hte_dev;
 571        struct hte_chip *gc;
 572
 573        dev = &pdev->dev;
 574
 575        ret = of_property_read_u32(dev->of_node, "nvidia,slices", &slices);
 576        if (ret != 0) {
 577                dev_err(dev, "Could not read slices\n");
 578                return -EINVAL;
 579        }
 580        nlines = slices << 5;
 581
 582        hte_dev = devm_kzalloc(dev, sizeof(*hte_dev), GFP_KERNEL);
 583        if (!hte_dev)
 584                return -ENOMEM;
 585
 586        gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
 587        if (!gc)
 588                return -ENOMEM;
 589
 590        dev_set_drvdata(&pdev->dev, hte_dev);
 591        hte_dev->prov_data = of_device_get_match_data(&pdev->dev);
 592
 593        hte_dev->regs = devm_platform_ioremap_resource(pdev, 0);
 594        if (IS_ERR(hte_dev->regs))
 595                return PTR_ERR(hte_dev->regs);
 596
 597        ret = of_property_read_u32(dev->of_node, "nvidia,int-threshold",
 598                                   &hte_dev->itr_thrshld);
 599        if (ret != 0)
 600                hte_dev->itr_thrshld = 1;
 601
 602        hte_dev->sl = devm_kcalloc(dev, slices, sizeof(*hte_dev->sl),
 603                                   GFP_KERNEL);
 604        if (!hte_dev->sl)
 605                return -ENOMEM;
 606
 607        ret = platform_get_irq(pdev, 0);
 608        if (ret < 0) {
 609                dev_err_probe(dev, ret, "failed to get irq\n");
 610                return ret;
 611        }
 612        hte_dev->hte_irq = ret;
 613        ret = devm_request_irq(dev, hte_dev->hte_irq, tegra_hte_isr, 0,
 614                               dev_name(dev), hte_dev);
 615        if (ret < 0) {
 616                dev_err(dev, "request irq failed.\n");
 617                return ret;
 618        }
 619
 620        gc->nlines = nlines;
 621        gc->ops = &g_ops;
 622        gc->dev = dev;
 623        gc->data = hte_dev;
 624        gc->xlate_of = tegra_hte_line_xlate;
 625        gc->xlate_plat = tegra_hte_line_xlate_plat;
 626        gc->of_hte_n_cells = 1;
 627
 628        if (hte_dev->prov_data &&
 629            hte_dev->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
 630                hte_dev->line_data = devm_kcalloc(dev, nlines,
 631                                                  sizeof(*hte_dev->line_data),
 632                                                  GFP_KERNEL);
 633                if (!hte_dev->line_data)
 634                        return -ENOMEM;
 635
 636                gc->match_from_linedata = tegra_hte_match_from_linedata;
 637
 638                hte_dev->c = gpiochip_find("tegra194-gpio-aon",
 639                                           tegra_get_gpiochip_from_name);
 640                if (!hte_dev->c)
 641                        return dev_err_probe(dev, -EPROBE_DEFER,
 642                                             "wait for gpio controller\n");
 643        }
 644
 645        hte_dev->chip = gc;
 646
 647        ret = devm_hte_register_chip(hte_dev->chip);
 648        if (ret) {
 649                dev_err(gc->dev, "hte chip register failed");
 650                return ret;
 651        }
 652
 653        for (i = 0; i < slices; i++) {
 654                hte_dev->sl[i].flags = 0;
 655                spin_lock_init(&hte_dev->sl[i].s_lock);
 656        }
 657
 658        val = HTE_TECTRL_ENABLE_ENABLE |
 659              (HTE_TECTRL_INTR_ENABLE << HTE_TECTRL_INTR_SHIFT) |
 660              (hte_dev->itr_thrshld << HTE_TECTRL_OCCU_SHIFT);
 661        tegra_hte_writel(hte_dev, HTE_TECTRL, val);
 662
 663        ret = devm_add_action_or_reset(&pdev->dev, tegra_gte_disable, pdev);
 664        if (ret)
 665                return ret;
 666
 667        dev_dbg(gc->dev, "lines: %d, slices:%d", gc->nlines, slices);
 668
 669        return 0;
 670}
 671
 672static int __maybe_unused tegra_hte_resume_early(struct device *dev)
 673{
 674        u32 i;
 675        struct tegra_hte_soc *gs = dev_get_drvdata(dev);
 676        u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
 677        u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
 678
 679        tegra_hte_writel(gs, HTE_TECTRL, gs->conf_rval);
 680
 681        for (i = 0; i < slices; i++) {
 682                spin_lock(&gs->sl[i].s_lock);
 683                tegra_hte_writel(gs,
 684                                 ((i << sl_bit_shift) + HTE_SLICE0_TETEN),
 685                                 gs->sl[i].r_val);
 686                clear_bit(HTE_SUSPEND, &gs->sl[i].flags);
 687                spin_unlock(&gs->sl[i].s_lock);
 688        }
 689
 690        return 0;
 691}
 692
 693static int __maybe_unused tegra_hte_suspend_late(struct device *dev)
 694{
 695        u32 i;
 696        struct tegra_hte_soc *gs = dev_get_drvdata(dev);
 697        u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
 698        u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
 699
 700        gs->conf_rval = tegra_hte_readl(gs, HTE_TECTRL);
 701        for (i = 0; i < slices; i++) {
 702                spin_lock(&gs->sl[i].s_lock);
 703                gs->sl[i].r_val = tegra_hte_readl(gs,
 704                                ((i << sl_bit_shift) + HTE_SLICE0_TETEN));
 705                set_bit(HTE_SUSPEND, &gs->sl[i].flags);
 706                spin_unlock(&gs->sl[i].s_lock);
 707        }
 708
 709        return 0;
 710}
 711
 712static const struct dev_pm_ops tegra_hte_pm = {
 713        SET_LATE_SYSTEM_SLEEP_PM_OPS(tegra_hte_suspend_late,
 714                                     tegra_hte_resume_early)
 715};
 716
 717static struct platform_driver tegra_hte_driver = {
 718        .probe = tegra_hte_probe,
 719        .driver = {
 720                .name = "tegra_hte",
 721                .pm = &tegra_hte_pm,
 722                .of_match_table = tegra_hte_of_match,
 723        },
 724};
 725
 726module_platform_driver(tegra_hte_driver);
 727
 728MODULE_AUTHOR("Dipen Patel <dipenp@nvidia.com>");
 729MODULE_DESCRIPTION("NVIDIA Tegra HTE (Hardware Timestamping Engine) driver");
 730MODULE_LICENSE("GPL");
 731