|
19 | 19 | #include <linux/spinlock.h> |
20 | 20 | #include <linux/string.h> |
21 | 21 |
|
22 | | -#define ASPEED_SGPIO_CTRL 0x54 |
| 22 | +#define SGPIO_G7_IRQ_STS_BASE 0x40 |
| 23 | +#define SGPIO_G7_IRQ_STS_OFFSET(x) (SGPIO_G7_IRQ_STS_BASE + (x) * 0x4) |
| 24 | +#define SGPIO_G7_CTRL_REG_BASE 0x80 |
| 25 | +#define SGPIO_G7_CTRL_REG_OFFSET(x) (SGPIO_G7_CTRL_REG_BASE + (x) * 0x4) |
| 26 | +#define SGPIO_G7_OUT_DATA BIT(0) |
| 27 | +#define SGPIO_G7_PARALLEL_OUT_DATA BIT(1) |
| 28 | +#define SGPIO_G7_IRQ_EN BIT(2) |
| 29 | +#define SGPIO_G7_IRQ_TYPE0 BIT(3) |
| 30 | +#define SGPIO_G7_IRQ_TYPE1 BIT(4) |
| 31 | +#define SGPIO_G7_IRQ_TYPE2 BIT(5) |
| 32 | +#define SGPIO_G7_RST_TOLERANCE BIT(6) |
| 33 | +#define SGPIO_G7_INPUT_MASK BIT(9) |
| 34 | +#define SGPIO_G7_HW_BYPASS_EN BIT(10) |
| 35 | +#define SGPIO_G7_HW_IN_SEL BIT(11) |
| 36 | +#define SGPIO_G7_IRQ_STS BIT(12) |
| 37 | +#define SGPIO_G7_IN_DATA BIT(13) |
| 38 | +#define SGPIO_G7_PARALLEL_IN_DATA BIT(14) |
| 39 | +#define SGPIO_G7_SERIAL_OUT_SEL GENMASK(17, 16) |
| 40 | +#define SGPIO_G7_PARALLEL_OUT_SEL GENMASK(19, 18) |
| 41 | +#define SELECT_FROM_CSR 0 |
| 42 | +#define SELECT_FROM_PARALLEL_IN 1 |
| 43 | +#define SELECT_FROM_SERIAL_IN 2 |
| 44 | + |
| 45 | +#define ASPEED_SGPIO_G4_CFG_OFFSET 0x54 |
| 46 | +#define ASPEED_SGPIO_G7_CFG_OFFSET 0x0 |
23 | 47 |
|
24 | 48 | #define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16) |
25 | 49 | #define ASPEED_SGPIO_ENABLE BIT(0) |
|
28 | 52 | struct aspeed_sgpio_pdata { |
29 | 53 | const u32 pin_mask; |
30 | 54 | const struct aspeed_sgpio_llops *llops; |
| 55 | + const u32 cfg_offset; |
31 | 56 | }; |
32 | 57 |
|
33 | 58 | struct aspeed_sgpio { |
@@ -135,6 +160,30 @@ static void __iomem *aspeed_sgpio_g4_bank_reg(struct aspeed_sgpio *gpio, |
135 | 160 | } |
136 | 161 | } |
137 | 162 |
|
| 163 | +static u32 aspeed_sgpio_g7_reg_mask(const enum aspeed_sgpio_reg reg) |
| 164 | +{ |
| 165 | + switch (reg) { |
| 166 | + case reg_val: |
| 167 | + case reg_rdata: |
| 168 | + return SGPIO_G7_OUT_DATA; |
| 169 | + case reg_irq_enable: |
| 170 | + return SGPIO_G7_IRQ_EN; |
| 171 | + case reg_irq_type0: |
| 172 | + return SGPIO_G7_IRQ_TYPE0; |
| 173 | + case reg_irq_type1: |
| 174 | + return SGPIO_G7_IRQ_TYPE1; |
| 175 | + case reg_irq_type2: |
| 176 | + return SGPIO_G7_IRQ_TYPE2; |
| 177 | + case reg_irq_status: |
| 178 | + return SGPIO_G7_IRQ_STS; |
| 179 | + case reg_tolerance: |
| 180 | + return SGPIO_G7_RST_TOLERANCE; |
| 181 | + default: |
| 182 | + WARN_ON_ONCE(1); |
| 183 | + return 0; |
| 184 | + } |
| 185 | +} |
| 186 | + |
138 | 187 | #define GPIO_BANK(x) ((x) >> 6) |
139 | 188 | #define GPIO_OFFSET(x) ((x) & GENMASK(5, 0)) |
140 | 189 | #define GPIO_BIT(x) BIT(GPIO_OFFSET(x) >> 1) |
@@ -457,6 +506,7 @@ static const struct aspeed_sgpio_llops aspeed_sgpio_g4_llops = { |
457 | 506 | static const struct aspeed_sgpio_pdata ast2400_sgpio_pdata = { |
458 | 507 | .pin_mask = GENMASK(9, 6), |
459 | 508 | .llops = &aspeed_sgpio_g4_llops, |
| 509 | + .cfg_offset = ASPEED_SGPIO_G4_CFG_OFFSET, |
460 | 510 | }; |
461 | 511 |
|
462 | 512 | static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, |
@@ -486,12 +536,68 @@ static int aspeed_sgpio_set_config(struct gpio_chip *chip, unsigned int offset, |
486 | 536 | static const struct aspeed_sgpio_pdata ast2600_sgpiom_pdata = { |
487 | 537 | .pin_mask = GENMASK(10, 6), |
488 | 538 | .llops = &aspeed_sgpio_g4_llops, |
| 539 | + .cfg_offset = ASPEED_SGPIO_G4_CFG_OFFSET, |
| 540 | +}; |
| 541 | + |
| 542 | +static void aspeed_sgpio_g7_reg_bit_set(struct aspeed_sgpio *gpio, unsigned int offset, |
| 543 | + const enum aspeed_sgpio_reg reg, bool val) |
| 544 | +{ |
| 545 | + u32 mask = aspeed_sgpio_g7_reg_mask(reg); |
| 546 | + void __iomem *addr = gpio->base + SGPIO_G7_CTRL_REG_OFFSET(offset >> 1); |
| 547 | + u32 write_val; |
| 548 | + |
| 549 | + if (mask) { |
| 550 | + write_val = (ioread32(addr) & ~(mask)) | field_prep(mask, val); |
| 551 | + iowrite32(write_val, addr); |
| 552 | + } |
| 553 | +} |
| 554 | + |
| 555 | +static bool aspeed_sgpio_g7_reg_bit_get(struct aspeed_sgpio *gpio, unsigned int offset, |
| 556 | + const enum aspeed_sgpio_reg reg) |
| 557 | +{ |
| 558 | + u32 mask = aspeed_sgpio_g7_reg_mask(reg); |
| 559 | + void __iomem *addr; |
| 560 | + |
| 561 | + addr = gpio->base + SGPIO_G7_CTRL_REG_OFFSET(offset >> 1); |
| 562 | + if (reg == reg_val) |
| 563 | + mask = SGPIO_G7_IN_DATA; |
| 564 | + |
| 565 | + if (mask) |
| 566 | + return field_get(mask, ioread32(addr)); |
| 567 | + else |
| 568 | + return 0; |
| 569 | +} |
| 570 | + |
| 571 | +static int aspeed_sgpio_g7_reg_bank_get(struct aspeed_sgpio *gpio, unsigned int offset, |
| 572 | + const enum aspeed_sgpio_reg reg) |
| 573 | +{ |
| 574 | + void __iomem *addr; |
| 575 | + |
| 576 | + if (reg == reg_irq_status) { |
| 577 | + addr = gpio->base + SGPIO_G7_IRQ_STS_OFFSET(offset >> 6); |
| 578 | + return ioread32(addr); |
| 579 | + } else { |
| 580 | + return -EOPNOTSUPP; |
| 581 | + } |
| 582 | +} |
| 583 | + |
| 584 | +static const struct aspeed_sgpio_llops aspeed_sgpio_g7_llops = { |
| 585 | + .reg_bit_set = aspeed_sgpio_g7_reg_bit_set, |
| 586 | + .reg_bit_get = aspeed_sgpio_g7_reg_bit_get, |
| 587 | + .reg_bank_get = aspeed_sgpio_g7_reg_bank_get, |
| 588 | +}; |
| 589 | + |
| 590 | +static const struct aspeed_sgpio_pdata ast2700_sgpiom_pdata = { |
| 591 | + .pin_mask = GENMASK(11, 6), |
| 592 | + .llops = &aspeed_sgpio_g7_llops, |
| 593 | + .cfg_offset = ASPEED_SGPIO_G7_CFG_OFFSET, |
489 | 594 | }; |
490 | 595 |
|
491 | 596 | static const struct of_device_id aspeed_sgpio_of_table[] = { |
492 | 597 | { .compatible = "aspeed,ast2400-sgpio", .data = &ast2400_sgpio_pdata, }, |
493 | 598 | { .compatible = "aspeed,ast2500-sgpio", .data = &ast2400_sgpio_pdata, }, |
494 | 599 | { .compatible = "aspeed,ast2600-sgpiom", .data = &ast2600_sgpiom_pdata, }, |
| 600 | + { .compatible = "aspeed,ast2700-sgpiom", .data = &ast2700_sgpiom_pdata, }, |
495 | 601 | {} |
496 | 602 | }; |
497 | 603 |
|
@@ -562,7 +668,7 @@ static int aspeed_sgpio_probe(struct platform_device *pdev) |
562 | 668 |
|
563 | 669 | gpio_cnt_regval = ((nr_gpios / 8) << ASPEED_SGPIO_PINS_SHIFT) & pin_mask; |
564 | 670 | iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval | |
565 | | - ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL); |
| 671 | + ASPEED_SGPIO_ENABLE, gpio->base + gpio->pdata->cfg_offset); |
566 | 672 |
|
567 | 673 | raw_spin_lock_init(&gpio->lock); |
568 | 674 |
|
|
0 commit comments