333 lines
9.3 KiB
C
333 lines
9.3 KiB
C
|
/*-
|
||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||
|
*
|
||
|
* Copyright (c) 2018 Advanced Micro Devices
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
* SUCH DAMAGE.
|
||
|
*
|
||
|
* $FreeBSD$
|
||
|
*/
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
#define dprintf(fmt, args...) do { \
|
||
|
printf("%s(): ", __func__); \
|
||
|
printf(fmt,##args); \
|
||
|
} while (0)
|
||
|
#else
|
||
|
#define dprintf(fmt, args...)
|
||
|
#endif
|
||
|
|
||
|
#define AMD_GPIO_PREFIX "AMDGPIO"
|
||
|
|
||
|
#define AMD_GPIO_NUM_PIN_BANK 4
|
||
|
#define AMD_GPIO_PINS_PER_BANK 64
|
||
|
#define AMD_GPIO_PINS_MAX 256 /* 4 banks * 64 pins */
|
||
|
|
||
|
/* Number of pins in each bank */
|
||
|
#define AMD_GPIO_PINS_BANK0 63
|
||
|
#define AMD_GPIO_PINS_BANK1 64
|
||
|
#define AMD_GPIO_PINS_BANK2 56
|
||
|
#define AMD_GPIO_PINS_BANK3 32
|
||
|
#define AMD_GPIO_PIN_PRESENT (AMD_GPIO_PINS_BANK0 + \
|
||
|
AMD_GPIO_PINS_BANK1 + \
|
||
|
AMD_GPIO_PINS_BANK2 + \
|
||
|
AMD_GPIO_PINS_BANK3)
|
||
|
#define AMDGPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
|
||
|
|
||
|
/* Register related macros */
|
||
|
#define AMDGPIO_PIN_REGISTER(pin) (pin * 4)
|
||
|
|
||
|
#define WAKE_INT_MASTER_REG 0xfc
|
||
|
#define EOI_MASK (1 << 29)
|
||
|
#define WAKE_INT_STATUS_REG0 0x2f8
|
||
|
#define WAKE_INT_STATUS_REG1 0x2fc
|
||
|
|
||
|
/* Bit definition of 32 bits of each pin register */
|
||
|
#define DB_TMR_OUT_OFF 0
|
||
|
#define DB_TMR_OUT_UNIT_OFF 4
|
||
|
#define DB_CNTRL_OFF 5
|
||
|
#define DB_TMR_LARGE_OFF 7
|
||
|
#define LEVEL_TRIG_OFF 8
|
||
|
#define ACTIVE_LEVEL_OFF 9
|
||
|
#define INTERRUPT_ENABLE_OFF 11
|
||
|
#define INTERRUPT_MASK_OFF 12
|
||
|
#define WAKE_CNTRL_OFF_S0I3 13
|
||
|
#define WAKE_CNTRL_OFF_S3 14
|
||
|
#define WAKE_CNTRL_OFF_S4 15
|
||
|
#define PIN_STS_OFF 16
|
||
|
#define DRV_STRENGTH_SEL_OFF 17
|
||
|
#define PULL_UP_SEL_OFF 19
|
||
|
#define PULL_UP_ENABLE_OFF 20
|
||
|
#define PULL_DOWN_ENABLE_OFF 21
|
||
|
#define OUTPUT_VALUE_OFF 22
|
||
|
#define OUTPUT_ENABLE_OFF 23
|
||
|
#define SW_CNTRL_IN_OFF 24
|
||
|
#define SW_CNTRL_EN_OFF 25
|
||
|
#define INTERRUPT_STS_OFF 28
|
||
|
#define WAKE_STS_OFF 29
|
||
|
|
||
|
#define DB_TMR_OUT_MASK 0xFUL
|
||
|
#define DB_CNTRL_MASK 0x3UL
|
||
|
#define ACTIVE_LEVEL_MASK 0x3UL
|
||
|
#define DRV_STRENGTH_SEL_MASK 0x3UL
|
||
|
|
||
|
#define DB_TYPE_NO_DEBOUNCE 0x0UL
|
||
|
#define DB_TYPE_PRESERVE_LOW_GLITCH 0x1UL
|
||
|
#define DB_TYPE_PRESERVE_HIGH_GLITCH 0x2UL
|
||
|
#define DB_TYPE_REMOVE_GLITCH 0x3UL
|
||
|
|
||
|
#define EDGE_TRIGGER 0x0UL
|
||
|
#define LEVEL_TRIGGER 0x1UL
|
||
|
|
||
|
#define ACTIVE_HIGH 0x0UL
|
||
|
#define ACTIVE_LOW 0x1UL
|
||
|
#define BOTH_EDGE 0x2UL
|
||
|
|
||
|
#define ENABLE_INTERRUPT 0x1UL
|
||
|
#define DISABLE_INTERRUPT 0x0UL
|
||
|
|
||
|
#define ENABLE_INTERRUPT_MASK 0x0UL
|
||
|
#define DISABLE_INTERRUPT_MASK 0x1UL
|
||
|
#define CLR_INTR_STAT 0x1UL
|
||
|
|
||
|
#define BIT(bit) (1 << bit)
|
||
|
#define GPIO_PIN_INFO(p, n) { .pin_num = (p), .pin_name = (n) }
|
||
|
|
||
|
struct pin_info {
|
||
|
int pin_num;
|
||
|
char *pin_name;
|
||
|
};
|
||
|
|
||
|
/* Pins exposed to drivers */
|
||
|
static const struct pin_info kernzp_pins[] = {
|
||
|
GPIO_PIN_INFO(0, "PIN_0"),
|
||
|
GPIO_PIN_INFO(1, "PIN_1"),
|
||
|
GPIO_PIN_INFO(2, "PIN_2"),
|
||
|
GPIO_PIN_INFO(3, "PIN_3"),
|
||
|
GPIO_PIN_INFO(4, "PIN_4"),
|
||
|
GPIO_PIN_INFO(5, "PIN_5"),
|
||
|
GPIO_PIN_INFO(6, "PIN_6"),
|
||
|
GPIO_PIN_INFO(7, "PIN_7"),
|
||
|
GPIO_PIN_INFO(8, "PIN_8"),
|
||
|
GPIO_PIN_INFO(9, "PIN_9"),
|
||
|
GPIO_PIN_INFO(10, "PIN_10"),
|
||
|
GPIO_PIN_INFO(11, "PIN_11"),
|
||
|
GPIO_PIN_INFO(12, "PIN_12"),
|
||
|
GPIO_PIN_INFO(13, "PIN_13"),
|
||
|
GPIO_PIN_INFO(14, "PIN_14"),
|
||
|
GPIO_PIN_INFO(15, "PIN_15"),
|
||
|
GPIO_PIN_INFO(16, "PIN_16"),
|
||
|
GPIO_PIN_INFO(17, "PIN_17"),
|
||
|
GPIO_PIN_INFO(18, "PIN_18"),
|
||
|
GPIO_PIN_INFO(19, "PIN_19"),
|
||
|
GPIO_PIN_INFO(20, "PIN_20"),
|
||
|
GPIO_PIN_INFO(23, "PIN_23"),
|
||
|
GPIO_PIN_INFO(24, "PIN_24"),
|
||
|
GPIO_PIN_INFO(25, "PIN_25"),
|
||
|
GPIO_PIN_INFO(26, "PIN_26"),
|
||
|
GPIO_PIN_INFO(39, "PIN_39"),
|
||
|
GPIO_PIN_INFO(40, "PIN_40"),
|
||
|
GPIO_PIN_INFO(43, "PIN_43"),
|
||
|
GPIO_PIN_INFO(46, "PIN_46"),
|
||
|
GPIO_PIN_INFO(47, "PIN_47"),
|
||
|
GPIO_PIN_INFO(48, "PIN_48"),
|
||
|
GPIO_PIN_INFO(49, "PIN_49"),
|
||
|
GPIO_PIN_INFO(50, "PIN_50"),
|
||
|
GPIO_PIN_INFO(51, "PIN_51"),
|
||
|
GPIO_PIN_INFO(52, "PIN_52"),
|
||
|
GPIO_PIN_INFO(53, "PIN_53"),
|
||
|
GPIO_PIN_INFO(54, "PIN_54"),
|
||
|
GPIO_PIN_INFO(55, "PIN_55"),
|
||
|
GPIO_PIN_INFO(56, "PIN_56"),
|
||
|
GPIO_PIN_INFO(57, "PIN_57"),
|
||
|
GPIO_PIN_INFO(58, "PIN_58"),
|
||
|
GPIO_PIN_INFO(59, "PIN_59"),
|
||
|
GPIO_PIN_INFO(60, "PIN_60"),
|
||
|
GPIO_PIN_INFO(61, "PIN_61"),
|
||
|
GPIO_PIN_INFO(62, "PIN_62"),
|
||
|
GPIO_PIN_INFO(64, "PIN_64"),
|
||
|
GPIO_PIN_INFO(65, "PIN_65"),
|
||
|
GPIO_PIN_INFO(66, "PIN_66"),
|
||
|
GPIO_PIN_INFO(68, "PIN_68"),
|
||
|
GPIO_PIN_INFO(69, "PIN_69"),
|
||
|
GPIO_PIN_INFO(70, "PIN_70"),
|
||
|
GPIO_PIN_INFO(71, "PIN_71"),
|
||
|
GPIO_PIN_INFO(72, "PIN_72"),
|
||
|
GPIO_PIN_INFO(74, "PIN_74"),
|
||
|
GPIO_PIN_INFO(75, "PIN_75"),
|
||
|
GPIO_PIN_INFO(76, "PIN_76"),
|
||
|
GPIO_PIN_INFO(84, "PIN_84"),
|
||
|
GPIO_PIN_INFO(85, "PIN_85"),
|
||
|
GPIO_PIN_INFO(86, "PIN_86"),
|
||
|
GPIO_PIN_INFO(87, "PIN_87"),
|
||
|
GPIO_PIN_INFO(88, "PIN_88"),
|
||
|
GPIO_PIN_INFO(89, "PIN_89"),
|
||
|
GPIO_PIN_INFO(90, "PIN_90"),
|
||
|
GPIO_PIN_INFO(91, "PIN_91"),
|
||
|
GPIO_PIN_INFO(92, "PIN_92"),
|
||
|
GPIO_PIN_INFO(93, "PIN_93"),
|
||
|
GPIO_PIN_INFO(95, "PIN_95"),
|
||
|
GPIO_PIN_INFO(96, "PIN_96"),
|
||
|
GPIO_PIN_INFO(97, "PIN_97"),
|
||
|
GPIO_PIN_INFO(98, "PIN_98"),
|
||
|
GPIO_PIN_INFO(99, "PIN_99"),
|
||
|
GPIO_PIN_INFO(100, "PIN_100"),
|
||
|
GPIO_PIN_INFO(101, "PIN_101"),
|
||
|
GPIO_PIN_INFO(102, "PIN_102"),
|
||
|
GPIO_PIN_INFO(113, "PIN_113"),
|
||
|
GPIO_PIN_INFO(114, "PIN_114"),
|
||
|
GPIO_PIN_INFO(115, "PIN_115"),
|
||
|
GPIO_PIN_INFO(116, "PIN_116"),
|
||
|
GPIO_PIN_INFO(117, "PIN_117"),
|
||
|
GPIO_PIN_INFO(118, "PIN_118"),
|
||
|
GPIO_PIN_INFO(119, "PIN_119"),
|
||
|
GPIO_PIN_INFO(120, "PIN_120"),
|
||
|
GPIO_PIN_INFO(121, "PIN_121"),
|
||
|
GPIO_PIN_INFO(122, "PIN_122"),
|
||
|
GPIO_PIN_INFO(126, "PIN_126"),
|
||
|
GPIO_PIN_INFO(129, "PIN_129"),
|
||
|
GPIO_PIN_INFO(130, "PIN_130"),
|
||
|
GPIO_PIN_INFO(131, "PIN_131"),
|
||
|
GPIO_PIN_INFO(132, "PIN_132"),
|
||
|
GPIO_PIN_INFO(133, "PIN_133"),
|
||
|
GPIO_PIN_INFO(135, "PIN_135"),
|
||
|
GPIO_PIN_INFO(136, "PIN_136"),
|
||
|
GPIO_PIN_INFO(137, "PIN_137"),
|
||
|
GPIO_PIN_INFO(138, "PIN_138"),
|
||
|
GPIO_PIN_INFO(139, "PIN_139"),
|
||
|
GPIO_PIN_INFO(140, "PIN_140"),
|
||
|
GPIO_PIN_INFO(141, "PIN_141"),
|
||
|
GPIO_PIN_INFO(142, "PIN_142"),
|
||
|
GPIO_PIN_INFO(143, "PIN_143"),
|
||
|
GPIO_PIN_INFO(144, "PIN_144"),
|
||
|
GPIO_PIN_INFO(145, "PIN_145"),
|
||
|
GPIO_PIN_INFO(146, "PIN_146"),
|
||
|
GPIO_PIN_INFO(147, "PIN_147"),
|
||
|
GPIO_PIN_INFO(148, "PIN_148"),
|
||
|
GPIO_PIN_INFO(166, "PIN_166"),
|
||
|
GPIO_PIN_INFO(167, "PIN_167"),
|
||
|
GPIO_PIN_INFO(168, "PIN_168"),
|
||
|
GPIO_PIN_INFO(169, "PIN_169"),
|
||
|
GPIO_PIN_INFO(170, "PIN_170"),
|
||
|
GPIO_PIN_INFO(171, "PIN_171"),
|
||
|
GPIO_PIN_INFO(172, "PIN_172"),
|
||
|
GPIO_PIN_INFO(173, "PIN_173"),
|
||
|
GPIO_PIN_INFO(174, "PIN_174"),
|
||
|
GPIO_PIN_INFO(175, "PIN_175"),
|
||
|
GPIO_PIN_INFO(176, "PIN_176"),
|
||
|
GPIO_PIN_INFO(177, "PIN_177"),
|
||
|
};
|
||
|
|
||
|
#define AMD_GPIO_PINS_EXPOSED nitems(kernzp_pins)
|
||
|
|
||
|
static const unsigned i2c0_pins[] = {145, 146};
|
||
|
static const unsigned i2c1_pins[] = {147, 148};
|
||
|
static const unsigned i2c2_pins[] = {113, 114};
|
||
|
static const unsigned i2c3_pins[] = {19, 20};
|
||
|
static const unsigned i2c4_pins[] = {149, 150};
|
||
|
static const unsigned i2c5_pins[] = {151, 152};
|
||
|
|
||
|
static const unsigned uart0_pins[] = {135, 136, 137, 138, 139};
|
||
|
static const unsigned uart1_pins[] = {140, 141, 142, 143, 144};
|
||
|
|
||
|
struct amd_pingroup {
|
||
|
const char *name;
|
||
|
const unsigned *pins;
|
||
|
unsigned npins;
|
||
|
};
|
||
|
|
||
|
static const struct amd_pingroup kernzp_groups[] = {
|
||
|
{
|
||
|
.name = "i2c0",
|
||
|
.pins = i2c0_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "i2c1",
|
||
|
.pins = i2c1_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "i2c2",
|
||
|
.pins = i2c2_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "i2c3",
|
||
|
.pins = i2c3_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "i2c4",
|
||
|
.pins = i2c4_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "i2c5",
|
||
|
.pins = i2c5_pins,
|
||
|
.npins = 2,
|
||
|
},
|
||
|
{
|
||
|
.name = "uart0",
|
||
|
.pins = uart0_pins,
|
||
|
.npins = 5,
|
||
|
},
|
||
|
{
|
||
|
.name = "uart1",
|
||
|
.pins = uart1_pins,
|
||
|
.npins = 5,
|
||
|
},
|
||
|
};
|
||
|
|
||
|
/* Macros for driver mutex locking */
|
||
|
#define AMDGPIO_LOCK_INIT(_sc) \
|
||
|
mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
|
||
|
"amdgpio", MTX_SPIN)
|
||
|
#define AMDGPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
|
||
|
#define AMDGPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
|
||
|
#define AMDGPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
|
||
|
#define AMDGPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
|
||
|
#define AMDGPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
|
||
|
|
||
|
struct amdgpio_softc {
|
||
|
ACPI_HANDLE sc_handle;
|
||
|
device_t sc_dev;
|
||
|
device_t sc_busdev;
|
||
|
const char* sc_bank_prefix;
|
||
|
int sc_nbanks;
|
||
|
int sc_npins;
|
||
|
int sc_ngroups;
|
||
|
struct mtx sc_mtx;
|
||
|
struct resource *sc_res[AMD_GPIO_NUM_PIN_BANK + 1];
|
||
|
bus_space_tag_t sc_bst;
|
||
|
bus_space_handle_t sc_bsh;
|
||
|
struct gpio_pin sc_gpio_pins[AMD_GPIO_PINS_MAX];
|
||
|
const struct pin_info *sc_pin_info;
|
||
|
const struct amd_pingroup *sc_groups;
|
||
|
};
|
||
|
|
||
|
struct amdgpio_sysctl {
|
||
|
struct amdgpio_softc *sc;
|
||
|
uint32_t pin;
|
||
|
};
|