/* * Copyright (C) 2012 Altera Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #define SYSMGR_FRZCTRL_LOOP_PARAM (1000) #define SYSMGR_FRZCTRL_DELAY_LOOP_PARAM (10) /* * sys_mgr_frzctrl_freeze_req * Freeze HPS IOs */ int sys_mgr_frzctrl_freeze_req(enum frz_channel_id channel_id) { uint32_t reg, val; void *sm = (void *)CYCLONE5_SYSMGR_ADDRESS; /* select software FSM */ writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, (sm + SYSMGR_FRZCTRL_SRC_ADDRESS)); /* Freeze channel ID checking and base address */ switch (channel_id) { case FREEZE_CHANNEL_0: case FREEZE_CHANNEL_1: case FREEZE_CHANNEL_2: reg = SYSMGR_FRZCTRL_VIOCTRL_ADDRESS + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT); /* * Assert active low enrnsl, plniotri * and niotri signals */ val = readl(sm + reg); val &= ~(SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK); writel(val, sm + reg); /* * Note: Delay for 20ns at min * Assert active low bhniotri signal and de-assert * active high csrdone */ val = readl(sm + reg); val &= ~(SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK); writel(val, sm + reg); break; case FREEZE_CHANNEL_3: /* * Assert active low enrnsl, plniotri and * niotri signals */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val &= ~(SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK); writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Note: Delay for 40ns at min * assert active low bhniotri & nfrzdrv signals, * de-assert active high csrdone and assert * active high frzreg and nfrzdrv signals */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val &= ~(SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK); val |= SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Note: Delay for 40ns at min * assert active high reinit signal and de-assert * active high pllbiasen signals */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val &= ~(SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK); val |= SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); break; default: return -EINVAL; } return 0; } /* * sys_mgr_frzctrl_thaw_req * Unfreeze/Thaw HPS IOs */ int sys_mgr_frzctrl_thaw_req(enum frz_channel_id channel_id) { uint32_t reg, val; void *sm = (void *)CYCLONE5_SYSMGR_ADDRESS; /* select software FSM */ writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, sm + SYSMGR_FRZCTRL_SRC_ADDRESS); /* Freeze channel ID checking and base address */ switch (channel_id) { case FREEZE_CHANNEL_0: case FREEZE_CHANNEL_1: case FREEZE_CHANNEL_2: reg = SYSMGR_FRZCTRL_VIOCTRL_ADDRESS + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT); /* * Assert active low bhniotri signal and * de-assert active high csrdone */ val = readl(sm + reg); val |= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; writel(val, sm + reg); /* * Note: Delay for 20ns at min * de-assert active low plniotri and niotri signals */ val = readl(sm + reg); val |= SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; writel(val, sm + reg); /* * Note: Delay for 20ns at min * de-assert active low enrnsl signal */ val = readl(sm + reg); val |= SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK; writel(val, sm + reg); break; case FREEZE_CHANNEL_3: /* de-assert active high reinit signal */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val &= ~SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Note: Delay for 40ns at min * assert active high pllbiasen signals */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val |= SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Delay 1000 intosc. intosc is based on eosc1 * At 25MHz this would be 40us. Play safe, we have time... */ __udelay(1000); /* * de-assert active low bhniotri signals, * assert active high csrdone and nfrzdrv signal */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val |= SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; val &= ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* Delay 33 intosc */ __udelay(100); /* de-assert active low plniotri and niotri signals */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val |= SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Note: Delay for 40ns at min * de-assert active high frzreg signal */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val &= ~SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); /* * Note: Delay for 40ns at min * de-assert active low enrnsl signal */ val = readl(sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); val |= SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK; writel(val, sm + SYSMGR_FRZCTRL_HIOCTRL_ADDRESS); break; default: return -EINVAL; } return 0; }