1*ce211e92Skettenis /* $OpenBSD: ofw_misc.h,v 1.31 2023/09/21 20:26:17 kettenis Exp $ */ 286ab2308Skettenis /* 3aa1f5e88Skettenis * Copyright (c) 2017-2021 Mark Kettenis 486ab2308Skettenis * 586ab2308Skettenis * Permission to use, copy, modify, and distribute this software for any 686ab2308Skettenis * purpose with or without fee is hereby granted, provided that the above 786ab2308Skettenis * copyright notice and this permission notice appear in all copies. 886ab2308Skettenis * 986ab2308Skettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1086ab2308Skettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1186ab2308Skettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1286ab2308Skettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1386ab2308Skettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1486ab2308Skettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1586ab2308Skettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1686ab2308Skettenis */ 1786ab2308Skettenis 1886ab2308Skettenis #ifndef _DEV_OFW_MISC_H_ 1986ab2308Skettenis #define _DEV_OFW_MISC_H_ 2086ab2308Skettenis 212ec99202Skettenis /* Register maps */ 222ec99202Skettenis 2386ab2308Skettenis void regmap_register(int, bus_space_tag_t, bus_space_handle_t, bus_size_t); 2486ab2308Skettenis 2586ab2308Skettenis struct regmap; 26a31afb08Spatrick struct regmap *regmap_bycompatible(char *); 27b8cbdd99Skettenis struct regmap *regmap_bynode(int); 2886ab2308Skettenis struct regmap *regmap_byphandle(uint32_t); 2986ab2308Skettenis 3086ab2308Skettenis uint32_t regmap_read_4(struct regmap *, bus_size_t); 3186ab2308Skettenis void regmap_write_4(struct regmap *, bus_size_t, uint32_t); 3286ab2308Skettenis 338f2101caSdlg /* Interface support */ 348f2101caSdlg 358f2101caSdlg struct ifnet; 368f2101caSdlg 378f2101caSdlg struct if_device { 388f2101caSdlg int if_node; 398f2101caSdlg struct ifnet *if_ifp; 408f2101caSdlg 418f2101caSdlg LIST_ENTRY(if_device) if_list; 428f2101caSdlg uint32_t if_phandle; 438f2101caSdlg }; 448f2101caSdlg 458f2101caSdlg void if_register(struct if_device *); 468f2101caSdlg 478f2101caSdlg struct ifnet *if_bynode(int); 488f2101caSdlg struct ifnet *if_byphandle(uint32_t); 498f2101caSdlg 502ec99202Skettenis /* PHY support */ 512ec99202Skettenis 522ec99202Skettenis #define PHY_NONE 0 532ec99202Skettenis #define PHY_TYPE_SATA 1 542ec99202Skettenis #define PHY_TYPE_PCIE 2 552ec99202Skettenis #define PHY_TYPE_USB2 3 562ec99202Skettenis #define PHY_TYPE_USB3 4 572ec99202Skettenis #define PHY_TYPE_UFS 5 582ec99202Skettenis 592ec99202Skettenis struct phy_device { 602ec99202Skettenis int pd_node; 612ec99202Skettenis void *pd_cookie; 622ec99202Skettenis int (*pd_enable)(void *, uint32_t *); 632ec99202Skettenis 642ec99202Skettenis LIST_ENTRY(phy_device) pd_list; 652ec99202Skettenis uint32_t pd_phandle; 662ec99202Skettenis uint32_t pd_cells; 672ec99202Skettenis }; 682ec99202Skettenis 692ec99202Skettenis void phy_register(struct phy_device *); 702ec99202Skettenis 713ce5e03eSdlg int phy_enable_prop_idx(int, char *, int); 722ec99202Skettenis int phy_enable_idx(int, int); 732ec99202Skettenis int phy_enable(int, const char *); 742ec99202Skettenis 754216024aSpatrick /* I2C support */ 764216024aSpatrick 774216024aSpatrick struct i2c_controller; 784216024aSpatrick struct i2c_bus { 794216024aSpatrick int ib_node; 804216024aSpatrick struct i2c_controller *ib_ic; 814216024aSpatrick 824216024aSpatrick LIST_ENTRY(i2c_bus) ib_list; 834216024aSpatrick uint32_t ib_phandle; 844216024aSpatrick }; 854216024aSpatrick 864216024aSpatrick void i2c_register(struct i2c_bus *); 874216024aSpatrick 884216024aSpatrick struct i2c_controller *i2c_bynode(int); 894216024aSpatrick struct i2c_controller *i2c_byphandle(uint32_t); 904216024aSpatrick 915296b96aSpatrick /* SFP support */ 925296b96aSpatrick 935296b96aSpatrick struct if_sffpage; 945296b96aSpatrick struct sfp_device { 955296b96aSpatrick int sd_node; 965296b96aSpatrick void *sd_cookie; 979e963265Skettenis int (*sd_enable)(void *, int); 985296b96aSpatrick int (*sd_get_sffpage)(void *, struct if_sffpage *); 995296b96aSpatrick 1005296b96aSpatrick LIST_ENTRY(sfp_device) sd_list; 1015296b96aSpatrick uint32_t sd_phandle; 1025296b96aSpatrick }; 1035296b96aSpatrick 1045296b96aSpatrick void sfp_register(struct sfp_device *); 1055296b96aSpatrick 106e9d39bafSkettenis struct mii_data; 1079e963265Skettenis int sfp_enable(uint32_t); 1089e963265Skettenis int sfp_disable(uint32_t); 109e9d39bafSkettenis int sfp_add_media(uint32_t, struct mii_data *); 1105296b96aSpatrick int sfp_get_sffpage(uint32_t, struct if_sffpage *); 1115296b96aSpatrick 1121eb4c955Skettenis /* PWM support */ 1131eb4c955Skettenis 1141eb4c955Skettenis #define PWM_POLARITY_INVERTED 0x00000001 1151eb4c955Skettenis 1161eb4c955Skettenis struct pwm_state { 1171eb4c955Skettenis uint32_t ps_period; 1181eb4c955Skettenis uint32_t ps_pulse_width; 1191eb4c955Skettenis uint32_t ps_flags; 1201eb4c955Skettenis int ps_enabled; 1211eb4c955Skettenis }; 1221eb4c955Skettenis 1231eb4c955Skettenis struct pwm_device { 1241eb4c955Skettenis int pd_node; 1251eb4c955Skettenis void *pd_cookie; 1261eb4c955Skettenis int (*pd_get_state)(void *, uint32_t *, struct pwm_state *); 1271eb4c955Skettenis int (*pd_set_state)(void *, uint32_t *, struct pwm_state *); 1281eb4c955Skettenis 1291eb4c955Skettenis LIST_ENTRY(pwm_device) pd_list; 1301eb4c955Skettenis uint32_t pd_phandle; 1311eb4c955Skettenis uint32_t pd_cells; 1321eb4c955Skettenis }; 1331eb4c955Skettenis 1341eb4c955Skettenis void pwm_register(struct pwm_device *); 1351eb4c955Skettenis 1361eb4c955Skettenis int pwm_init_state(uint32_t *cells, struct pwm_state *ps); 1371eb4c955Skettenis int pwm_get_state(uint32_t *cells, struct pwm_state *ps); 1381eb4c955Skettenis int pwm_set_state(uint32_t *cells, struct pwm_state *ps); 1391eb4c955Skettenis 140047fbc8bSkettenis /* Non-volatile memory support */ 141047fbc8bSkettenis 142047fbc8bSkettenis struct nvmem_device { 143047fbc8bSkettenis int nd_node; 144047fbc8bSkettenis void *nd_cookie; 145047fbc8bSkettenis int (*nd_read)(void *, bus_addr_t, void *, bus_size_t); 1462b93968fSkettenis int (*nd_write)(void *, bus_addr_t, const void *, bus_size_t); 147047fbc8bSkettenis 148047fbc8bSkettenis LIST_ENTRY(nvmem_device) nd_list; 149047fbc8bSkettenis uint32_t nd_phandle; 150047fbc8bSkettenis }; 151047fbc8bSkettenis 152047fbc8bSkettenis void nvmem_register(struct nvmem_device *); 153047fbc8bSkettenis int nvmem_read(uint32_t, bus_addr_t, void *, bus_size_t); 1541bd1536fSkettenis int nvmem_read_cell(int, const char *name, void *, bus_size_t); 1552b93968fSkettenis int nvmem_write_cell(int, const char *name, const void *, bus_size_t); 156047fbc8bSkettenis 157c2490375Skettenis /* Port/endpoint interface support */ 158f11bbe72Spatrick 159c2490375Skettenis struct endpoint; 160f11bbe72Spatrick 161c2490375Skettenis struct device_ports { 162c2490375Skettenis int dp_node; 163c2490375Skettenis void *dp_cookie; 164f11bbe72Spatrick 165c2490375Skettenis int (*dp_ep_activate)(void *, struct endpoint *, void *); 166c2490375Skettenis void *(*dp_ep_get_cookie)(void *, struct endpoint *); 167c2490375Skettenis 168c2490375Skettenis LIST_HEAD(, device_port) dp_ports; 169f11bbe72Spatrick }; 170f11bbe72Spatrick 171c2490375Skettenis struct device_port { 172c2490375Skettenis int dp_node; 173c2490375Skettenis uint32_t dp_phandle; 174c2490375Skettenis uint32_t dp_reg; 175c2490375Skettenis struct device_ports *dp_ports; 176c2490375Skettenis LIST_ENTRY(device_port) dp_list; 177c2490375Skettenis LIST_HEAD(, endpoint) dp_endpoints; 178c2490375Skettenis }; 179c2490375Skettenis 180c2490375Skettenis enum endpoint_type { 181c2490375Skettenis EP_DRM_BRIDGE = 1, /* struct drm_bridge */ 182c2490375Skettenis EP_DRM_CONNECTOR, /* struct drm_connector */ 183c2490375Skettenis EP_DRM_CRTC, /* struct drm_crtc */ 184c2490375Skettenis EP_DRM_ENCODER, /* struct drm_encoder */ 185c2490375Skettenis EP_DRM_PANEL, /* struct drm_panel */ 18657d4ae74Skettenis EP_DAI_DEVICE, /* struct dai_device */ 187ade86d6eSkettenis EP_USB_CONTROLLER_PORT, /* struct usb_controller_port */ 188ade86d6eSkettenis }; 189ade86d6eSkettenis 190ade86d6eSkettenis struct usb_controller_port { 191ade86d6eSkettenis void *up_cookie; 192ade86d6eSkettenis void (*up_connect)(void *); 193ade86d6eSkettenis void (*up_disconnect)(void *); 194c2490375Skettenis }; 195c2490375Skettenis 196c2490375Skettenis struct endpoint { 197c2490375Skettenis int ep_node; 198c2490375Skettenis uint32_t ep_phandle; 199c2490375Skettenis uint32_t ep_reg; 200c2490375Skettenis enum endpoint_type ep_type; 201c2490375Skettenis struct device_port *ep_port; 202c2490375Skettenis LIST_ENTRY(endpoint) ep_list; 203c2490375Skettenis LIST_ENTRY(endpoint) ep_plist; 204c2490375Skettenis }; 205c2490375Skettenis 206c2490375Skettenis void device_ports_register(struct device_ports *, enum endpoint_type); 20757d4ae74Skettenis struct device_ports *device_ports_byphandle(uint32_t); 208eebea054Skettenis int device_port_activate(uint32_t, void *); 209c2490375Skettenis struct endpoint *endpoint_byreg(struct device_ports *, uint32_t, uint32_t); 210c2490375Skettenis struct endpoint *endpoint_remote(struct endpoint *); 211c2490375Skettenis int endpoint_activate(struct endpoint *, void *); 212c2490375Skettenis void *endpoint_get_cookie(struct endpoint *); 213f11bbe72Spatrick 214470a8ce0Spatrick /* Digital audio interface support */ 215470a8ce0Spatrick 216470a8ce0Spatrick struct dai_device { 217470a8ce0Spatrick int dd_node; 218470a8ce0Spatrick void *dd_cookie; 2190d6a2fdeSmiod const void *dd_hw_if; 220470a8ce0Spatrick int (*dd_set_format)(void *, uint32_t, uint32_t, uint32_t); 221470a8ce0Spatrick int (*dd_set_sysclk)(void *, uint32_t); 2227141bfc1Skettenis int (*dd_set_tdm_slot)(void *, int); 223470a8ce0Spatrick 224470a8ce0Spatrick LIST_ENTRY(dai_device) dd_list; 225470a8ce0Spatrick uint32_t dd_phandle; 22657d4ae74Skettenis 22757d4ae74Skettenis struct device_ports dd_ports; 228470a8ce0Spatrick }; 229470a8ce0Spatrick 230470a8ce0Spatrick void dai_register(struct dai_device *); 231470a8ce0Spatrick struct dai_device *dai_byphandle(uint32_t); 232470a8ce0Spatrick 233470a8ce0Spatrick #define DAI_FORMAT_I2S 0 234470a8ce0Spatrick #define DAI_FORMAT_RJ 1 235470a8ce0Spatrick #define DAI_FORMAT_LJ 2 236470a8ce0Spatrick #define DAI_FORMAT_DSPA 3 237470a8ce0Spatrick #define DAI_FORMAT_DSPB 4 238470a8ce0Spatrick #define DAI_FORMAT_AC97 5 239470a8ce0Spatrick #define DAI_FORMAT_PDM 6 240470a8ce0Spatrick #define DAI_FORMAT_MSB 7 241470a8ce0Spatrick #define DAI_FORMAT_LSB 8 242470a8ce0Spatrick 243470a8ce0Spatrick #define DAI_POLARITY_NB (0 << 0) 244470a8ce0Spatrick #define DAI_POLARITY_IB (1 << 0) 245470a8ce0Spatrick #define DAI_POLARITY_NF (0 << 1) 246470a8ce0Spatrick #define DAI_POLARITY_IF (1 << 1) 247470a8ce0Spatrick 248470a8ce0Spatrick #define DAI_CLOCK_CBS (0 << 0) 249470a8ce0Spatrick #define DAI_CLOCK_CBM (1 << 0) 250470a8ce0Spatrick #define DAI_CLOCK_CFS (0 << 1) 251470a8ce0Spatrick #define DAI_CLOCK_CFM (1 << 1) 252470a8ce0Spatrick 253da5e0c17Spatrick /* MII support */ 254da5e0c17Spatrick 255da5e0c17Spatrick struct mii_bus { 256da5e0c17Spatrick int md_node; 257da5e0c17Spatrick void *md_cookie; 258da5e0c17Spatrick int (*md_readreg)(struct device *, int, int); 259da5e0c17Spatrick void (*md_writereg)(struct device *, int, int, int); 260da5e0c17Spatrick 261da5e0c17Spatrick LIST_ENTRY(mii_bus) md_list; 262da5e0c17Spatrick }; 263da5e0c17Spatrick 264da5e0c17Spatrick void mii_register(struct mii_bus *); 2655368d553Skettenis struct mii_bus *mii_bynode(int); 266da5e0c17Spatrick struct mii_bus *mii_byphandle(uint32_t); 267da5e0c17Spatrick 268682b00caSkettenis /* IOMMU support */ 269682b00caSkettenis 270682b00caSkettenis struct iommu_device { 271682b00caSkettenis int id_node; 272682b00caSkettenis void *id_cookie; 273682b00caSkettenis bus_dma_tag_t (*id_map)(void *, uint32_t *, bus_dma_tag_t); 274415019ceSpatrick void (*id_reserve)(void *, uint32_t *, bus_addr_t, bus_size_t); 275682b00caSkettenis 276682b00caSkettenis LIST_ENTRY(iommu_device) id_list; 277682b00caSkettenis uint32_t id_phandle; 278682b00caSkettenis }; 279682b00caSkettenis 280682b00caSkettenis void iommu_device_register(struct iommu_device *); 281*ce211e92Skettenis int iommu_device_lookup(int, uint32_t *, uint32_t *); 282*ce211e92Skettenis int iommu_device_lookup_pci(int, uint32_t, uint32_t *, uint32_t *); 283ba301097Spatrick bus_dma_tag_t iommu_device_map(int, bus_dma_tag_t); 284682b00caSkettenis bus_dma_tag_t iommu_device_map_pci(int, uint32_t, bus_dma_tag_t); 285415019ceSpatrick void iommu_reserve_region_pci(int, uint32_t, bus_addr_t, bus_size_t); 286682b00caSkettenis 287aa1f5e88Skettenis /* Mailbox support */ 288aa1f5e88Skettenis 289aa1f5e88Skettenis struct mbox_client { 290aa1f5e88Skettenis void (*mc_rx_callback)(void *); 291aa1f5e88Skettenis void *mc_rx_arg; 2923b6109e0Skettenis int mc_flags; 2933b6109e0Skettenis #define MC_WAKEUP 0x00000001 294aa1f5e88Skettenis }; 295aa1f5e88Skettenis 296aa1f5e88Skettenis struct mbox_channel; 297aa1f5e88Skettenis 298aa1f5e88Skettenis struct mbox_device { 299aa1f5e88Skettenis int md_node; 300aa1f5e88Skettenis void *md_cookie; 301aa1f5e88Skettenis void *(*md_channel)(void *, uint32_t *, struct mbox_client *); 302aa1f5e88Skettenis int (*md_recv)(void *, void *, size_t); 303aa1f5e88Skettenis int (*md_send)(void *, const void *, size_t); 304aa1f5e88Skettenis 305aa1f5e88Skettenis LIST_ENTRY(mbox_device) md_list; 306aa1f5e88Skettenis uint32_t md_phandle; 307aa1f5e88Skettenis uint32_t md_cells; 308aa1f5e88Skettenis }; 309aa1f5e88Skettenis 310aa1f5e88Skettenis void mbox_register(struct mbox_device *); 311aa1f5e88Skettenis 312aa1f5e88Skettenis struct mbox_channel *mbox_channel(int, const char *, struct mbox_client *); 313aa1f5e88Skettenis struct mbox_channel *mbox_channel_idx(int, int, struct mbox_client *); 314aa1f5e88Skettenis 315aa1f5e88Skettenis int mbox_send(struct mbox_channel *, const void *, size_t); 316aa1f5e88Skettenis int mbox_recv(struct mbox_channel *, void *, size_t); 317aa1f5e88Skettenis 318949f008fSpatrick /* hwlock support */ 319949f008fSpatrick 320949f008fSpatrick struct hwlock_device { 321949f008fSpatrick int hd_node; 322949f008fSpatrick void *hd_cookie; 323949f008fSpatrick int (*hd_lock)(void *, uint32_t *, int); 324949f008fSpatrick 325949f008fSpatrick LIST_ENTRY(hwlock_device) hd_list; 326949f008fSpatrick uint32_t hd_phandle; 327949f008fSpatrick uint32_t hd_cells; 328949f008fSpatrick }; 329949f008fSpatrick 330949f008fSpatrick void hwlock_register(struct hwlock_device *); 331949f008fSpatrick 332949f008fSpatrick int hwlock_lock_idx(int, int); 333949f008fSpatrick int hwlock_lock_idx_timeout(int, int, int); 334949f008fSpatrick int hwlock_unlock_idx(int, int); 335949f008fSpatrick 33686ab2308Skettenis #endif /* _DEV_OFW_MISC_H_ */ 337