b34cae60044b803d7ca824599bd92b82c6970a4b
[platform/kernel/u-boot.git] / drivers / pinctrl / intel / pinctrl_apl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2017 Intel Corp.
4  * Copyright 2019 Google LLC
5  *
6  * Taken partly from coreboot gpio.c
7  */
8
9 #define LOG_CATEGORY UCLASS_GPIO
10
11 #include <common.h>
12 #include <dm.h>
13 #include <dt-structs.h>
14 #include <log.h>
15 #include <p2sb.h>
16 #include <asm/intel_pinctrl.h>
17 #include <asm-generic/gpio.h>
18 #include <asm/intel_pinctrl_defs.h>
19
20 /**
21  * struct apl_gpio_platdata - platform data for each device
22  *
23  * @dtplat: of-platdata data from C struct
24  */
25 struct apl_gpio_platdata {
26 #if CONFIG_IS_ENABLED(OF_PLATDATA)
27         /* Put this first since driver model will copy the data here */
28         struct dtd_intel_apl_pinctrl dtplat;
29 #endif
30 };
31
32 static const struct reset_mapping rst_map[] = {
33         { .logical = PAD_CFG0_LOGICAL_RESET_PWROK, .chipset = 0U << 30 },
34         { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30 },
35         { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30 },
36 };
37
38 /* Groups for each community */
39 static const struct pad_group apl_community_n_groups[] = {
40         INTEL_GPP(N_OFFSET, N_OFFSET, GPIO_31),         /* NORTH 0 */
41         INTEL_GPP(N_OFFSET, GPIO_32, JTAG_TRST_B),      /* NORTH 1 */
42         INTEL_GPP(N_OFFSET, JTAG_TMS, SVID0_CLK),       /* NORTH 2 */
43 };
44
45 static const struct pad_group apl_community_w_groups[] = {
46         INTEL_GPP(W_OFFSET, W_OFFSET, OSC_CLK_OUT_1),   /* WEST 0 */
47         INTEL_GPP(W_OFFSET, OSC_CLK_OUT_2, SUSPWRDNACK),/* WEST 1 */
48 };
49
50 static const struct pad_group apl_community_sw_groups[] = {
51         INTEL_GPP(SW_OFFSET, SW_OFFSET, SMB_ALERTB),    /* SOUTHWEST 0 */
52         INTEL_GPP(SW_OFFSET, SMB_CLK, LPC_FRAMEB),      /* SOUTHWEST 1 */
53 };
54
55 static const struct pad_group apl_community_nw_groups[] = {
56         INTEL_GPP(NW_OFFSET, NW_OFFSET, PROCHOT_B),     /* NORTHWEST 0 */
57         INTEL_GPP(NW_OFFSET, PMIC_I2C_SCL, GPIO_106),   /* NORTHWEST 1 */
58         INTEL_GPP(NW_OFFSET, GPIO_109, GPIO_123),       /* NORTHWEST 2 */
59 };
60
61 /* TODO(sjg@chromium.org): Consider moving this to device tree */
62 static const struct pad_community apl_gpio_communities[] = {
63         {
64                 .port = PID_GPIO_N,
65                 .first_pad = N_OFFSET,
66                 .last_pad = SVID0_CLK,
67                 .num_gpi_regs = NUM_N_GPI_REGS,
68                 .gpi_status_offset = NUM_NW_GPI_REGS + NUM_W_GPI_REGS
69                         + NUM_SW_GPI_REGS,
70                 .pad_cfg_base = PAD_CFG_BASE,
71                 .host_own_reg_0 = HOSTSW_OWN_REG_0,
72                 .gpi_int_sts_reg_0 = GPI_INT_STS_0,
73                 .gpi_int_en_reg_0 = GPI_INT_EN_0,
74                 .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
75                 .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
76                 .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
77                 .name = "GPIO_GPE_N",
78                 .reset_map = rst_map,
79                 .num_reset_vals = ARRAY_SIZE(rst_map),
80                 .groups = apl_community_n_groups,
81                 .num_groups = ARRAY_SIZE(apl_community_n_groups),
82         }, {
83                 .port = PID_GPIO_NW,
84                 .first_pad = NW_OFFSET,
85                 .last_pad = GPIO_123,
86                 .num_gpi_regs = NUM_NW_GPI_REGS,
87                 .gpi_status_offset = NUM_W_GPI_REGS + NUM_SW_GPI_REGS,
88                 .pad_cfg_base = PAD_CFG_BASE,
89                 .host_own_reg_0 = HOSTSW_OWN_REG_0,
90                 .gpi_int_sts_reg_0 = GPI_INT_STS_0,
91                 .gpi_int_en_reg_0 = GPI_INT_EN_0,
92                 .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
93                 .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
94                 .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
95                 .name = "GPIO_GPE_NW",
96                 .reset_map = rst_map,
97                 .num_reset_vals = ARRAY_SIZE(rst_map),
98                 .groups = apl_community_nw_groups,
99                 .num_groups = ARRAY_SIZE(apl_community_nw_groups),
100         }, {
101                 .port = PID_GPIO_W,
102                 .first_pad = W_OFFSET,
103                 .last_pad = SUSPWRDNACK,
104                 .num_gpi_regs = NUM_W_GPI_REGS,
105                 .gpi_status_offset = NUM_SW_GPI_REGS,
106                 .pad_cfg_base = PAD_CFG_BASE,
107                 .host_own_reg_0 = HOSTSW_OWN_REG_0,
108                 .gpi_int_sts_reg_0 = GPI_INT_STS_0,
109                 .gpi_int_en_reg_0 = GPI_INT_EN_0,
110                 .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
111                 .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
112                 .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
113                 .name = "GPIO_GPE_W",
114                 .reset_map = rst_map,
115                 .num_reset_vals = ARRAY_SIZE(rst_map),
116                 .groups = apl_community_w_groups,
117                 .num_groups = ARRAY_SIZE(apl_community_w_groups),
118         }, {
119                 .port = PID_GPIO_SW,
120                 .first_pad = SW_OFFSET,
121                 .last_pad = LPC_FRAMEB,
122                 .num_gpi_regs = NUM_SW_GPI_REGS,
123                 .gpi_status_offset = 0,
124                 .pad_cfg_base = PAD_CFG_BASE,
125                 .host_own_reg_0 = HOSTSW_OWN_REG_0,
126                 .gpi_int_sts_reg_0 = GPI_INT_STS_0,
127                 .gpi_int_en_reg_0 = GPI_INT_EN_0,
128                 .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
129                 .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
130                 .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
131                 .name = "GPIO_GPE_SW",
132                 .reset_map = rst_map,
133                 .num_reset_vals = ARRAY_SIZE(rst_map),
134                 .groups = apl_community_sw_groups,
135                 .num_groups = ARRAY_SIZE(apl_community_sw_groups),
136         },
137 };
138
139 static int apl_pinctrl_ofdata_to_platdata(struct udevice *dev)
140 {
141         struct p2sb_child_platdata *pplat;
142         const struct pad_community *comm = NULL;
143         int i;
144
145 #if CONFIG_IS_ENABLED(OF_PLATDATA)
146         struct apl_gpio_platdata *plat = dev_get_plat(dev);
147         int ret;
148
149         /*
150          * It would be nice to do this in the bind() method, but with
151          * of-platdata binding happens in the order that DM finds things in the
152          * linker list (i.e. alphabetical order by driver name). So the GPIO
153          * device may well be bound before its parent (p2sb), and this call
154          * will fail if p2sb is not bound yet.
155          *
156          * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
157          */
158         ret = p2sb_set_port_id(dev, plat->dtplat.intel_p2sb_port_id);
159         if (ret)
160                 return log_msg_ret("Could not set port id", ret);
161 #endif
162         /* Attach this device to its community structure */
163         pplat = dev_get_parent_plat(dev);
164         for (i = 0; i < ARRAY_SIZE(apl_gpio_communities); i++) {
165                 if (apl_gpio_communities[i].port == pplat->pid)
166                         comm = &apl_gpio_communities[i];
167         }
168
169         return intel_pinctrl_ofdata_to_platdata(dev, comm, 2);
170 }
171
172 static const struct udevice_id apl_gpio_ids[] = {
173         { .compatible = "intel,apl-pinctrl"},
174         { }
175 };
176
177 U_BOOT_DRIVER(intel_apl_pinctrl) = {
178         .name           = "intel_apl_pinctrl",
179         .id             = UCLASS_PINCTRL,
180         .of_match       = apl_gpio_ids,
181         .probe          = intel_pinctrl_probe,
182         .ops            = &intel_pinctrl_ops,
183 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
184         .bind           = dm_scan_fdt_dev,
185 #endif
186         .ofdata_to_platdata = apl_pinctrl_ofdata_to_platdata,
187         .priv_auto      = sizeof(struct intel_pinctrl_priv),
188         .plat_auto      = sizeof(struct apl_gpio_platdata),
189 };