1 /* 2 * Copyright (c) 2020 Nuvoton Technology Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef _NUVOTON_NPCX_SOC_DT_H_ 8 #define _NUVOTON_NPCX_SOC_DT_H_ 9 10 #include <zephyr/devicetree.h> 11 #include <zephyr/irq.h> 12 #include <zephyr/sys/util_macro.h> 13 14 /** 15 * @brief Like DT_PROP(), but expand parameters with 16 * DT_ENUM_UPPER_TOKEN not DT_PROP 17 * 18 * If the prop exists, this expands to DT_ENUM_UPPER_TOKEN(node_id, prop). 19 * The default_value parameter is not expanded in this case. 20 * 21 * Otherwise, this expands to default_value. 22 * 23 * @param node_id node identifier 24 * @param prop lowercase-and-underscores property name 25 * @param default_value a fallback value to expand to 26 * @return the property's enum upper token value or default_value 27 */ 28 #define NPCX_DT_PROP_ENUM_OR(node_id, prop, default_value) \ 29 COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \ 30 (DT_STRING_UPPER_TOKEN(node_id, prop)), (default_value)) 31 32 /** 33 * @brief Like DT_INST_PROP_OR(), but expand parameters with 34 * NPCX_DT_PROP_ENUM_OR not DT_PROP_OR 35 * @param inst instance number 36 * @param prop lowercase-and-underscores property name 37 * @param default_value a fallback value to expand to 38 * @return the property's enum upper token value or default_value 39 */ 40 #define NPCX_DT_INST_PROP_ENUM_OR(inst, prop, default_value) \ 41 NPCX_DT_PROP_ENUM_OR(DT_DRV_INST(inst), prop, default_value) 42 43 /** 44 * @brief Construct a npcx_clk_cfg item from first item in 'clocks' prop which 45 * type is 'phandle-array' to handle "clock-cells" in current driver. 46 * 47 * Example devicetree fragment: 48 * / { 49 * uart1: serial@400c4000 { 50 * clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL1 4>; 51 * ... 52 * }; 53 * }; 54 * 55 * Example usage: 56 * const struct npcx_clk_cfg clk_cfg = NPCX_DT_CLK_CFG_ITEM(inst); 57 * 58 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 59 * @return npcx_clk_cfg item. 60 */ 61 #define NPCX_DT_CLK_CFG_ITEM(inst) \ 62 { \ 63 .bus = NPCX_DT_INST_PROP_ENUM_OR(inst, clock_bus, \ 64 DT_PHA(DT_DRV_INST(inst), clocks, bus)), \ 65 .ctrl = DT_PHA(DT_DRV_INST(inst), clocks, ctl), \ 66 .bit = DT_PHA(DT_DRV_INST(inst), clocks, bit), \ 67 } 68 69 /** 70 * @brief Construct a npcx_clk_cfg structure from 'clocks' property at index 'i' 71 * 72 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 73 * @param i index of clocks prop which type is 'phandle-array' 74 * @return npcx_clk_cfg item from 'clocks' property at index 'i' 75 */ 76 #define NPCX_DT_CLK_CFG_ITEM_BY_IDX(inst, i) \ 77 { \ 78 .bus = DT_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), i, bus), \ 79 .ctrl = DT_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), i, ctl), \ 80 .bit = DT_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), i, bit), \ 81 } 82 83 /** 84 * @brief Construct a npcx_clk_cfg structure from 'clocks' with the same clock 'name'. 85 * 86 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 87 * @param name name of the clock 88 * @return npcx_clk_cfg item from 'clocks' property with the same clock 'name' 89 */ 90 #define NPCX_DT_CLK_CFG_ITEM_BY_NAME(inst, name) \ 91 { \ 92 .bus = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, bus), \ 93 .ctrl = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, ctl), \ 94 .bit = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, bit), \ 95 } 96 97 /** 98 * @brief Length of 'clocks' property which type is 'phandle-array' 99 * 100 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 101 * @return length of 'clocks' property which type is 'phandle-array' 102 */ 103 #define NPCX_DT_CLK_CFG_ITEMS_LEN(inst) DT_INST_PROP_LEN(inst, clocks) 104 105 /** 106 * @brief Macro function to construct npcx_clk_cfg item in UTIL_LISTIFY 107 * extension. 108 * 109 * @param child child index in UTIL_LISTIFY extension. 110 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 111 * @return macro function to construct a npcx_clk_cfg structure. 112 */ 113 #define NPCX_DT_CLK_CFG_ITEMS_FUNC(child, inst) \ 114 NPCX_DT_CLK_CFG_ITEM_BY_IDX(inst, child) 115 116 /** 117 * @brief Macro function to construct a list of npcx_clk_cfg items by 118 * UTIL_LISTIFY func 119 * 120 * Example devicetree fragment: 121 * / { 122 * host_sub: lpc@400c1000 { 123 * clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 3>, 124 * <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 4>, 125 * <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 5>, 126 * <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 6>, 127 * <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 7>; 128 * ... 129 * }; 130 * Example usage: 131 * const struct npcx_clk_cfg clk_cfg[] = NPCX_DT_CLK_CFG_ITEMS_LIST(0); 132 * 133 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 134 * @return an array of npcx_clk_cfg items. 135 */ 136 #define NPCX_DT_CLK_CFG_ITEMS_LIST(inst) { \ 137 LISTIFY(NPCX_DT_CLK_CFG_ITEMS_LEN(inst), \ 138 NPCX_DT_CLK_CFG_ITEMS_FUNC, (,), \ 139 inst) \ 140 } 141 142 /** 143 * @brief Get phandle from "name" property which contains wui information. 144 * 145 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 146 * @param name property 'name' which type is 'phandle' and contains wui info. 147 * @return phandle from 'name' property. 148 */ 149 #define NPCX_DT_PHANDLE_FROM_WUI_NAME(inst, name) \ 150 DT_INST_PHANDLE(inst, name) 151 152 /** 153 * @brief Construct a npcx_wui structure from 'name' property 154 * 155 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 156 * @param name property 'name'which type is 'phandle' and contains wui info. 157 * @return npcx_wui item from 'name' property. 158 */ 159 #define NPCX_DT_WUI_ITEM_BY_NAME(inst, name) \ 160 { \ 161 .table = DT_PROP(DT_PHANDLE(NPCX_DT_PHANDLE_FROM_WUI_NAME(inst, \ 162 name), miwus), index), \ 163 .group = DT_PHA(NPCX_DT_PHANDLE_FROM_WUI_NAME(inst, name), miwus, \ 164 group), \ 165 .bit = DT_PHA(NPCX_DT_PHANDLE_FROM_WUI_NAME(inst, name), miwus, \ 166 bit), \ 167 } 168 169 /** 170 * @brief Get phandle from 'wui-maps' prop which type is 'phandles' at index 'i' 171 * 172 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 173 * @param i index of 'wui-maps' prop which type is 'phandles' 174 * @return phandle from 'wui-maps' prop at index 'i' 175 */ 176 #define NPCX_DT_PHANDLE_FROM_WUI_MAPS(inst, i) \ 177 DT_INST_PHANDLE_BY_IDX(inst, wui_maps, i) 178 179 /** 180 * @brief Construct a npcx_wui structure from wui-maps property at index 'i' 181 * 182 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 183 * @param i index of 'wui-maps' prop which type is 'phandles' 184 * @return npcx_wui item at index 'i' 185 */ 186 #define NPCX_DT_WUI_ITEM_BY_IDX(inst, i) \ 187 { \ 188 .table = DT_PROP(DT_PHANDLE(NPCX_DT_PHANDLE_FROM_WUI_MAPS(inst, i), \ 189 miwus), index), \ 190 .group = DT_PHA(NPCX_DT_PHANDLE_FROM_WUI_MAPS(inst, i), miwus, \ 191 group), \ 192 .bit = DT_PHA(NPCX_DT_PHANDLE_FROM_WUI_MAPS(inst, i), miwus, bit), \ 193 } 194 195 /** 196 * @brief Length of npcx_wui structures in 'wui-maps' property 197 * 198 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 199 * @return length of 'wui-maps' prop which type is 'phandles' 200 */ 201 #define NPCX_DT_WUI_ITEMS_LEN(inst) DT_INST_PROP_LEN(inst, wui_maps) 202 203 /** 204 * @brief Macro function to construct a list of npcx_wui items by UTIL_LISTIFY 205 * 206 * @param child child index in UTIL_LISTIFY extension. 207 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 208 * @return macro function to construct a npcx_wui structure. 209 */ 210 #define NPCX_DT_WUI_ITEMS_FUNC(child, inst) NPCX_DT_WUI_ITEM_BY_IDX(inst, child) 211 212 /** 213 * @brief Macro function to construct a list of npcx_wui items by UTIL_LISTIFY 214 * func. 215 * 216 * Example devicetree fragment: 217 * / { 218 * uart1: serial@400c4000 { 219 * uart-rx = <&wui_cr_sin1>; 220 * ... 221 * }; 222 * 223 * gpio0: gpio@40081000 { 224 * wui-maps = <&wui_io00 &wui_io01 &wui_io02 &wui_io03 225 * &wui_io04 &wui_io05 &wui_io06 &wui_io07>; 226 * ... 227 * }; 228 * }; 229 * 230 * Example usage: 231 * const struct npcx_wui wui_map = NPCX_DT_PHANDLE_FROM_WUI_NAME(inst, uart_rx); 232 * const struct npcx_wui wui_maps[] = NPCX_DT_WUI_ITEMS_LIST(inst); 233 * 234 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 235 * @return an array of npcx_wui items. 236 */ 237 #define NPCX_DT_WUI_ITEMS_LIST(inst) { \ 238 LISTIFY(NPCX_DT_WUI_ITEMS_LEN(inst), \ 239 NPCX_DT_WUI_ITEMS_FUNC, (,), \ 240 inst) \ 241 } 242 243 /** 244 * @brief Get a node from path '/npcx_miwus_map/map_miwu(0/1/2)_groups' 245 * 246 * @param i index of npcx miwu devices 247 * @return node identifier with that path. 248 */ 249 #define NPCX_DT_NODE_FROM_MIWU_MAP(i) DT_PATH(npcx_miwus_int_map, \ 250 map_miwu##i##_groups) 251 /** 252 * @brief Get the index prop from parent MIWU device node. 253 * 254 * @param child index in UTIL_LISTIFY extension. 255 * @return 'index' prop value of the node which compatible type is 256 * "nuvoton,npcx-miwu". 257 */ 258 #define NPCX_DT_MIWU_IRQ_TABLE_IDX(child) \ 259 DT_PROP(DT_PHANDLE(DT_PARENT(child), parent), index) 260 261 /** 262 * @brief Macro function for DT_FOREACH_CHILD to generate a IRQ_CONNECT 263 * implementation. 264 * 265 * @param child index in UTIL_LISTIFY extension. 266 * @return implementation to initialize interrupts of MIWU groups and enable 267 * them. 268 */ 269 #define NPCX_DT_MIWU_IRQ_CONNECT_IMPL_CHILD_FUNC(child) \ 270 NPCX_DT_MIWU_IRQ_CONNECT_IMPL_CHILD_FUNC_OBJ(child); 271 272 #define NPCX_DT_MIWU_IRQ_CONNECT_IMPL_CHILD_FUNC_OBJ(child) \ 273 do { \ 274 IRQ_CONNECT(DT_PROP(child, irq), \ 275 DT_PROP(child, irq_prio), \ 276 NPCX_MIWU_ISR_FUNC(NPCX_DT_MIWU_IRQ_TABLE_IDX(child)), \ 277 DT_PROP(child, group_mask), \ 278 0); \ 279 irq_enable(DT_PROP(child, irq)); \ 280 } while (false) 281 282 /** 283 * @brief Get a child node from path '/npcx-espi-vws-map/name'. 284 * 285 * @param name a path which name is /npcx-espi-vws-map/'name'. 286 * @return child node identifier with that path. 287 */ 288 #define NPCX_DT_NODE_FROM_VWTABLE(name) DT_CHILD(DT_PATH(npcx_espi_vws_map), \ 289 name) 290 291 /** 292 * @brief Get phandle from vw-wui property of child node with that path. 293 * 294 * @param name path which name is /npcx-espi-vws-map/'name'. 295 * @return phandle from "vw-wui" prop of child node with that path. 296 */ 297 #define NPCX_DT_PHANDLE_VW_WUI(name) DT_PHANDLE(NPCX_DT_NODE_FROM_VWTABLE( \ 298 name), vw_wui) 299 300 /** 301 * @brief Construct a npcx_wui structure from vw-wui property of a child node 302 * with that path. 303 * 304 * @param name a path which name is /npcx-espi-vws-map/'name'. 305 * @return npcx_wui item with that path. 306 */ 307 #define NPCX_DT_VW_WUI_ITEM(name) \ 308 { \ 309 .table = DT_PROP(DT_PHANDLE(NPCX_DT_PHANDLE_VW_WUI(name), miwus), \ 310 index),\ 311 .group = DT_PHA(NPCX_DT_PHANDLE_VW_WUI(name), miwus, group), \ 312 .bit = DT_PHA(NPCX_DT_PHANDLE_VW_WUI(name), miwus, bit), \ 313 } 314 315 /** 316 * @brief Construct a npcx espi device configuration of vw input signal from 317 * a child node with that path. 318 * 319 * @signal vw input signal name. 320 * @param name a path which name is /npcx-espi-vws-map/'name'. 321 * @return npcx_vw_in_config item with that path. 322 */ 323 #define NPCX_DT_VW_IN_CONF(signal, name) \ 324 { \ 325 .sig = signal, \ 326 .reg_idx = DT_PROP_BY_IDX(NPCX_DT_NODE_FROM_VWTABLE(name), vw_reg, \ 327 0), \ 328 .bitmask = DT_PROP_BY_IDX(NPCX_DT_NODE_FROM_VWTABLE(name), vw_reg, \ 329 1), \ 330 .vw_wui = NPCX_DT_VW_WUI_ITEM(name), \ 331 } 332 333 /** 334 * @brief Construct a npcx espi device configuration of vw output signal from 335 * a child node with that path. 336 * 337 * @signal vw output signal name. 338 * @param name a path which name is /npcx-espi-vws-map/'name'. 339 * @return npcx_vw_in_config item with that path. 340 */ 341 #define NPCX_DT_VW_OUT_CONF(signal, name) \ 342 { \ 343 .sig = signal, \ 344 .reg_idx = DT_PROP_BY_IDX(NPCX_DT_NODE_FROM_VWTABLE(name), vw_reg, \ 345 0), \ 346 .bitmask = DT_PROP_BY_IDX(NPCX_DT_NODE_FROM_VWTABLE(name), vw_reg, \ 347 1), \ 348 } 349 350 /** 351 * @brief Construct a npcx_lvol structure from 'lvol-maps' property at index 'i'. 352 * 353 * @param node_id Node identifier. 354 * @param prop Low voltage configurations property name. (i.e. 'lvol-maps') 355 * @param idx Property entry index. 356 */ 357 #define NPCX_DT_LVOL_CTRL_NONE \ 358 DT_PHA(DT_NODELABEL(lvol_none), lvols, ctrl) 359 360 /** 361 * @brief Length of npcx_lvol structures in 'lvol-maps' property 362 * 363 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 364 * @return length of 'lvol-maps' prop which type is 'phandles' 365 */ 366 #define NPCX_DT_LVOL_ITEMS_LEN(inst) DT_INST_PROP_LEN(inst, lvol_maps) 367 368 /** 369 * @brief Construct a npcx_lvol structure from 'lvol-maps' property at index 'i'. 370 * 371 * @param node_id Node identifier. 372 * @param prop Low voltage configurations property name. (i.e. 'lvol-maps') 373 * @param idx Property entry index. 374 */ 375 #define NPCX_DT_LVOL_ITEMS_INIT(node_id, prop, idx) \ 376 { \ 377 .ctrl = DT_PHA(DT_PROP_BY_IDX(node_id, prop, idx), lvols, ctrl), \ 378 .bit = DT_PHA(DT_PROP_BY_IDX(node_id, prop, idx), lvols, bit), \ 379 }, 380 381 /** 382 * @brief Macro function to construct a list of npcx_lvol items from 'lvol-maps' 383 * property. 384 * 385 * @param inst instance number for compatible defined in DT_DRV_COMPAT. 386 * @return an array of npcx_lvol items. 387 */ 388 #define NPCX_DT_LVOL_ITEMS_LIST(inst) { \ 389 DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), lvol_maps, \ 390 NPCX_DT_LVOL_ITEMS_INIT)} 391 392 /** 393 * @brief Check if the host interface type is automatically configured by 394 * booter. 395 * 396 * @return TRUE - if the host interface is configured by booter, 397 * FALSE - otherwise. 398 */ 399 #define NPCX_BOOTER_IS_HIF_TYPE_SET() \ 400 DT_PROP(DT_PATH(booter_variant), hif_type_auto) 401 402 /** 403 * @brief Helper macro to get address of system configuration module which is 404 * used by serval peripheral device drivers in npcx series. 405 * 406 * @return base address of system configuration module. 407 */ 408 #define NPCX_SCFG_REG_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), scfg) 409 410 /** 411 * @brief Helper macro to get address of system glue module which is 412 * used by serval peripheral device drivers in npcx series. 413 * 414 * @return base address of system glue module. 415 */ 416 #define NPCX_GLUE_REG_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), glue) 417 418 #endif /* _NUVOTON_NPCX_SOC_DT_H_ */ 419