linux/drivers/soc/brcmstb/biuctrl.c
<<
>>
Prefs
   1/*
   2 * Broadcom STB SoCs Bus Unit Interface controls
   3 *
   4 * Copyright (C) 2015, Broadcom Corporation
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#define pr_fmt(fmt)     "brcmstb: " KBUILD_MODNAME ": " fmt
  17
  18#include <linux/kernel.h>
  19#include <linux/io.h>
  20#include <linux/of_address.h>
  21#include <linux/syscore_ops.h>
  22
  23#define CPU_CREDIT_REG_OFFSET                   0x184
  24#define  CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
  25
  26static void __iomem *cpubiuctrl_base;
  27static bool mcp_wr_pairing_en;
  28
  29static int __init mcp_write_pairing_set(void)
  30{
  31        u32 creds = 0;
  32
  33        if (!cpubiuctrl_base)
  34                return -1;
  35
  36        creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  37        if (mcp_wr_pairing_en) {
  38                pr_info("MCP: Enabling write pairing\n");
  39                writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  40                             cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  41        } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
  42                pr_info("MCP: Disabling write pairing\n");
  43                writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
  44                                cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  45        } else {
  46                pr_info("MCP: Write pairing already disabled\n");
  47        }
  48
  49        return 0;
  50}
  51
  52static int __init setup_hifcpubiuctrl_regs(void)
  53{
  54        struct device_node *np;
  55        int ret = 0;
  56
  57        np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
  58        if (!np) {
  59                pr_err("missing BIU control node\n");
  60                return -ENODEV;
  61        }
  62
  63        cpubiuctrl_base = of_iomap(np, 0);
  64        if (!cpubiuctrl_base) {
  65                pr_err("failed to remap BIU control base\n");
  66                ret = -ENOMEM;
  67                goto out;
  68        }
  69
  70        mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
  71out:
  72        of_node_put(np);
  73        return ret;
  74}
  75
  76#ifdef CONFIG_PM_SLEEP
  77static u32 cpu_credit_reg_dump;  /* for save/restore */
  78
  79static int brcmstb_cpu_credit_reg_suspend(void)
  80{
  81        if (cpubiuctrl_base)
  82                cpu_credit_reg_dump =
  83                        readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  84        return 0;
  85}
  86
  87static void brcmstb_cpu_credit_reg_resume(void)
  88{
  89        if (cpubiuctrl_base)
  90                writel_relaxed(cpu_credit_reg_dump,
  91                                cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
  92}
  93
  94static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
  95        .suspend = brcmstb_cpu_credit_reg_suspend,
  96        .resume = brcmstb_cpu_credit_reg_resume,
  97};
  98#endif
  99
 100
 101void __init brcmstb_biuctrl_init(void)
 102{
 103        int ret;
 104
 105        setup_hifcpubiuctrl_regs();
 106
 107        ret = mcp_write_pairing_set();
 108        if (ret) {
 109                pr_err("MCP: Unable to disable write pairing!\n");
 110                return;
 111        }
 112
 113#ifdef CONFIG_PM_SLEEP
 114        register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
 115#endif
 116}
 117