History

gpio: aspeed: Add SGPIO driver

Add SGPIO driver support for Aspeed AST2500 SoC.

Hongwei Zhang committed 7 years ago

Commit 7db47fa1 parent d5d4aa11 file · +533 −0Browse files

Unified · Split

drivers/gpio/sgpio-aspeed.c+533−0
@@ -0,0 +1,533 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+/*
3+ * Copyright 2019 American Megatrends International LLC.
4+ *
5+ * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in>
6+ */
7+
8+#include <linux/bitfield.h>
9+#include <linux/clk.h>
10+#include <linux/gpio/driver.h>
11+#include <linux/hashtable.h>
12+#include <linux/init.h>
13+#include <linux/io.h>
14+#include <linux/kernel.h>
15+#include <linux/module.h>
16+#include <linux/platform_device.h>
17+#include <linux/spinlock.h>
18+#include <linux/string.h>
19+
20+#define MAX_NR_SGPIO 80
21+
22+#define ASPEED_SGPIO_CTRL 0x54
23+
24+#define ASPEED_SGPIO_PINS_MASK GENMASK(9, 6)
25+#define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16)
26+#define ASPEED_SGPIO_ENABLE BIT(0)
27+
28+struct aspeed_sgpio {
29+ struct gpio_chip chip;
30+ struct clk *pclk;
31+ spinlock_t lock;
32+ void __iomem *base;
33+ uint32_t dir_in[3];
34+ int irq;
35+};
36+
37+struct aspeed_sgpio_bank {
38+ uint16_t val_regs;
39+ uint16_t rdata_reg;
40+ uint16_t irq_regs;
41+ const char names[4][3];
42+};
43+
44+/*
45+ * Note: The "value" register returns the input value when the GPIO is
46+ * configured as an input.
47+ *
48+ * The "rdata" register returns the output value when the GPIO is
49+ * configured as an output.
50+ */
51+static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
52+ {
53+ .val_regs = 0x0000,
54+ .rdata_reg = 0x0070,
55+ .irq_regs = 0x0004,
56+ .names = { "A", "B", "C", "D" },
57+ },
58+ {
59+ .val_regs = 0x001C,
60+ .rdata_reg = 0x0074,
61+ .irq_regs = 0x0020,
62+ .names = { "E", "F", "G", "H" },
63+ },
64+ {
65+ .val_regs = 0x0038,
66+ .rdata_reg = 0x0078,
67+ .irq_regs = 0x003C,
68+ .names = { "I", "J" },
69+ },
70+};
71+
72+enum aspeed_sgpio_reg {
73+ reg_val,
74+ reg_rdata,
75+ reg_irq_enable,
76+ reg_irq_type0,
77+ reg_irq_type1,
78+ reg_irq_type2,
79+ reg_irq_status,
80+};
81+
82+#define GPIO_VAL_VALUE 0x00
83+#define GPIO_IRQ_ENABLE 0x00
84+#define GPIO_IRQ_TYPE0 0x04
85+#define GPIO_IRQ_TYPE1 0x08
86+#define GPIO_IRQ_TYPE2 0x0C
87+#define GPIO_IRQ_STATUS 0x10
88+
89+static void __iomem *bank_reg(struct aspeed_sgpio *gpio,
90+ const struct aspeed_sgpio_bank *bank,
91+ const enum aspeed_sgpio_reg reg)
92+{
93+ switch (reg) {
94+ case reg_val:
95+ return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
96+ case reg_rdata:
97+ return gpio->base + bank->rdata_reg;
98+ case reg_irq_enable:
99+ return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
100+ case reg_irq_type0:
101+ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
102+ case reg_irq_type1:
103+ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
104+ case reg_irq_type2:
105+ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
106+ case reg_irq_status:
107+ return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
108+ default:
109+ /* acturally if code runs to here, it's an error case */
110+ BUG_ON(1);
111+ }
112+}
113+
114+#define GPIO_BANK(x) ((x) >> 5)
115+#define GPIO_OFFSET(x) ((x) & 0x1f)
116+#define GPIO_BIT(x) BIT(GPIO_OFFSET(x))
117+
118+static const struct aspeed_sgpio_bank *to_bank(unsigned int offset)
119+{
120+ unsigned int bank = GPIO_BANK(offset);
121+
122+ WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks));
123+ return &aspeed_sgpio_banks[bank];
124+}
125+
126+static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
127+{
128+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
129+ const struct aspeed_sgpio_bank *bank = to_bank(offset);
130+ unsigned long flags;
131+ enum aspeed_sgpio_reg reg;
132+ bool is_input;
133+ int rc = 0;
134+
135+ spin_lock_irqsave(&gpio->lock, flags);
136+
137+ is_input = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
138+ reg = is_input ? reg_val : reg_rdata;
139+ rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
140+
141+ spin_unlock_irqrestore(&gpio->lock, flags);
142+
143+ return rc;
144+}
145+
146+static void sgpio_set_value(struct gpio_chip *gc, unsigned int offset, int val)
147+{
148+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
149+ const struct aspeed_sgpio_bank *bank = to_bank(offset);
150+ void __iomem *addr;
151+ u32 reg = 0;
152+
153+ addr = bank_reg(gpio, bank, reg_val);
154+ reg = ioread32(addr);
155+
156+ if (val)
157+ reg |= GPIO_BIT(offset);
158+ else
159+ reg &= ~GPIO_BIT(offset);
160+
161+ iowrite32(reg, addr);
162+}
163+
164+static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
165+{
166+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
167+ unsigned long flags;
168+
169+ spin_lock_irqsave(&gpio->lock, flags);
170+
171+ sgpio_set_value(gc, offset, val);
172+
173+ spin_unlock_irqrestore(&gpio->lock, flags);
174+}
175+
176+static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
177+{
178+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
179+ unsigned long flags;
180+
181+ spin_lock_irqsave(&gpio->lock, flags);
182+ gpio->dir_in[GPIO_BANK(offset)] |= GPIO_BIT(offset);
183+ spin_unlock_irqrestore(&gpio->lock, flags);
184+
185+ return 0;
186+}
187+
188+static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val)
189+{
190+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
191+ unsigned long flags;
192+
193+ spin_lock_irqsave(&gpio->lock, flags);
194+
195+ gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
196+ sgpio_set_value(gc, offset, val);
197+
198+ spin_unlock_irqrestore(&gpio->lock, flags);
199+
200+ return 0;
201+}
202+
203+static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset)
204+{
205+ int dir_status;
206+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
207+ unsigned long flags;
208+
209+ spin_lock_irqsave(&gpio->lock, flags);
210+ dir_status = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
211+ spin_unlock_irqrestore(&gpio->lock, flags);
212+
213+ return dir_status;
214+
215+}
216+
217+static void irqd_to_aspeed_sgpio_data(struct irq_data *d,
218+ struct aspeed_sgpio **gpio,
219+ const struct aspeed_sgpio_bank **bank,
220+ u32 *bit, int *offset)
221+{
222+ struct aspeed_sgpio *internal;
223+
224+ *offset = irqd_to_hwirq(d);
225+ internal = irq_data_get_irq_chip_data(d);
226+ WARN_ON(!internal);
227+
228+ *gpio = internal;
229+ *bank = to_bank(*offset);
230+ *bit = GPIO_BIT(*offset);
231+}
232+
233+static void aspeed_sgpio_irq_ack(struct irq_data *d)
234+{
235+ const struct aspeed_sgpio_bank *bank;
236+ struct aspeed_sgpio *gpio;
237+ unsigned long flags;
238+ void __iomem *status_addr;
239+ int offset;
240+ u32 bit;
241+
242+ irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
243+
244+ status_addr = bank_reg(gpio, bank, reg_irq_status);
245+
246+ spin_lock_irqsave(&gpio->lock, flags);
247+
248+ iowrite32(bit, status_addr);
249+
250+ spin_unlock_irqrestore(&gpio->lock, flags);
251+}
252+
253+static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
254+{
255+ const struct aspeed_sgpio_bank *bank;
256+ struct aspeed_sgpio *gpio;
257+ unsigned long flags;
258+ u32 reg, bit;
259+ void __iomem *addr;
260+ int offset;
261+
262+ irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
263+ addr = bank_reg(gpio, bank, reg_irq_enable);
264+
265+ spin_lock_irqsave(&gpio->lock, flags);
266+
267+ reg = ioread32(addr);
268+ if (set)
269+ reg |= bit;
270+ else
271+ reg &= ~bit;
272+
273+ iowrite32(reg, addr);
274+
275+ spin_unlock_irqrestore(&gpio->lock, flags);
276+}
277+
278+static void aspeed_sgpio_irq_mask(struct irq_data *d)
279+{
280+ aspeed_sgpio_irq_set_mask(d, false);
281+}
282+
283+static void aspeed_sgpio_irq_unmask(struct irq_data *d)
284+{
285+ aspeed_sgpio_irq_set_mask(d, true);
286+}
287+
288+static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
289+{
290+ u32 type0 = 0;
291+ u32 type1 = 0;
292+ u32 type2 = 0;
293+ u32 bit, reg;
294+ const struct aspeed_sgpio_bank *bank;
295+ irq_flow_handler_t handler;
296+ struct aspeed_sgpio *gpio;
297+ unsigned long flags;
298+ void __iomem *addr;
299+ int offset;
300+
301+ irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
302+
303+ switch (type & IRQ_TYPE_SENSE_MASK) {
304+ case IRQ_TYPE_EDGE_BOTH:
305+ type2 |= bit;
306+ /* fall through */
307+ case IRQ_TYPE_EDGE_RISING:
308+ type0 |= bit;
309+ /* fall through */
310+ case IRQ_TYPE_EDGE_FALLING:
311+ handler = handle_edge_irq;
312+ break;
313+ case IRQ_TYPE_LEVEL_HIGH:
314+ type0 |= bit;
315+ /* fall through */
316+ case IRQ_TYPE_LEVEL_LOW:
317+ type1 |= bit;
318+ handler = handle_level_irq;
319+ break;
320+ default:
321+ return -EINVAL;
322+ }
323+
324+ spin_lock_irqsave(&gpio->lock, flags);
325+
326+ addr = bank_reg(gpio, bank, reg_irq_type0);
327+ reg = ioread32(addr);
328+ reg = (reg & ~bit) | type0;
329+ iowrite32(reg, addr);
330+
331+ addr = bank_reg(gpio, bank, reg_irq_type1);
332+ reg = ioread32(addr);
333+ reg = (reg & ~bit) | type1;
334+ iowrite32(reg, addr);
335+
336+ addr = bank_reg(gpio, bank, reg_irq_type2);
337+ reg = ioread32(addr);
338+ reg = (reg & ~bit) | type2;
339+ iowrite32(reg, addr);
340+
341+ spin_unlock_irqrestore(&gpio->lock, flags);
342+
343+ irq_set_handler_locked(d, handler);
344+
345+ return 0;
346+}
347+
348+static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
349+{
350+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
351+ struct irq_chip *ic = irq_desc_get_chip(desc);
352+ struct aspeed_sgpio *data = gpiochip_get_data(gc);
353+ unsigned int i, p, girq;
354+ unsigned long reg;
355+
356+ chained_irq_enter(ic, desc);
357+
358+ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
359+ const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i];
360+
361+ reg = ioread32(bank_reg(data, bank, reg_irq_status));
362+
363+ for_each_set_bit(p, &reg, 32) {
364+ girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
365+ generic_handle_irq(girq);
366+ }
367+
368+ }
369+
370+ chained_irq_exit(ic, desc);
371+}
372+
373+static struct irq_chip aspeed_sgpio_irqchip = {
374+ .name = "aspeed-sgpio",
375+ .irq_ack = aspeed_sgpio_irq_ack,
376+ .irq_mask = aspeed_sgpio_irq_mask,
377+ .irq_unmask = aspeed_sgpio_irq_unmask,
378+ .irq_set_type = aspeed_sgpio_set_type,
379+};
380+
381+static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio,
382+ struct platform_device *pdev)
383+{
384+ int rc, i;
385+ const struct aspeed_sgpio_bank *bank;
386+ struct gpio_irq_chip *irq;
387+
388+ rc = platform_get_irq(pdev, 0);
389+ if (rc < 0)
390+ return rc;
391+
392+ gpio->irq = rc;
393+
394+ /* Disable IRQ and clear Interrupt status registers for all SPGIO Pins. */
395+ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
396+ bank = &aspeed_sgpio_banks[i];
397+ /* disable irq enable bits */
398+ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable));
399+ /* clear status bits */
400+ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status));
401+ }
402+
403+ irq = &gpio->chip.irq;
404+ irq->chip = &aspeed_sgpio_irqchip;
405+ irq->handler = handle_bad_irq;
406+ irq->default_type = IRQ_TYPE_NONE;
407+ irq->parent_handler = aspeed_sgpio_irq_handler;
408+ irq->parent_handler_data = gpio;
409+ irq->parents = &gpio->irq;
410+ irq->num_parents = 1;
411+
412+ /* set IRQ settings and Enable Interrupt */
413+ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
414+ bank = &aspeed_sgpio_banks[i];
415+ /* set falling or level-low irq */
416+ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0));
417+ /* trigger type is edge */
418+ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1));
419+ /* dual edge trigger mode. */
420+ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2));
421+ /* enable irq */
422+ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable));
423+ }
424+
425+ return 0;
426+}
427+
428+static const struct of_device_id aspeed_sgpio_of_table[] = {
429+ { .compatible = "aspeed,ast2400-sgpio" },
430+ { .compatible = "aspeed,ast2500-sgpio" },
431+ {}
432+};
433+
434+MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table);
435+
436+static int __init aspeed_sgpio_probe(struct platform_device *pdev)
437+{
438+ struct aspeed_sgpio *gpio;
439+ u32 nr_gpios, sgpio_freq, sgpio_clk_div;
440+ int rc;
441+ unsigned long apb_freq;
442+
443+ gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
444+ if (!gpio)
445+ return -ENOMEM;
446+
447+ gpio->base = devm_platform_ioremap_resource(pdev, 0);
448+ if (IS_ERR(gpio->base))
449+ return PTR_ERR(gpio->base);
450+
451+ rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios);
452+ if (rc < 0) {
453+ dev_err(&pdev->dev, "Could not read ngpios property\n");
454+ return -EINVAL;
455+ } else if (nr_gpios > MAX_NR_SGPIO) {
456+ dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: %d\n",
457+ MAX_NR_SGPIO, nr_gpios);
458+ return -EINVAL;
459+ }
460+
461+ rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq);
462+ if (rc < 0) {
463+ dev_err(&pdev->dev, "Could not read bus-frequency property\n");
464+ return -EINVAL;
465+ }
466+
467+ gpio->pclk = devm_clk_get(&pdev->dev, NULL);
468+ if (IS_ERR(gpio->pclk)) {
469+ dev_err(&pdev->dev, "devm_clk_get failed\n");
470+ return PTR_ERR(gpio->pclk);
471+ }
472+
473+ apb_freq = clk_get_rate(gpio->pclk);
474+
475+ /*
476+ * From the datasheet,
477+ * SGPIO period = 1/PCLK * 2 * (GPIO254[31:16] + 1)
478+ * period = 2 * (GPIO254[31:16] + 1) / PCLK
479+ * frequency = 1 / (2 * (GPIO254[31:16] + 1) / PCLK)
480+ * frequency = PCLK / (2 * (GPIO254[31:16] + 1))
481+ * frequency * 2 * (GPIO254[31:16] + 1) = PCLK
482+ * GPIO254[31:16] = PCLK / (frequency * 2) - 1
483+ */
484+ if (sgpio_freq == 0)
485+ return -EINVAL;
486+
487+ sgpio_clk_div = (apb_freq / (sgpio_freq * 2)) - 1;
488+
489+ if (sgpio_clk_div > (1 << 16) - 1)
490+ return -EINVAL;
491+
492+ iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) |
493+ FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) |
494+ ASPEED_SGPIO_ENABLE,
495+ gpio->base + ASPEED_SGPIO_CTRL);
496+
497+ spin_lock_init(&gpio->lock);
498+
499+ gpio->chip.parent = &pdev->dev;
500+ gpio->chip.ngpio = nr_gpios;
501+ gpio->chip.direction_input = aspeed_sgpio_dir_in;
502+ gpio->chip.direction_output = aspeed_sgpio_dir_out;
503+ gpio->chip.get_direction = aspeed_sgpio_get_direction;
504+ gpio->chip.request = NULL;
505+ gpio->chip.free = NULL;
506+ gpio->chip.get = aspeed_sgpio_get;
507+ gpio->chip.set = aspeed_sgpio_set;
508+ gpio->chip.set_config = NULL;
509+ gpio->chip.label = dev_name(&pdev->dev);
510+ gpio->chip.base = -1;
511+
512+ /* set all SGPIO pins as input (1). */
513+ memset(gpio->dir_in, 0xff, sizeof(gpio->dir_in));
514+
515+ aspeed_sgpio_setup_irqs(gpio, pdev);
516+
517+ rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
518+ if (rc < 0)
519+ return rc;
520+
521+ return 0;
522+}
523+
524+static struct platform_driver aspeed_sgpio_driver = {
525+ .driver = {
526+ .name = KBUILD_MODNAME,
527+ .of_match_table = aspeed_sgpio_of_table,
528+ },
529+};
530+
531+module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
532+MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
533+MODULE_LICENSE("GPL");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t