static int stm_xfer_start(void) { struct stm_dev *stm = _dev_stm; struct stm_ctrl *stm_ctrl; u32 reg_word; if (!stm) return -ENODEV; /* REVERTME : filter PUNIT and SCU MasterID when switching to USB */ if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_ANNIEDALE) { pr_info("%s\n REVERTME : filter PUNIT and SCU MasterID\n", __func__); reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_MASMSK1); reg_word |= 0x28; stm_writel(stm->stm_ioaddr, (u32)STM_MASMSK1, reg_word); pr_info("%s\n REVERTME : USBTO\n", __func__); reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_USBTO); reg_word |= 0x01; stm_writel(stm->stm_ioaddr, (u32)STM_USBTO, reg_word); } stm_ctrl = &stm->stm_ctrl_hwreg; stm_ctrl->reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_CTRL); stm_ctrl->usb_debug_en = true; stm_ctrl->pti_out_en = false; stm_writel(stm->stm_ioaddr, (u32)STM_CTRL, stm_ctrl->reg_word); pr_info("%s\n switch STM output to DvC.Trace ", __func__); return 0; }
static int stm_hwevent_isenable(struct stm_drvdata *drvdata) { int ret = 0; spin_lock(&drvdata->spinlock); if (drvdata->enable) if (BVAL(stm_readl(drvdata, STMHEMCR), 0)) ret = stm_readl(drvdata, STMHEER) == 0 ? 0 : 1; spin_unlock(&drvdata->spinlock); return ret; }
static void __stm_enable(struct stm_drvdata *drvdata) { __stm_hwevent_enable(drvdata); __stm_port_enable(drvdata); STM_UNLOCK(drvdata); stm_writel(drvdata, 0xFFF, STMSYNCR); /* SYNCEN is read-only and HWTEN is not implemented */ stm_writel(drvdata, 0x100003,STMTCSR); #ifdef STM_DEBUG dev_dbg("STMSYNCR = 0x%02x\n", stm_readl(drvdata, STMSYNCR)); dev_dbg("STMTCSR = 0x%02x\n", stm_readl(drvdata, STMTCSR)); #endif STM_LOCK(drvdata); }
static void __stm_port_enable(struct stm_drvdata *drvdata) { STM_UNLOCK(drvdata); stm_writel(drvdata, 0x10, STMSPTRIGCSR); stm_writel(drvdata, 0xFFFFFFFF, STMSPER); stm_writel(drvdata,0x0FFF8000,STMSPSCR); stm_writel(drvdata,0xFFFFC000,STMSPMSCR); #ifdef STM_DEBUG dev_dbg("STMSPTRIGCSR = 0x%02x\n", stm_readl(drvdata, STMSPTRIGCSR)); dev_dbg("STMSPER = 0x%02x\n", stm_readl(drvdata, STMSPER)); dev_dbg("STMSPSCR = 0x%02x\n", stm_readl(drvdata, STMSPSCR)); dev_dbg("STMSPMSCR = 0x%02x\n", stm_readl(drvdata, STMSPMSCR)); #endif STM_LOCK(drvdata); }
static void __stm_hwevent_enable(struct stm_drvdata *drvdata) { STM_UNLOCK(drvdata); /* Program STMHETER to ensure TRIGOUTHETE (fed to CTI) is asserted for HW events. */ stm_writel(drvdata, 0xFFFFFFFF, STMHETER); stm_writel(drvdata, 0xFFFFFFFF, STMHEER); stm_writel(drvdata, 0x5, STMHEMCR); #ifdef STM_DEBUG dev_dbg("STMHETER = 0x%02x\n", stm_readl(drvdata, STMHETER)); dev_dbg("STMHEER = 0x%02x\n", stm_readl(drvdata, STMHEER)); dev_dbg("STMHEMCR = 0x%02x\n", stm_readl(drvdata, STMHEMCR)); #endif STM_LOCK(drvdata); }
static int stm_port_isenable(struct stm_drvdata *drvdata) { int ret = 0; spin_lock(&drvdata->spinlock); if (drvdata->enable) ret = stm_readl(drvdata, STMSPER) == 0 ? 0 : 1; spin_unlock(&drvdata->spinlock); return ret; }
/** * stm_init() - initialize stmsub3dbgthr register * * @return - 0 on Success */ static int stm_init(void) { struct stm_dev *stm = _dev_stm; struct stm_usb3_ctrl *usb3dbg; if (!stm) return -ENODEV; usb3dbg = &stm->stm_usb3_hwreg; usb3dbg->reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_USB3DBGGTHR); usb3dbg->reg_word = 0xFF; stm_writel(stm->stm_ioaddr, (u32)STM_USB3DBGGTHR, usb3dbg->reg_word); return 0; }
/** * stm_kernel_set_out()- * Kernel API function used to * set STM output configuration to PTI or USB. * * @bus_type: * 0 = PTI 4-bits legacy end user * 1 = PTI 4-bits NiDnT * 2 = PTI 16-bits * 3 = PTI 12-bits * 4 = PTI 8-bits * 15 = USB Debug-Class (DvC.Trace) * */ int stm_kernel_set_out(int bus_type) { struct stm_dev *drv_stm = _dev_stm; /* * since this function is exported, this is treated like an * API function, thus, all parameters should * be checked for validity. */ if (drv_stm == NULL) return 0; mutex_lock(&stmlock); drv_stm->stm_ctrl_hwreg.reg_word = stm_readl(drv_stm->stm_ioaddr, (u32)STM_CTRL); switch (bus_type) { case STM_PTI_4BIT_LEGACY: case STM_PTI_4BIT_NIDNT: case STM_PTI_16BIT: case STM_PTI_12BIT: case STM_PTI_8BIT: drv_stm->stm_ctrl_hwreg.pti_out_en = true; drv_stm->stm_ctrl_hwreg.usb_debug_en = false; drv_stm->stm_ctrl_hwreg.pti_out_mode_sel = bus_type; stm_writel(drv_stm->stm_ioaddr, (u32)STM_CTRL, drv_stm->stm_ctrl_hwreg.reg_word); break; case STM_USB: drv_stm->stm_ctrl_hwreg.pti_out_en = false; drv_stm->stm_ctrl_hwreg.usb_debug_en = true; stm_writel(drv_stm->stm_ioaddr, (u32)STM_CTRL, drv_stm->stm_ctrl_hwreg.reg_word); break; default: /* N/A */ break; } mutex_unlock(&stmlock); return 1; }
static int stm_xfer_stop(void) { struct stm_dev *stm = _dev_stm; struct stm_ctrl *stm_ctrl; if (!stm) return -ENODEV; stm_ctrl = &stm->stm_ctrl_hwreg; stm_ctrl->reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_CTRL); stm_ctrl->usb_debug_en = false; stm_ctrl->pti_out_en = true; stm_writel(stm->stm_ioaddr, (u32)STM_CTRL, stm_ctrl->reg_word); pr_info("%s\n switch STM to 4bits MIPI PTI (default)", __func__); return 0; }
/** * stm_kernel_get_out()- * Kernel API function used to get * STM output cofiguration PTI or USB. * */ int stm_kernel_get_out(void) { struct stm_dev *drv_stm = _dev_stm; int ret = -EOPNOTSUPP; if (drv_stm == NULL) return -EOPNOTSUPP; mutex_lock(&stmlock); drv_stm->stm_ctrl_hwreg.reg_word = stm_readl(drv_stm->stm_ioaddr, (u32)STM_CTRL); if (!drv_stm->stm_ctrl_hwreg.usb_debug_en) { if (drv_stm->stm_ctrl_hwreg.pti_out_en) ret = (int)drv_stm->stm_ctrl_hwreg.pti_out_mode_sel; } else { ret = (int)STM_USB; } mutex_unlock(&stmlock); return ret; }
/** * stm_dev_init()- Used to setup STM resources on the pci bus. * * @pdev- pci_dev struct values for pti device. * @stm- stm_dev struct managing stm resources * * Returns: * 0 for success * otherwise, error */ int stm_dev_init(struct pci_dev *pdev, struct stm_dev *stm) { int retval = 0; int pci_bar = 0; if (!cpu_has_debug_feature(DEBUG_FEATURE_PTI)) return -ENODEV; dev_dbg(&pdev->dev, "%s %s(%d): STM PCI ID %04x:%04x\n", __FILE__, __func__, __LINE__, pdev->vendor, pdev->device); stm->stm_addr = pci_resource_start(pdev, pci_bar); retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); if (retval != 0) { dev_err(&pdev->dev, "%s(%d): pci_request_region() returned error %d\n", __func__, __LINE__, retval); return retval; } pr_info("stm add %x\n", stm->stm_addr); stm->stm_reg_base = stm->stm_addr+STM_REG_BASE; stm->stm_ioaddr = ioremap_nocache((u32)stm->stm_reg_base, STM_REG_LEN); if (!stm->stm_ioaddr) { retval = -ENOMEM; goto out_release_region; } stm->stm_trb_base = stm->stm_addr+STM_TRB_BASE; stm->trb_ioaddr = ioremap_nocache((u32)stm->stm_trb_base, STM_TRB_LEN); if (!stm->trb_ioaddr) { retval = -ENOMEM; goto out_iounmap_stm_ioaddr; } stm->stm_ctrl_hwreg.reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_CTRL); stm->stm_usb3_hwreg.reg_word = stm_readl(stm->stm_ioaddr, (u32)STM_USB3DBGGTHR); _dev_stm = stm; dwc3_register_io_ebc(&stm_ebc_io_ops); dwc3_register_io_ebc(&exi_in_ebc_io_ops); dwc3_register_io_ebc(&exi_out_ebc_io_ops); pr_info("successfully registered ebc io ops\n"); return retval; out_iounmap_stm_ioaddr: pci_iounmap(pdev, stm->stm_ioaddr); out_release_region: pci_release_region(pdev, pci_bar); _dev_stm = NULL; return retval; }