0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/err.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/slab.h>
0012 #include <linux/stat.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/of.h>
0015 #include <linux/of_device.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/hte.h>
0018 #include <linux/uaccess.h>
0019 #include <linux/gpio/driver.h>
0020 #include <linux/gpio/consumer.h>
0021
0022 #define HTE_SUSPEND 0
0023
0024
0025 #define HTE_TS_CLK_RATE_HZ 31250000ULL
0026 #define HTE_CLK_RATE_NS 32
0027 #define HTE_TS_NS_SHIFT __builtin_ctz(HTE_CLK_RATE_NS)
0028
0029 #define NV_AON_SLICE_INVALID -1
0030 #define NV_LINES_IN_SLICE 32
0031
0032
0033 #define NV_AON_HTE_SLICE1_IRQ_GPIO_28 12
0034 #define NV_AON_HTE_SLICE1_IRQ_GPIO_29 13
0035
0036
0037 #define NV_AON_HTE_SLICE2_IRQ_GPIO_0 0
0038 #define NV_AON_HTE_SLICE2_IRQ_GPIO_1 1
0039 #define NV_AON_HTE_SLICE2_IRQ_GPIO_2 2
0040 #define NV_AON_HTE_SLICE2_IRQ_GPIO_3 3
0041 #define NV_AON_HTE_SLICE2_IRQ_GPIO_4 4
0042 #define NV_AON_HTE_SLICE2_IRQ_GPIO_5 5
0043 #define NV_AON_HTE_SLICE2_IRQ_GPIO_6 6
0044 #define NV_AON_HTE_SLICE2_IRQ_GPIO_7 7
0045 #define NV_AON_HTE_SLICE2_IRQ_GPIO_8 8
0046 #define NV_AON_HTE_SLICE2_IRQ_GPIO_9 9
0047 #define NV_AON_HTE_SLICE2_IRQ_GPIO_10 10
0048 #define NV_AON_HTE_SLICE2_IRQ_GPIO_11 11
0049 #define NV_AON_HTE_SLICE2_IRQ_GPIO_12 12
0050 #define NV_AON_HTE_SLICE2_IRQ_GPIO_13 13
0051 #define NV_AON_HTE_SLICE2_IRQ_GPIO_14 14
0052 #define NV_AON_HTE_SLICE2_IRQ_GPIO_15 15
0053 #define NV_AON_HTE_SLICE2_IRQ_GPIO_16 16
0054 #define NV_AON_HTE_SLICE2_IRQ_GPIO_17 17
0055 #define NV_AON_HTE_SLICE2_IRQ_GPIO_18 18
0056 #define NV_AON_HTE_SLICE2_IRQ_GPIO_19 19
0057 #define NV_AON_HTE_SLICE2_IRQ_GPIO_20 20
0058 #define NV_AON_HTE_SLICE2_IRQ_GPIO_21 21
0059 #define NV_AON_HTE_SLICE2_IRQ_GPIO_22 22
0060 #define NV_AON_HTE_SLICE2_IRQ_GPIO_23 23
0061 #define NV_AON_HTE_SLICE2_IRQ_GPIO_24 24
0062 #define NV_AON_HTE_SLICE2_IRQ_GPIO_25 25
0063 #define NV_AON_HTE_SLICE2_IRQ_GPIO_26 26
0064 #define NV_AON_HTE_SLICE2_IRQ_GPIO_27 27
0065
0066 #define HTE_TECTRL 0x0
0067 #define HTE_TETSCH 0x4
0068 #define HTE_TETSCL 0x8
0069 #define HTE_TESRC 0xC
0070 #define HTE_TECCV 0x10
0071 #define HTE_TEPCV 0x14
0072 #define HTE_TECMD 0x1C
0073 #define HTE_TESTATUS 0x20
0074 #define HTE_SLICE0_TETEN 0x40
0075 #define HTE_SLICE1_TETEN 0x60
0076
0077 #define HTE_SLICE_SIZE (HTE_SLICE1_TETEN - HTE_SLICE0_TETEN)
0078
0079 #define HTE_TECTRL_ENABLE_ENABLE 0x1
0080
0081 #define HTE_TECTRL_OCCU_SHIFT 0x8
0082 #define HTE_TECTRL_INTR_SHIFT 0x1
0083 #define HTE_TECTRL_INTR_ENABLE 0x1
0084
0085 #define HTE_TESRC_SLICE_SHIFT 16
0086 #define HTE_TESRC_SLICE_DEFAULT_MASK 0xFF
0087
0088 #define HTE_TECMD_CMD_POP 0x1
0089
0090 #define HTE_TESTATUS_OCCUPANCY_SHIFT 8
0091 #define HTE_TESTATUS_OCCUPANCY_MASK 0xFF
0092
0093 enum tegra_hte_type {
0094 HTE_TEGRA_TYPE_GPIO = 1U << 0,
0095 HTE_TEGRA_TYPE_LIC = 1U << 1,
0096 };
0097
0098 struct hte_slices {
0099 u32 r_val;
0100 unsigned long flags;
0101
0102 spinlock_t s_lock;
0103 };
0104
0105 struct tegra_hte_line_mapped {
0106 int slice;
0107 u32 bit_index;
0108 };
0109
0110 struct tegra_hte_line_data {
0111 unsigned long flags;
0112 void *data;
0113 };
0114
0115 struct tegra_hte_data {
0116 enum tegra_hte_type type;
0117 u32 map_sz;
0118 u32 sec_map_sz;
0119 const struct tegra_hte_line_mapped *map;
0120 const struct tegra_hte_line_mapped *sec_map;
0121 };
0122
0123 struct tegra_hte_soc {
0124 int hte_irq;
0125 u32 itr_thrshld;
0126 u32 conf_rval;
0127 struct hte_slices *sl;
0128 const struct tegra_hte_data *prov_data;
0129 struct tegra_hte_line_data *line_data;
0130 struct hte_chip *chip;
0131 struct gpio_chip *c;
0132 void __iomem *regs;
0133 };
0134
0135 static const struct tegra_hte_line_mapped tegra194_aon_gpio_map[] = {
0136
0137
0138 [0] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_11},
0139 [1] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_10},
0140 [2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_9},
0141 [3] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_8},
0142 [4] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_7},
0143 [5] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_6},
0144 [6] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_5},
0145 [7] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_4},
0146
0147 [8] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_3},
0148 [9] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_2},
0149 [10] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_1},
0150 [11] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_0},
0151
0152 [12] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_22},
0153 [13] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_21},
0154 [14] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_20},
0155 [15] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_19},
0156 [16] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_18},
0157 [17] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_17},
0158 [18] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_16},
0159 [19] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_15},
0160
0161 [20] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_14},
0162 [21] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_13},
0163 [22] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_12},
0164
0165 [23] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_29},
0166 [24] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_28},
0167 [25] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_27},
0168 [26] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_26},
0169 [27] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_25},
0170 [28] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_24},
0171 [29] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_23},
0172 };
0173
0174 static const struct tegra_hte_line_mapped tegra194_aon_gpio_sec_map[] = {
0175
0176
0177 [0] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_11},
0178 [1] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_10},
0179 [2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_9},
0180 [3] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_8},
0181 [4] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_7},
0182 [5] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_6},
0183 [6] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_5},
0184 [7] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_4},
0185
0186 [8] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_3},
0187 [9] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_2},
0188 [10] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_1},
0189 [11] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_0},
0190 [12] = {NV_AON_SLICE_INVALID, 0},
0191 [13] = {NV_AON_SLICE_INVALID, 0},
0192 [14] = {NV_AON_SLICE_INVALID, 0},
0193 [15] = {NV_AON_SLICE_INVALID, 0},
0194
0195 [16] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_22},
0196 [17] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_21},
0197 [18] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_20},
0198 [19] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_19},
0199 [20] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_18},
0200 [21] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_17},
0201 [22] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_16},
0202 [23] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_15},
0203
0204 [24] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_14},
0205 [25] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_13},
0206 [26] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_12},
0207 [27] = {NV_AON_SLICE_INVALID, 0},
0208 [28] = {NV_AON_SLICE_INVALID, 0},
0209 [29] = {NV_AON_SLICE_INVALID, 0},
0210 [30] = {NV_AON_SLICE_INVALID, 0},
0211 [31] = {NV_AON_SLICE_INVALID, 0},
0212
0213 [32] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_29},
0214 [33] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_28},
0215 [34] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_27},
0216 [35] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_26},
0217 [36] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_25},
0218 [37] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_24},
0219 [38] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_23},
0220 [39] = {NV_AON_SLICE_INVALID, 0},
0221 };
0222
0223 static const struct tegra_hte_data aon_hte = {
0224 .map_sz = ARRAY_SIZE(tegra194_aon_gpio_map),
0225 .map = tegra194_aon_gpio_map,
0226 .sec_map_sz = ARRAY_SIZE(tegra194_aon_gpio_sec_map),
0227 .sec_map = tegra194_aon_gpio_sec_map,
0228 .type = HTE_TEGRA_TYPE_GPIO,
0229 };
0230
0231 static const struct tegra_hte_data lic_hte = {
0232 .map_sz = 0,
0233 .map = NULL,
0234 .type = HTE_TEGRA_TYPE_LIC,
0235 };
0236
0237 static inline u32 tegra_hte_readl(struct tegra_hte_soc *hte, u32 reg)
0238 {
0239 return readl(hte->regs + reg);
0240 }
0241
0242 static inline void tegra_hte_writel(struct tegra_hte_soc *hte, u32 reg,
0243 u32 val)
0244 {
0245 writel(val, hte->regs + reg);
0246 }
0247
0248 static int tegra_hte_map_to_line_id(u32 eid,
0249 const struct tegra_hte_line_mapped *m,
0250 u32 map_sz, u32 *mapped)
0251 {
0252
0253 if (m) {
0254 if (eid > map_sz)
0255 return -EINVAL;
0256 if (m[eid].slice == NV_AON_SLICE_INVALID)
0257 return -EINVAL;
0258
0259 *mapped = (m[eid].slice << 5) + m[eid].bit_index;
0260 } else {
0261 *mapped = eid;
0262 }
0263
0264 return 0;
0265 }
0266
0267 static int tegra_hte_line_xlate(struct hte_chip *gc,
0268 const struct of_phandle_args *args,
0269 struct hte_ts_desc *desc, u32 *xlated_id)
0270 {
0271 int ret = 0;
0272 u32 line_id;
0273 struct tegra_hte_soc *gs;
0274 const struct tegra_hte_line_mapped *map = NULL;
0275 u32 map_sz = 0;
0276
0277 if (!gc || !desc || !xlated_id)
0278 return -EINVAL;
0279
0280 if (args) {
0281 if (gc->of_hte_n_cells < 1)
0282 return -EINVAL;
0283
0284 if (args->args_count != gc->of_hte_n_cells)
0285 return -EINVAL;
0286
0287 desc->attr.line_id = args->args[0];
0288 }
0289
0290 gs = gc->data;
0291 if (!gs || !gs->prov_data)
0292 return -EINVAL;
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO && !args) {
0306 line_id = desc->attr.line_id - gs->c->base;
0307 map = gs->prov_data->map;
0308 map_sz = gs->prov_data->map_sz;
0309 } else if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO && args) {
0310 line_id = desc->attr.line_id;
0311 map = gs->prov_data->sec_map;
0312 map_sz = gs->prov_data->sec_map_sz;
0313 } else {
0314 line_id = desc->attr.line_id;
0315 }
0316
0317 ret = tegra_hte_map_to_line_id(line_id, map, map_sz, xlated_id);
0318 if (ret < 0) {
0319 dev_err(gc->dev, "line_id:%u mapping failed\n",
0320 desc->attr.line_id);
0321 return ret;
0322 }
0323
0324 if (*xlated_id > gc->nlines)
0325 return -EINVAL;
0326
0327 dev_dbg(gc->dev, "requested id:%u, xlated id:%u\n",
0328 desc->attr.line_id, *xlated_id);
0329
0330 return 0;
0331 }
0332
0333 static int tegra_hte_line_xlate_plat(struct hte_chip *gc,
0334 struct hte_ts_desc *desc, u32 *xlated_id)
0335 {
0336 return tegra_hte_line_xlate(gc, NULL, desc, xlated_id);
0337 }
0338
0339 static int tegra_hte_en_dis_common(struct hte_chip *chip, u32 line_id, bool en)
0340 {
0341 u32 slice, sl_bit_shift, line_bit, val, reg;
0342 struct tegra_hte_soc *gs;
0343
0344 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
0345
0346 if (!chip)
0347 return -EINVAL;
0348
0349 gs = chip->data;
0350
0351 if (line_id > chip->nlines) {
0352 dev_err(chip->dev,
0353 "line id: %u is not supported by this controller\n",
0354 line_id);
0355 return -EINVAL;
0356 }
0357
0358 slice = line_id >> sl_bit_shift;
0359 line_bit = line_id & (HTE_SLICE_SIZE - 1);
0360 reg = (slice << sl_bit_shift) + HTE_SLICE0_TETEN;
0361
0362 spin_lock(&gs->sl[slice].s_lock);
0363
0364 if (test_bit(HTE_SUSPEND, &gs->sl[slice].flags)) {
0365 spin_unlock(&gs->sl[slice].s_lock);
0366 dev_dbg(chip->dev, "device suspended");
0367 return -EBUSY;
0368 }
0369
0370 val = tegra_hte_readl(gs, reg);
0371 if (en)
0372 val = val | (1 << line_bit);
0373 else
0374 val = val & (~(1 << line_bit));
0375 tegra_hte_writel(gs, reg, val);
0376
0377 spin_unlock(&gs->sl[slice].s_lock);
0378
0379 dev_dbg(chip->dev, "line: %u, slice %u, line_bit %u, reg:0x%x\n",
0380 line_id, slice, line_bit, reg);
0381
0382 return 0;
0383 }
0384
0385 static int tegra_hte_enable(struct hte_chip *chip, u32 line_id)
0386 {
0387 if (!chip)
0388 return -EINVAL;
0389
0390 return tegra_hte_en_dis_common(chip, line_id, true);
0391 }
0392
0393 static int tegra_hte_disable(struct hte_chip *chip, u32 line_id)
0394 {
0395 if (!chip)
0396 return -EINVAL;
0397
0398 return tegra_hte_en_dis_common(chip, line_id, false);
0399 }
0400
0401 static int tegra_hte_request(struct hte_chip *chip, struct hte_ts_desc *desc,
0402 u32 line_id)
0403 {
0404 int ret;
0405 struct tegra_hte_soc *gs;
0406 struct hte_line_attr *attr;
0407
0408 if (!chip || !chip->data || !desc)
0409 return -EINVAL;
0410
0411 gs = chip->data;
0412 attr = &desc->attr;
0413
0414 if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
0415 if (!attr->line_data)
0416 return -EINVAL;
0417
0418 ret = gpiod_enable_hw_timestamp_ns(attr->line_data,
0419 attr->edge_flags);
0420 if (ret)
0421 return ret;
0422
0423 gs->line_data[line_id].data = attr->line_data;
0424 gs->line_data[line_id].flags = attr->edge_flags;
0425 }
0426
0427 return tegra_hte_en_dis_common(chip, line_id, true);
0428 }
0429
0430 static int tegra_hte_release(struct hte_chip *chip, struct hte_ts_desc *desc,
0431 u32 line_id)
0432 {
0433 struct tegra_hte_soc *gs;
0434 struct hte_line_attr *attr;
0435 int ret;
0436
0437 if (!chip || !chip->data || !desc)
0438 return -EINVAL;
0439
0440 gs = chip->data;
0441 attr = &desc->attr;
0442
0443 if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
0444 ret = gpiod_disable_hw_timestamp_ns(attr->line_data,
0445 gs->line_data[line_id].flags);
0446 if (ret)
0447 return ret;
0448
0449 gs->line_data[line_id].data = NULL;
0450 gs->line_data[line_id].flags = 0;
0451 }
0452
0453 return tegra_hte_en_dis_common(chip, line_id, false);
0454 }
0455
0456 static int tegra_hte_clk_src_info(struct hte_chip *chip,
0457 struct hte_clk_info *ci)
0458 {
0459 (void)chip;
0460
0461 if (!ci)
0462 return -EINVAL;
0463
0464 ci->hz = HTE_TS_CLK_RATE_HZ;
0465 ci->type = CLOCK_MONOTONIC;
0466
0467 return 0;
0468 }
0469
0470 static int tegra_hte_get_level(struct tegra_hte_soc *gs, u32 line_id)
0471 {
0472 struct gpio_desc *desc;
0473
0474 if (gs->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
0475 desc = gs->line_data[line_id].data;
0476 if (desc)
0477 return gpiod_get_raw_value(desc);
0478 }
0479
0480 return -1;
0481 }
0482
0483 static void tegra_hte_read_fifo(struct tegra_hte_soc *gs)
0484 {
0485 u32 tsh, tsl, src, pv, cv, acv, slice, bit_index, line_id;
0486 u64 tsc;
0487 struct hte_ts_data el;
0488
0489 while ((tegra_hte_readl(gs, HTE_TESTATUS) >>
0490 HTE_TESTATUS_OCCUPANCY_SHIFT) &
0491 HTE_TESTATUS_OCCUPANCY_MASK) {
0492 tsh = tegra_hte_readl(gs, HTE_TETSCH);
0493 tsl = tegra_hte_readl(gs, HTE_TETSCL);
0494 tsc = (((u64)tsh << 32) | tsl);
0495
0496 src = tegra_hte_readl(gs, HTE_TESRC);
0497 slice = (src >> HTE_TESRC_SLICE_SHIFT) &
0498 HTE_TESRC_SLICE_DEFAULT_MASK;
0499
0500 pv = tegra_hte_readl(gs, HTE_TEPCV);
0501 cv = tegra_hte_readl(gs, HTE_TECCV);
0502 acv = pv ^ cv;
0503 while (acv) {
0504 bit_index = __builtin_ctz(acv);
0505 line_id = bit_index + (slice << 5);
0506 el.tsc = tsc << HTE_TS_NS_SHIFT;
0507 el.raw_level = tegra_hte_get_level(gs, line_id);
0508 hte_push_ts_ns(gs->chip, line_id, &el);
0509 acv &= ~BIT(bit_index);
0510 }
0511 tegra_hte_writel(gs, HTE_TECMD, HTE_TECMD_CMD_POP);
0512 }
0513 }
0514
0515 static irqreturn_t tegra_hte_isr(int irq, void *dev_id)
0516 {
0517 struct tegra_hte_soc *gs = dev_id;
0518 (void)irq;
0519
0520 tegra_hte_read_fifo(gs);
0521
0522 return IRQ_HANDLED;
0523 }
0524
0525 static bool tegra_hte_match_from_linedata(const struct hte_chip *chip,
0526 const struct hte_ts_desc *hdesc)
0527 {
0528 struct tegra_hte_soc *hte_dev = chip->data;
0529
0530 if (!hte_dev || (hte_dev->prov_data->type != HTE_TEGRA_TYPE_GPIO))
0531 return false;
0532
0533 return hte_dev->c == gpiod_to_chip(hdesc->attr.line_data);
0534 }
0535
0536 static const struct of_device_id tegra_hte_of_match[] = {
0537 { .compatible = "nvidia,tegra194-gte-lic", .data = &lic_hte},
0538 { .compatible = "nvidia,tegra194-gte-aon", .data = &aon_hte},
0539 { }
0540 };
0541 MODULE_DEVICE_TABLE(of, tegra_hte_of_match);
0542
0543 static const struct hte_ops g_ops = {
0544 .request = tegra_hte_request,
0545 .release = tegra_hte_release,
0546 .enable = tegra_hte_enable,
0547 .disable = tegra_hte_disable,
0548 .get_clk_src_info = tegra_hte_clk_src_info,
0549 };
0550
0551 static void tegra_gte_disable(void *data)
0552 {
0553 struct platform_device *pdev = data;
0554 struct tegra_hte_soc *gs = dev_get_drvdata(&pdev->dev);
0555
0556 tegra_hte_writel(gs, HTE_TECTRL, 0);
0557 }
0558
0559 static int tegra_get_gpiochip_from_name(struct gpio_chip *chip, void *data)
0560 {
0561 return !strcmp(chip->label, data);
0562 }
0563
0564 static int tegra_hte_probe(struct platform_device *pdev)
0565 {
0566 int ret;
0567 u32 i, slices, val = 0;
0568 u32 nlines;
0569 struct device *dev;
0570 struct tegra_hte_soc *hte_dev;
0571 struct hte_chip *gc;
0572
0573 dev = &pdev->dev;
0574
0575 ret = of_property_read_u32(dev->of_node, "nvidia,slices", &slices);
0576 if (ret != 0) {
0577 dev_err(dev, "Could not read slices\n");
0578 return -EINVAL;
0579 }
0580 nlines = slices << 5;
0581
0582 hte_dev = devm_kzalloc(dev, sizeof(*hte_dev), GFP_KERNEL);
0583 if (!hte_dev)
0584 return -ENOMEM;
0585
0586 gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
0587 if (!gc)
0588 return -ENOMEM;
0589
0590 dev_set_drvdata(&pdev->dev, hte_dev);
0591 hte_dev->prov_data = of_device_get_match_data(&pdev->dev);
0592
0593 hte_dev->regs = devm_platform_ioremap_resource(pdev, 0);
0594 if (IS_ERR(hte_dev->regs))
0595 return PTR_ERR(hte_dev->regs);
0596
0597 ret = of_property_read_u32(dev->of_node, "nvidia,int-threshold",
0598 &hte_dev->itr_thrshld);
0599 if (ret != 0)
0600 hte_dev->itr_thrshld = 1;
0601
0602 hte_dev->sl = devm_kcalloc(dev, slices, sizeof(*hte_dev->sl),
0603 GFP_KERNEL);
0604 if (!hte_dev->sl)
0605 return -ENOMEM;
0606
0607 ret = platform_get_irq(pdev, 0);
0608 if (ret < 0) {
0609 dev_err_probe(dev, ret, "failed to get irq\n");
0610 return ret;
0611 }
0612 hte_dev->hte_irq = ret;
0613 ret = devm_request_irq(dev, hte_dev->hte_irq, tegra_hte_isr, 0,
0614 dev_name(dev), hte_dev);
0615 if (ret < 0) {
0616 dev_err(dev, "request irq failed.\n");
0617 return ret;
0618 }
0619
0620 gc->nlines = nlines;
0621 gc->ops = &g_ops;
0622 gc->dev = dev;
0623 gc->data = hte_dev;
0624 gc->xlate_of = tegra_hte_line_xlate;
0625 gc->xlate_plat = tegra_hte_line_xlate_plat;
0626 gc->of_hte_n_cells = 1;
0627
0628 if (hte_dev->prov_data &&
0629 hte_dev->prov_data->type == HTE_TEGRA_TYPE_GPIO) {
0630 hte_dev->line_data = devm_kcalloc(dev, nlines,
0631 sizeof(*hte_dev->line_data),
0632 GFP_KERNEL);
0633 if (!hte_dev->line_data)
0634 return -ENOMEM;
0635
0636 gc->match_from_linedata = tegra_hte_match_from_linedata;
0637
0638 hte_dev->c = gpiochip_find("tegra194-gpio-aon",
0639 tegra_get_gpiochip_from_name);
0640 if (!hte_dev->c)
0641 return dev_err_probe(dev, -EPROBE_DEFER,
0642 "wait for gpio controller\n");
0643 }
0644
0645 hte_dev->chip = gc;
0646
0647 ret = devm_hte_register_chip(hte_dev->chip);
0648 if (ret) {
0649 dev_err(gc->dev, "hte chip register failed");
0650 return ret;
0651 }
0652
0653 for (i = 0; i < slices; i++) {
0654 hte_dev->sl[i].flags = 0;
0655 spin_lock_init(&hte_dev->sl[i].s_lock);
0656 }
0657
0658 val = HTE_TECTRL_ENABLE_ENABLE |
0659 (HTE_TECTRL_INTR_ENABLE << HTE_TECTRL_INTR_SHIFT) |
0660 (hte_dev->itr_thrshld << HTE_TECTRL_OCCU_SHIFT);
0661 tegra_hte_writel(hte_dev, HTE_TECTRL, val);
0662
0663 ret = devm_add_action_or_reset(&pdev->dev, tegra_gte_disable, pdev);
0664 if (ret)
0665 return ret;
0666
0667 dev_dbg(gc->dev, "lines: %d, slices:%d", gc->nlines, slices);
0668
0669 return 0;
0670 }
0671
0672 static int __maybe_unused tegra_hte_resume_early(struct device *dev)
0673 {
0674 u32 i;
0675 struct tegra_hte_soc *gs = dev_get_drvdata(dev);
0676 u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
0677 u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
0678
0679 tegra_hte_writel(gs, HTE_TECTRL, gs->conf_rval);
0680
0681 for (i = 0; i < slices; i++) {
0682 spin_lock(&gs->sl[i].s_lock);
0683 tegra_hte_writel(gs,
0684 ((i << sl_bit_shift) + HTE_SLICE0_TETEN),
0685 gs->sl[i].r_val);
0686 clear_bit(HTE_SUSPEND, &gs->sl[i].flags);
0687 spin_unlock(&gs->sl[i].s_lock);
0688 }
0689
0690 return 0;
0691 }
0692
0693 static int __maybe_unused tegra_hte_suspend_late(struct device *dev)
0694 {
0695 u32 i;
0696 struct tegra_hte_soc *gs = dev_get_drvdata(dev);
0697 u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
0698 u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
0699
0700 gs->conf_rval = tegra_hte_readl(gs, HTE_TECTRL);
0701 for (i = 0; i < slices; i++) {
0702 spin_lock(&gs->sl[i].s_lock);
0703 gs->sl[i].r_val = tegra_hte_readl(gs,
0704 ((i << sl_bit_shift) + HTE_SLICE0_TETEN));
0705 set_bit(HTE_SUSPEND, &gs->sl[i].flags);
0706 spin_unlock(&gs->sl[i].s_lock);
0707 }
0708
0709 return 0;
0710 }
0711
0712 static const struct dev_pm_ops tegra_hte_pm = {
0713 SET_LATE_SYSTEM_SLEEP_PM_OPS(tegra_hte_suspend_late,
0714 tegra_hte_resume_early)
0715 };
0716
0717 static struct platform_driver tegra_hte_driver = {
0718 .probe = tegra_hte_probe,
0719 .driver = {
0720 .name = "tegra_hte",
0721 .pm = &tegra_hte_pm,
0722 .of_match_table = tegra_hte_of_match,
0723 },
0724 };
0725
0726 module_platform_driver(tegra_hte_driver);
0727
0728 MODULE_AUTHOR("Dipen Patel <dipenp@nvidia.com>");
0729 MODULE_DESCRIPTION("NVIDIA Tegra HTE (Hardware Timestamping Engine) driver");
0730 MODULE_LICENSE("GPL");