Lines Matching +full:tegra186 +full:- +full:gpio +full:- +full:aon
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016-2022 NVIDIA Corporation
9 #include <linux/gpio/driver.h>
17 #include <dt-bindings/gpio/tegra186-gpio.h>
18 #include <dt-bindings/gpio/tegra194-gpio.h>
19 #include <dt-bindings/gpio/tegra234-gpio.h>
20 #include <dt-bindings/gpio/tegra241-gpio.h>
86 struct gpio_chip gpio; member
99 tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin) in tegra186_gpio_get_port() argument
103 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_get_port()
104 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_get_port()
106 if (*pin >= start && *pin < start + port->pins) { in tegra186_gpio_get_port()
107 *pin -= start; in tegra186_gpio_get_port()
111 start += port->pins; in tegra186_gpio_get_port()
117 static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio, in tegra186_gpio_get_base() argument
123 port = tegra186_gpio_get_port(gpio, &pin); in tegra186_gpio_get_base()
127 offset = port->bank * 0x1000 + port->port * 0x200; in tegra186_gpio_get_base()
129 return gpio->base + offset + pin * 0x20; in tegra186_gpio_get_base()
135 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_get_direction() local
139 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_get_direction()
141 return -ENODEV; in tegra186_gpio_get_direction()
153 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_direction_input() local
157 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_direction_input()
159 return -ENODEV; in tegra186_gpio_direction_input()
176 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_direction_output() local
181 chip->set(chip, offset, level); in tegra186_gpio_direction_output()
183 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_direction_output()
185 return -EINVAL; in tegra186_gpio_direction_output()
205 struct tegra_gpio *gpio; in tegra186_gpio_en_hw_ts() local
210 return -EINVAL; in tegra186_gpio_en_hw_ts()
212 gpio = gpiochip_get_data(gc); in tegra186_gpio_en_hw_ts()
213 if (!gpio) in tegra186_gpio_en_hw_ts()
214 return -ENODEV; in tegra186_gpio_en_hw_ts()
216 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_en_hw_ts()
218 return -EINVAL; in tegra186_gpio_en_hw_ts()
240 struct tegra_gpio *gpio; in tegra186_gpio_dis_hw_ts() local
245 return -EINVAL; in tegra186_gpio_dis_hw_ts()
247 gpio = gpiochip_get_data(gc); in tegra186_gpio_dis_hw_ts()
248 if (!gpio) in tegra186_gpio_dis_hw_ts()
249 return -ENODEV; in tegra186_gpio_dis_hw_ts()
251 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_dis_hw_ts()
253 return -EINVAL; in tegra186_gpio_dis_hw_ts()
272 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_get() local
276 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_get()
278 return -ENODEV; in tegra186_gpio_get()
292 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_set() local
296 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_set()
313 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_set_config() local
317 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_set_config()
319 return -ENXIO; in tegra186_gpio_set_config()
322 return -ENOTSUPP; in tegra186_gpio_set_config()
327 * The Tegra186 GPIO controller supports a maximum of 255 ms debounce in tegra186_gpio_set_config()
331 return -EINVAL; in tegra186_gpio_set_config()
347 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_add_pin_ranges() local
353 if (!gpio->soc->pinmux || gpio->soc->num_pin_ranges == 0) in tegra186_gpio_add_pin_ranges()
356 np = of_find_compatible_node(NULL, NULL, gpio->soc->pinmux); in tegra186_gpio_add_pin_ranges()
358 return -ENODEV; in tegra186_gpio_add_pin_ranges()
363 return -EPROBE_DEFER; in tegra186_gpio_add_pin_ranges()
365 for (i = 0; i < gpio->soc->num_pin_ranges; i++) { in tegra186_gpio_add_pin_ranges()
366 unsigned int pin = gpio->soc->pin_ranges[i].offset, port; in tegra186_gpio_add_pin_ranges()
367 const char *group = gpio->soc->pin_ranges[i].group; in tegra186_gpio_add_pin_ranges()
372 if (port >= gpio->soc->num_ports) { in tegra186_gpio_add_pin_ranges()
373 dev_warn(chip->parent, "invalid port %u for %s\n", in tegra186_gpio_add_pin_ranges()
379 pin += gpio->soc->ports[j].pins; in tegra186_gpio_add_pin_ranges()
393 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_of_xlate() local
396 if (WARN_ON(chip->of_gpio_n_cells < 2)) in tegra186_gpio_of_xlate()
397 return -EINVAL; in tegra186_gpio_of_xlate()
399 if (WARN_ON(spec->args_count < chip->of_gpio_n_cells)) in tegra186_gpio_of_xlate()
400 return -EINVAL; in tegra186_gpio_of_xlate()
402 port = spec->args[0] / 8; in tegra186_gpio_of_xlate()
403 pin = spec->args[0] % 8; in tegra186_gpio_of_xlate()
405 if (port >= gpio->soc->num_ports) { in tegra186_gpio_of_xlate()
406 dev_err(chip->parent, "invalid port number: %u\n", port); in tegra186_gpio_of_xlate()
407 return -EINVAL; in tegra186_gpio_of_xlate()
411 offset += gpio->soc->ports[i].pins; in tegra186_gpio_of_xlate()
414 *flags = spec->args[1]; in tegra186_gpio_of_xlate()
419 #define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio)
424 struct tegra_gpio *gpio = to_tegra_gpio(gc); in tegra186_irq_ack() local
427 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_ack()
437 struct tegra_gpio *gpio = to_tegra_gpio(gc); in tegra186_irq_mask() local
441 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_mask()
449 gpiochip_disable_irq(&gpio->gpio, data->hwirq); in tegra186_irq_mask()
455 struct tegra_gpio *gpio = to_tegra_gpio(gc); in tegra186_irq_unmask() local
459 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_unmask()
463 gpiochip_enable_irq(&gpio->gpio, data->hwirq); in tegra186_irq_unmask()
473 struct tegra_gpio *gpio = to_tegra_gpio(gc); in tegra186_irq_set_type() local
477 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_set_type()
479 return -ENODEV; in tegra186_irq_set_type()
512 return -EINVAL; in tegra186_irq_set_type()
522 if (data->parent_data) in tegra186_irq_set_type()
530 if (data->parent_data) in tegra186_irq_set_wake()
540 seq_printf(p, dev_name(gc->parent)); in tegra186_irq_print_chip()
556 struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); in tegra186_gpio_irq() local
557 struct irq_domain *domain = gpio->gpio.irq.domain; in tegra186_gpio_irq()
564 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_irq()
565 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_irq()
570 base = gpio->base + port->bank * 0x1000 + port->port * 0x200; in tegra186_gpio_irq()
573 for (j = 0; j < gpio->num_irqs_per_bank; j++) { in tegra186_gpio_irq()
574 if (parent == gpio->irq[port->bank * gpio->num_irqs_per_bank + j]) in tegra186_gpio_irq()
578 if (j == gpio->num_irqs_per_bank) in tegra186_gpio_irq()
583 for_each_set_bit(pin, &value, port->pins) { in tegra186_gpio_irq()
589 offset += port->pins; in tegra186_gpio_irq()
600 struct tegra_gpio *gpio = gpiochip_get_data(domain->host_data); in tegra186_gpio_irq_domain_translate() local
603 if (WARN_ON(gpio->gpio.of_gpio_n_cells < 2)) in tegra186_gpio_irq_domain_translate()
604 return -EINVAL; in tegra186_gpio_irq_domain_translate()
606 if (WARN_ON(fwspec->param_count < gpio->gpio.of_gpio_n_cells)) in tegra186_gpio_irq_domain_translate()
607 return -EINVAL; in tegra186_gpio_irq_domain_translate()
609 port = fwspec->param[0] / 8; in tegra186_gpio_irq_domain_translate()
610 pin = fwspec->param[0] % 8; in tegra186_gpio_irq_domain_translate()
612 if (port >= gpio->soc->num_ports) in tegra186_gpio_irq_domain_translate()
613 return -EINVAL; in tegra186_gpio_irq_domain_translate()
616 offset += gpio->soc->ports[i].pins; in tegra186_gpio_irq_domain_translate()
618 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in tegra186_gpio_irq_domain_translate()
629 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_populate_parent_fwspec() local
630 struct irq_fwspec *fwspec = &gfwspec->fwspec; in tegra186_gpio_populate_parent_fwspec()
632 fwspec->fwnode = chip->irq.parent_domain->fwnode; in tegra186_gpio_populate_parent_fwspec()
633 fwspec->param_count = 3; in tegra186_gpio_populate_parent_fwspec()
634 fwspec->param[0] = gpio->soc->instance; in tegra186_gpio_populate_parent_fwspec()
635 fwspec->param[1] = parent_hwirq; in tegra186_gpio_populate_parent_fwspec()
636 fwspec->param[2] = parent_type; in tegra186_gpio_populate_parent_fwspec()
647 *parent_hwirq = chip->irq.child_offset_to_irq(chip, hwirq); in tegra186_gpio_child_to_parent_hwirq()
656 struct tegra_gpio *gpio = gpiochip_get_data(chip); in tegra186_gpio_child_offset_to_irq() local
659 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_child_offset_to_irq()
660 if (offset < gpio->soc->ports[i].pins) in tegra186_gpio_child_offset_to_irq()
663 offset -= gpio->soc->ports[i].pins; in tegra186_gpio_child_offset_to_irq()
670 { .compatible = "nvidia,tegra186-pmc" },
671 { .compatible = "nvidia,tegra194-pmc" },
675 static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) in tegra186_gpio_init_route_mapping() argument
677 struct device *dev = gpio->gpio.parent; in tegra186_gpio_init_route_mapping()
681 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_init_route_mapping()
682 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_init_route_mapping()
683 unsigned int offset, p = port->port; in tegra186_gpio_init_route_mapping()
686 base = gpio->secure + port->bank * 0x1000 + 0x800; in tegra186_gpio_init_route_mapping()
700 for (j = 0; j < gpio->num_irqs_per_bank; j++) { in tegra186_gpio_init_route_mapping()
702 port->name); in tegra186_gpio_init_route_mapping()
707 * By default we only want to route GPIO pins to IRQ 0. This works in tegra186_gpio_init_route_mapping()
709 * and hence all GPIO pins are owned by Linux. in tegra186_gpio_init_route_mapping()
717 value = BIT(port->pins) - 1; in tegra186_gpio_init_route_mapping()
725 static unsigned int tegra186_gpio_irqs_per_bank(struct tegra_gpio *gpio) in tegra186_gpio_irqs_per_bank() argument
727 struct device *dev = gpio->gpio.parent; in tegra186_gpio_irqs_per_bank()
729 if (gpio->num_irq > gpio->num_banks) { in tegra186_gpio_irqs_per_bank()
730 if (gpio->num_irq % gpio->num_banks != 0) in tegra186_gpio_irqs_per_bank()
734 if (gpio->num_irq < gpio->num_banks) in tegra186_gpio_irqs_per_bank()
737 gpio->num_irqs_per_bank = gpio->num_irq / gpio->num_banks; in tegra186_gpio_irqs_per_bank()
739 if (gpio->num_irqs_per_bank > gpio->soc->num_irqs_per_bank) in tegra186_gpio_irqs_per_bank()
746 gpio->num_irq, gpio->num_banks); in tegra186_gpio_irqs_per_bank()
747 return -EINVAL; in tegra186_gpio_irqs_per_bank()
754 struct tegra_gpio *gpio; in tegra186_gpio_probe() local
759 gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); in tegra186_gpio_probe()
760 if (!gpio) in tegra186_gpio_probe()
761 return -ENOMEM; in tegra186_gpio_probe()
763 gpio->soc = device_get_match_data(&pdev->dev); in tegra186_gpio_probe()
764 gpio->gpio.label = gpio->soc->name; in tegra186_gpio_probe()
765 gpio->gpio.parent = &pdev->dev; in tegra186_gpio_probe()
768 for (i = 0; i < gpio->soc->num_ports; i++) in tegra186_gpio_probe()
769 if (gpio->soc->ports[i].bank > gpio->num_banks) in tegra186_gpio_probe()
770 gpio->num_banks = gpio->soc->ports[i].bank; in tegra186_gpio_probe()
772 gpio->num_banks++; in tegra186_gpio_probe()
775 gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); in tegra186_gpio_probe()
776 if (IS_ERR(gpio->secure)) { in tegra186_gpio_probe()
777 gpio->secure = devm_platform_ioremap_resource(pdev, 0); in tegra186_gpio_probe()
778 if (IS_ERR(gpio->secure)) in tegra186_gpio_probe()
779 return PTR_ERR(gpio->secure); in tegra186_gpio_probe()
782 gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); in tegra186_gpio_probe()
783 if (IS_ERR(gpio->base)) { in tegra186_gpio_probe()
784 gpio->base = devm_platform_ioremap_resource(pdev, 1); in tegra186_gpio_probe()
785 if (IS_ERR(gpio->base)) in tegra186_gpio_probe()
786 return PTR_ERR(gpio->base); in tegra186_gpio_probe()
793 gpio->num_irq = err; in tegra186_gpio_probe()
795 err = tegra186_gpio_irqs_per_bank(gpio); in tegra186_gpio_probe()
799 gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq), in tegra186_gpio_probe()
801 if (!gpio->irq) in tegra186_gpio_probe()
802 return -ENOMEM; in tegra186_gpio_probe()
804 for (i = 0; i < gpio->num_irq; i++) { in tegra186_gpio_probe()
809 gpio->irq[i] = err; in tegra186_gpio_probe()
812 gpio->gpio.request = gpiochip_generic_request; in tegra186_gpio_probe()
813 gpio->gpio.free = gpiochip_generic_free; in tegra186_gpio_probe()
814 gpio->gpio.get_direction = tegra186_gpio_get_direction; in tegra186_gpio_probe()
815 gpio->gpio.direction_input = tegra186_gpio_direction_input; in tegra186_gpio_probe()
816 gpio->gpio.direction_output = tegra186_gpio_direction_output; in tegra186_gpio_probe()
817 gpio->gpio.get = tegra186_gpio_get; in tegra186_gpio_probe()
818 gpio->gpio.set = tegra186_gpio_set; in tegra186_gpio_probe()
819 gpio->gpio.set_config = tegra186_gpio_set_config; in tegra186_gpio_probe()
820 gpio->gpio.add_pin_ranges = tegra186_gpio_add_pin_ranges; in tegra186_gpio_probe()
821 if (gpio->soc->has_gte) { in tegra186_gpio_probe()
822 gpio->gpio.en_hw_timestamp = tegra186_gpio_en_hw_ts; in tegra186_gpio_probe()
823 gpio->gpio.dis_hw_timestamp = tegra186_gpio_dis_hw_ts; in tegra186_gpio_probe()
826 gpio->gpio.base = -1; in tegra186_gpio_probe()
828 for (i = 0; i < gpio->soc->num_ports; i++) in tegra186_gpio_probe()
829 gpio->gpio.ngpio += gpio->soc->ports[i].pins; in tegra186_gpio_probe()
831 names = devm_kcalloc(gpio->gpio.parent, gpio->gpio.ngpio, in tegra186_gpio_probe()
834 return -ENOMEM; in tegra186_gpio_probe()
836 for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_probe()
837 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_probe()
840 for (j = 0; j < port->pins; j++) { in tegra186_gpio_probe()
841 name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, in tegra186_gpio_probe()
842 "P%s.%02x", port->name, j); in tegra186_gpio_probe()
844 return -ENOMEM; in tegra186_gpio_probe()
849 offset += port->pins; in tegra186_gpio_probe()
852 gpio->gpio.names = (const char * const *)names; in tegra186_gpio_probe()
855 gpio->gpio.of_gpio_n_cells = 2; in tegra186_gpio_probe()
856 gpio->gpio.of_xlate = tegra186_gpio_of_xlate; in tegra186_gpio_probe()
859 irq = &gpio->gpio.irq; in tegra186_gpio_probe()
861 irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); in tegra186_gpio_probe()
862 irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; in tegra186_gpio_probe()
863 irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; in tegra186_gpio_probe()
864 irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq; in tegra186_gpio_probe()
865 irq->child_irq_domain_ops.translate = tegra186_gpio_irq_domain_translate; in tegra186_gpio_probe()
866 irq->handler = handle_simple_irq; in tegra186_gpio_probe()
867 irq->default_type = IRQ_TYPE_NONE; in tegra186_gpio_probe()
868 irq->parent_handler = tegra186_gpio_irq; in tegra186_gpio_probe()
869 irq->parent_handler_data = gpio; in tegra186_gpio_probe()
870 irq->num_parents = gpio->num_irq; in tegra186_gpio_probe()
879 if (gpio->num_irqs_per_bank > 1) { in tegra186_gpio_probe()
880 irq->parents = devm_kcalloc(&pdev->dev, gpio->num_banks, in tegra186_gpio_probe()
881 sizeof(*irq->parents), GFP_KERNEL); in tegra186_gpio_probe()
882 if (!irq->parents) in tegra186_gpio_probe()
883 return -ENOMEM; in tegra186_gpio_probe()
885 for (i = 0; i < gpio->num_banks; i++) in tegra186_gpio_probe()
886 irq->parents[i] = gpio->irq[i * gpio->num_irqs_per_bank]; in tegra186_gpio_probe()
888 irq->num_parents = gpio->num_banks; in tegra186_gpio_probe()
890 irq->num_parents = gpio->num_irq; in tegra186_gpio_probe()
891 irq->parents = gpio->irq; in tegra186_gpio_probe()
894 if (gpio->soc->num_irqs_per_bank > 1) in tegra186_gpio_probe()
895 tegra186_gpio_init_route_mapping(gpio); in tegra186_gpio_probe()
899 irq->parent_domain = irq_find_host(np); in tegra186_gpio_probe()
902 if (!irq->parent_domain) in tegra186_gpio_probe()
903 return -EPROBE_DEFER; in tegra186_gpio_probe()
906 irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, in tegra186_gpio_probe()
907 sizeof(*irq->map), GFP_KERNEL); in tegra186_gpio_probe()
908 if (!irq->map) in tegra186_gpio_probe()
909 return -ENOMEM; in tegra186_gpio_probe()
911 for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_probe()
912 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_probe()
914 for (j = 0; j < port->pins; j++) in tegra186_gpio_probe()
915 irq->map[offset + j] = irq->parents[port->bank]; in tegra186_gpio_probe()
917 offset += port->pins; in tegra186_gpio_probe()
920 return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio); in tegra186_gpio_probe()
960 .name = "tegra186-gpio",
987 .name = "tegra186-gpio-aon",
1039 .name = "tegra194-gpio",
1044 .pinmux = "nvidia,tegra194-pinmux",
1066 .name = "tegra194-gpio-aon",
1111 .name = "tegra234-gpio",
1136 .name = "tegra234-gpio-aon",
1166 .name = "tegra241-gpio",
1187 .name = "tegra241-gpio-aon",
1194 .compatible = "nvidia,tegra186-gpio",
1197 .compatible = "nvidia,tegra186-gpio-aon",
1200 .compatible = "nvidia,tegra194-gpio",
1203 .compatible = "nvidia,tegra194-gpio-aon",
1206 .compatible = "nvidia,tegra234-gpio",
1209 .compatible = "nvidia,tegra234-gpio-aon",
1230 .name = "tegra186-gpio",
1238 MODULE_DESCRIPTION("NVIDIA Tegra186 GPIO controller driver");