17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*d58fda43Sjbeloro * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/conf.h> 317c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 327c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 337c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 347c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h> 357c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 367c478bd9Sstevel@tonic-gate #include <sys/devops.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 39*d58fda43Sjbeloro * The pmugpio driver supports ALOM GPIO bits for resetSC and 40*d58fda43Sjbeloro * watchdog heartbeat on all relevant platforms. Historically, 41*d58fda43Sjbeloro * pmugpio is a leaf off the Chalupa pmubus. In addition to 42*d58fda43Sjbeloro * this support the pmugpio driver has been modified to support 43*d58fda43Sjbeloro * Minneapolis/Boston Controller (MBC) FPGA GPIO and Seattle CPLD 44*d58fda43Sjbeloro * GPIO. 45*d58fda43Sjbeloro */ 46*d58fda43Sjbeloro 47*d58fda43Sjbeloro typedef enum { 48*d58fda43Sjbeloro PMUGPIO_MBC, /* Boston MBC FPGA GPIO - 8-bit */ 49*d58fda43Sjbeloro PMUGPIO_CPLD, /* Seattle CPLD GPIO - 8-bit */ 50*d58fda43Sjbeloro PMUGPIO_OTHER /* Chalupa - 8-bit */ 51*d58fda43Sjbeloro } pmugpio_access_type_t; 52*d58fda43Sjbeloro 53*d58fda43Sjbeloro /* 54*d58fda43Sjbeloro * CPLD GPIO Register defines. 55*d58fda43Sjbeloro */ 56*d58fda43Sjbeloro #define CPLD_RESET_SC 0x01 /* Reset SC */ 57*d58fda43Sjbeloro #define CPLD_WATCHDOG 0x02 /* Watchdog */ 58*d58fda43Sjbeloro 59*d58fda43Sjbeloro #define CPLD_RESET_DELAY 3 /* microsecond delay */ 60*d58fda43Sjbeloro 61*d58fda43Sjbeloro /* 62*d58fda43Sjbeloro * MBC FPGA CSR defines. 63*d58fda43Sjbeloro */ 64*d58fda43Sjbeloro #define MBC_PPC_RESET 0x10 /* Reset ALOM */ 65*d58fda43Sjbeloro #define MBC_WATCHDOG 0x40 /* Watchdog heartbeat bit */ 66*d58fda43Sjbeloro 67*d58fda43Sjbeloro /* 687c478bd9Sstevel@tonic-gate * Time periods, in nanoseconds 697c478bd9Sstevel@tonic-gate */ 707c478bd9Sstevel@tonic-gate #define PMUGPIO_TWO_SEC 2000000000LL 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate static dev_info_t *pmugpio_dip; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate typedef struct pmugpio_state { 757c478bd9Sstevel@tonic-gate uint8_t *pmugpio_reset_reg; 767c478bd9Sstevel@tonic-gate ddi_acc_handle_t pmugpio_reset_reg_handle; 777c478bd9Sstevel@tonic-gate uint8_t *pmugpio_watchdog_reg; 787c478bd9Sstevel@tonic-gate ddi_acc_handle_t pmugpio_watchdog_reg_handle; 797c478bd9Sstevel@tonic-gate hrtime_t hw_last_pat; 80*d58fda43Sjbeloro pmugpio_access_type_t access_type; 817c478bd9Sstevel@tonic-gate } pmugpio_state_t; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static void *pmugpio_statep; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate static int pmugpio_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 867c478bd9Sstevel@tonic-gate static int pmugpio_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 877c478bd9Sstevel@tonic-gate static int pmugpio_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 887c478bd9Sstevel@tonic-gate void **result); 897c478bd9Sstevel@tonic-gate static int pmugpio_map_regs(dev_info_t *, pmugpio_state_t *); 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate struct cb_ops pmugpio_cb_ops = { 927c478bd9Sstevel@tonic-gate nulldev, /* open */ 937c478bd9Sstevel@tonic-gate nulldev, /* close */ 947c478bd9Sstevel@tonic-gate nulldev, /* strategy */ 957c478bd9Sstevel@tonic-gate nulldev, /* print */ 967c478bd9Sstevel@tonic-gate nulldev, /* dump */ 977c478bd9Sstevel@tonic-gate nulldev, /* read */ 987c478bd9Sstevel@tonic-gate nulldev, /* write */ 997c478bd9Sstevel@tonic-gate nulldev, /* ioctl */ 1007c478bd9Sstevel@tonic-gate nulldev, /* devmap */ 1017c478bd9Sstevel@tonic-gate nulldev, /* mmap */ 1027c478bd9Sstevel@tonic-gate nulldev, /* segmap */ 1037c478bd9Sstevel@tonic-gate nochpoll, /* poll */ 1047c478bd9Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */ 1057c478bd9Sstevel@tonic-gate NULL, /* streamtab */ 1067c478bd9Sstevel@tonic-gate D_MP | D_NEW 1077c478bd9Sstevel@tonic-gate }; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate static struct dev_ops pmugpio_ops = { 1107c478bd9Sstevel@tonic-gate DEVO_REV, /* Devo_rev */ 1117c478bd9Sstevel@tonic-gate 0, /* Refcnt */ 1127c478bd9Sstevel@tonic-gate pmugpio_info, /* Info */ 1137c478bd9Sstevel@tonic-gate nulldev, /* Identify */ 1147c478bd9Sstevel@tonic-gate nulldev, /* Probe */ 1157c478bd9Sstevel@tonic-gate pmugpio_attach, /* Attach */ 1167c478bd9Sstevel@tonic-gate pmugpio_detach, /* Detach */ 1177c478bd9Sstevel@tonic-gate nodev, /* Reset */ 1187c478bd9Sstevel@tonic-gate &pmugpio_cb_ops, /* Driver operations */ 1197c478bd9Sstevel@tonic-gate 0, /* Bus operations */ 1207c478bd9Sstevel@tonic-gate NULL /* Power */ 1217c478bd9Sstevel@tonic-gate }; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate static struct modldrv modldrv = { 1247c478bd9Sstevel@tonic-gate &mod_driverops, /* This one is a driver */ 1257c478bd9Sstevel@tonic-gate "Pmugpio Driver %I%", /* Name of the module. */ 1267c478bd9Sstevel@tonic-gate &pmugpio_ops, /* Driver ops */ 1277c478bd9Sstevel@tonic-gate }; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 1307c478bd9Sstevel@tonic-gate MODREV_1, (void *)&modldrv, NULL 1317c478bd9Sstevel@tonic-gate }; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate int 1347c478bd9Sstevel@tonic-gate _init(void) 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate int error; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* Initialize the soft state structures */ 1397c478bd9Sstevel@tonic-gate if ((error = ddi_soft_state_init(&pmugpio_statep, 1407c478bd9Sstevel@tonic-gate sizeof (pmugpio_state_t), 1)) != 0) { 1417c478bd9Sstevel@tonic-gate return (error); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* Install the loadable module */ 1457c478bd9Sstevel@tonic-gate if ((error = mod_install(&modlinkage)) != 0) { 1467c478bd9Sstevel@tonic-gate ddi_soft_state_fini(&pmugpio_statep); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate return (error); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate int 1527c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate int 1587c478bd9Sstevel@tonic-gate _fini(void) 1597c478bd9Sstevel@tonic-gate { 1607c478bd9Sstevel@tonic-gate int error; 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate error = mod_remove(&modlinkage); 1637c478bd9Sstevel@tonic-gate if (error == 0) { 1647c478bd9Sstevel@tonic-gate /* Release per module resources */ 1657c478bd9Sstevel@tonic-gate ddi_soft_state_fini(&pmugpio_statep); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate return (error); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate static int 1717c478bd9Sstevel@tonic-gate pmugpio_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate int instance; 1747c478bd9Sstevel@tonic-gate pmugpio_state_t *pmugpio_ptr = NULL; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate switch (cmd) { 1777c478bd9Sstevel@tonic-gate case DDI_ATTACH: 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate case DDI_RESUME: 1807c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 1817c478bd9Sstevel@tonic-gate default: 1827c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /* Get the instance and create soft state */ 1867c478bd9Sstevel@tonic-gate instance = ddi_get_instance(dip); 1877c478bd9Sstevel@tonic-gate if (ddi_soft_state_zalloc(pmugpio_statep, instance) != 0) { 1887c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate pmugpio_ptr = ddi_get_soft_state(pmugpio_statep, instance); 1917c478bd9Sstevel@tonic-gate if (pmugpio_ptr == NULL) { 1927c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (pmugpio_map_regs(dip, pmugpio_ptr) != DDI_SUCCESS) { 1967c478bd9Sstevel@tonic-gate ddi_soft_state_free(pmugpio_statep, instance); 1977c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* Display information in the banner */ 2017c478bd9Sstevel@tonic-gate ddi_report_dev(dip); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /* Save the dip */ 2047c478bd9Sstevel@tonic-gate pmugpio_dip = dip; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2107c478bd9Sstevel@tonic-gate static int 2117c478bd9Sstevel@tonic-gate pmugpio_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 2127c478bd9Sstevel@tonic-gate { 2137c478bd9Sstevel@tonic-gate /* Pointer to soft state */ 2147c478bd9Sstevel@tonic-gate switch (cmd) { 2157c478bd9Sstevel@tonic-gate case DDI_SUSPEND: 2167c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2177c478bd9Sstevel@tonic-gate default: 2187c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2237c478bd9Sstevel@tonic-gate static int 2247c478bd9Sstevel@tonic-gate pmugpio_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 2257c478bd9Sstevel@tonic-gate void *arg, void **result) 2267c478bd9Sstevel@tonic-gate { 2277c478bd9Sstevel@tonic-gate dev_t dev; 2287c478bd9Sstevel@tonic-gate int instance, error; 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate switch (infocmd) { 2317c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO: 2327c478bd9Sstevel@tonic-gate *result = (void *)pmugpio_dip; 2337c478bd9Sstevel@tonic-gate error = DDI_SUCCESS; 2347c478bd9Sstevel@tonic-gate break; 2357c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE: 2367c478bd9Sstevel@tonic-gate dev = (dev_t)arg; 2377c478bd9Sstevel@tonic-gate instance = getminor(dev); 2387c478bd9Sstevel@tonic-gate *result = (void *)(uintptr_t)instance; 2397c478bd9Sstevel@tonic-gate error = DDI_SUCCESS; 2407c478bd9Sstevel@tonic-gate break; 2417c478bd9Sstevel@tonic-gate default: 2427c478bd9Sstevel@tonic-gate error = DDI_FAILURE; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate return (error); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate void 2487c478bd9Sstevel@tonic-gate pmugpio_watchdog_pat(void) 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate dev_info_t *dip = pmugpio_dip; 2517c478bd9Sstevel@tonic-gate int instance; 2527c478bd9Sstevel@tonic-gate pmugpio_state_t *pmugpio_ptr; 2537c478bd9Sstevel@tonic-gate hrtime_t now; 2547c478bd9Sstevel@tonic-gate uint8_t value; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (dip == NULL) { 2577c478bd9Sstevel@tonic-gate return; 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate instance = ddi_get_instance(dip); 2607c478bd9Sstevel@tonic-gate pmugpio_ptr = ddi_get_soft_state(pmugpio_statep, instance); 2617c478bd9Sstevel@tonic-gate if (pmugpio_ptr == NULL) { 2627c478bd9Sstevel@tonic-gate return; 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * The RMC can read interrupts either high to low OR low to high. As 2667c478bd9Sstevel@tonic-gate * a result all that needs to happen is that when we hit the time to 2677c478bd9Sstevel@tonic-gate * send an signal we simply need to change the state. 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate now = gethrtime(); 2707c478bd9Sstevel@tonic-gate if ((now - pmugpio_ptr->hw_last_pat) >= PMUGPIO_TWO_SEC) { 2717c478bd9Sstevel@tonic-gate /* 2727c478bd9Sstevel@tonic-gate * fetch current reg value and invert it 2737c478bd9Sstevel@tonic-gate */ 274*d58fda43Sjbeloro switch (pmugpio_ptr->access_type) { 275*d58fda43Sjbeloro case PMUGPIO_CPLD: 276*d58fda43Sjbeloro value = (CPLD_WATCHDOG ^ 277*d58fda43Sjbeloro ddi_get8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 278*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg)); 279*d58fda43Sjbeloro 280*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 281*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg, value); 282*d58fda43Sjbeloro break; 283*d58fda43Sjbeloro 284*d58fda43Sjbeloro case PMUGPIO_MBC: 285*d58fda43Sjbeloro value = (uint8_t)(MBC_WATCHDOG ^ 286*d58fda43Sjbeloro ddi_get8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 287*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg)); 288*d58fda43Sjbeloro 289*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 290*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg, value); 291*d58fda43Sjbeloro break; 292*d58fda43Sjbeloro 293*d58fda43Sjbeloro case PMUGPIO_OTHER: 2947c478bd9Sstevel@tonic-gate value = (uint8_t)(0xff ^ 2957c478bd9Sstevel@tonic-gate ddi_get8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 2967c478bd9Sstevel@tonic-gate pmugpio_ptr->pmugpio_watchdog_reg)); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate ddi_put8(pmugpio_ptr->pmugpio_watchdog_reg_handle, 2997c478bd9Sstevel@tonic-gate pmugpio_ptr->pmugpio_watchdog_reg, value); 300*d58fda43Sjbeloro break; 301*d58fda43Sjbeloro 302*d58fda43Sjbeloro default: 303*d58fda43Sjbeloro cmn_err(CE_WARN, "pmugpio_watchdog_pat: Invalid type"); 304*d58fda43Sjbeloro } 3057c478bd9Sstevel@tonic-gate pmugpio_ptr->hw_last_pat = now; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate void 3107c478bd9Sstevel@tonic-gate pmugpio_reset(void) 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate dev_info_t *dip = pmugpio_dip; 3137c478bd9Sstevel@tonic-gate int instance; 3147c478bd9Sstevel@tonic-gate pmugpio_state_t *pmugpio_ptr; 315*d58fda43Sjbeloro uint8_t value; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (dip == NULL) { 3187c478bd9Sstevel@tonic-gate return; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate instance = ddi_get_instance(dip); 3217c478bd9Sstevel@tonic-gate pmugpio_ptr = ddi_get_soft_state(pmugpio_statep, instance); 3227c478bd9Sstevel@tonic-gate if (pmugpio_ptr == NULL) { 3237c478bd9Sstevel@tonic-gate return; 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate /* 327*d58fda43Sjbeloro * For Chalupa, turn all bits on then off again - pmubus nexus 328*d58fda43Sjbeloro * will ensure that only unmasked bit is affected. 329*d58fda43Sjbeloro * For CPLD and MBC, turn just reset bit on, then off. 3307c478bd9Sstevel@tonic-gate */ 331*d58fda43Sjbeloro switch (pmugpio_ptr->access_type) { 332*d58fda43Sjbeloro case PMUGPIO_CPLD: 333*d58fda43Sjbeloro value = ddi_get8(pmugpio_ptr->pmugpio_reset_reg_handle, 334*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg); 335*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 336*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg, (value | CPLD_RESET_SC)); 337*d58fda43Sjbeloro 338*d58fda43Sjbeloro drv_usecwait(CPLD_RESET_DELAY); 339*d58fda43Sjbeloro 340*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 341*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg, (value & ~CPLD_RESET_SC)); 342*d58fda43Sjbeloro break; 343*d58fda43Sjbeloro 344*d58fda43Sjbeloro case PMUGPIO_MBC: 345*d58fda43Sjbeloro value = ddi_get8(pmugpio_ptr->pmugpio_reset_reg_handle, 346*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg); 347*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 348*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg, 349*d58fda43Sjbeloro (value | MBC_PPC_RESET)); 350*d58fda43Sjbeloro ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 351*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg, 352*d58fda43Sjbeloro (value & ~MBC_PPC_RESET)); 353*d58fda43Sjbeloro break; 354*d58fda43Sjbeloro 355*d58fda43Sjbeloro case PMUGPIO_OTHER: 3567c478bd9Sstevel@tonic-gate ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 3577c478bd9Sstevel@tonic-gate pmugpio_ptr->pmugpio_reset_reg, ~0); 3587c478bd9Sstevel@tonic-gate ddi_put8(pmugpio_ptr->pmugpio_reset_reg_handle, 3597c478bd9Sstevel@tonic-gate pmugpio_ptr->pmugpio_reset_reg, 0); 360*d58fda43Sjbeloro break; 361*d58fda43Sjbeloro 362*d58fda43Sjbeloro default: 363*d58fda43Sjbeloro cmn_err(CE_WARN, "pmugpio_reset: Invalid type"); 364*d58fda43Sjbeloro } 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate static int 3687c478bd9Sstevel@tonic-gate pmugpio_map_regs(dev_info_t *dip, pmugpio_state_t *pmugpio_ptr) 3697c478bd9Sstevel@tonic-gate { 3707c478bd9Sstevel@tonic-gate ddi_device_acc_attr_t attr; 371*d58fda43Sjbeloro char *binding_name; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate /* The host controller will be little endian */ 3747c478bd9Sstevel@tonic-gate attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 3757c478bd9Sstevel@tonic-gate attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 3767c478bd9Sstevel@tonic-gate attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 3777c478bd9Sstevel@tonic-gate 378*d58fda43Sjbeloro binding_name = ddi_binding_name(dip); 379*d58fda43Sjbeloro 380*d58fda43Sjbeloro /* 381*d58fda43Sjbeloro * Determine access type. 382*d58fda43Sjbeloro */ 383*d58fda43Sjbeloro if (strcmp(binding_name, "mbcgpio") == 0) 384*d58fda43Sjbeloro pmugpio_ptr->access_type = PMUGPIO_MBC; 385*d58fda43Sjbeloro else if (strcmp(binding_name, "cpldgpio") == 0) 386*d58fda43Sjbeloro pmugpio_ptr->access_type = PMUGPIO_CPLD; 387*d58fda43Sjbeloro else 388*d58fda43Sjbeloro pmugpio_ptr->access_type = PMUGPIO_OTHER; 389*d58fda43Sjbeloro 390*d58fda43Sjbeloro switch (pmugpio_ptr->access_type) { 391*d58fda43Sjbeloro case PMUGPIO_CPLD: 392*d58fda43Sjbeloro case PMUGPIO_MBC: 393*d58fda43Sjbeloro if (ddi_regs_map_setup(dip, 0, 394*d58fda43Sjbeloro (caddr_t *)&pmugpio_ptr->pmugpio_reset_reg, 0, 1, &attr, 395*d58fda43Sjbeloro &pmugpio_ptr->pmugpio_reset_reg_handle) != DDI_SUCCESS) 396*d58fda43Sjbeloro return (DDI_FAILURE); 397*d58fda43Sjbeloro /* MBC and CPLD have reset and watchdog bits in same reg. */ 398*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg_handle = 399*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg_handle; 400*d58fda43Sjbeloro pmugpio_ptr->pmugpio_watchdog_reg = 401*d58fda43Sjbeloro pmugpio_ptr->pmugpio_reset_reg; 402*d58fda43Sjbeloro break; 403*d58fda43Sjbeloro 404*d58fda43Sjbeloro case PMUGPIO_OTHER: 4057c478bd9Sstevel@tonic-gate if (ddi_regs_map_setup(dip, 1, 4067c478bd9Sstevel@tonic-gate (caddr_t *)&pmugpio_ptr->pmugpio_watchdog_reg, 0, 1, &attr, 4077c478bd9Sstevel@tonic-gate &pmugpio_ptr->pmugpio_watchdog_reg_handle) != DDI_SUCCESS) { 4087c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate if (ddi_regs_map_setup(dip, 0, 4117c478bd9Sstevel@tonic-gate (caddr_t *)&pmugpio_ptr->pmugpio_reset_reg, 0, 1, &attr, 4127c478bd9Sstevel@tonic-gate &pmugpio_ptr->pmugpio_reset_reg_handle) != DDI_SUCCESS) { 413*d58fda43Sjbeloro ddi_regs_map_free( 414*d58fda43Sjbeloro &pmugpio_ptr->pmugpio_watchdog_reg_handle); 4157c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 4167c478bd9Sstevel@tonic-gate } 417*d58fda43Sjbeloro break; 418*d58fda43Sjbeloro 419*d58fda43Sjbeloro default: 420*d58fda43Sjbeloro cmn_err(CE_WARN, "pmugpio_map_regs: Invalid type"); 421*d58fda43Sjbeloro return (DDI_FAILURE); 422*d58fda43Sjbeloro } 423*d58fda43Sjbeloro 4247c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 4257c478bd9Sstevel@tonic-gate } 426