1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Zynq power management
- *
- * Copyright (C) 2012 - 2014 Xilinx
- *
- * Sören Brinkmann <[email protected]>
- */
- #include <linux/io.h>
- #include <linux/of_address.h>
- #include <linux/of_device.h>
- #include "common.h"
- /* register offsets */
- #define DDRC_CTRL_REG1_OFFS 0x60
- #define DDRC_DRAM_PARAM_REG3_OFFS 0x20
- /* bitfields */
- #define DDRC_CLOCKSTOP_MASK BIT(23)
- #define DDRC_SELFREFRESH_MASK BIT(12)
- static void __iomem *ddrc_base;
- /**
- * zynq_pm_ioremap() - Create IO mappings
- * @comp: DT compatible string
- * Return: Pointer to the mapped memory or NULL.
- *
- * Remap the memory region for a compatible DT node.
- */
- static void __iomem *zynq_pm_ioremap(const char *comp)
- {
- struct device_node *np;
- void __iomem *base = NULL;
- np = of_find_compatible_node(NULL, NULL, comp);
- if (np) {
- base = of_iomap(np, 0);
- of_node_put(np);
- } else {
- pr_warn("%s: no compatible node found for '%s'\n", __func__,
- comp);
- }
- return base;
- }
- /**
- * zynq_pm_late_init() - Power management init
- *
- * Initialization of power management related features and infrastructure.
- */
- void __init zynq_pm_late_init(void)
- {
- u32 reg;
- ddrc_base = zynq_pm_ioremap("xlnx,zynq-ddrc-a05");
- if (!ddrc_base) {
- pr_warn("%s: Unable to map DDRC IO memory.\n", __func__);
- } else {
- /*
- * Enable DDRC clock stop feature. The HW takes care of
- * entering/exiting the correct mode depending
- * on activity state.
- */
- reg = readl(ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
- reg |= DDRC_CLOCKSTOP_MASK;
- writel(reg, ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
- }
- }
|