blob: 21631dba46578ac31ba9b83af78fa790422ce5cd [file] [log] [blame]
#include <asm/errno.h>
#include <asm/io.h>
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/syscore_ops.h>
#include <mach/p7.h>
#include "mpmc.h"
int p7_mpmc_set_prio(enum p7_mpmc_port port, unsigned prio)
{
int off = port * 4;
u32 r;
if (prio > 7)
return -ERANGE;
r = __raw_readl(__MMIO_P2V(P7_MPMC_GBC_PRI));
r &= ~(7UL << off);
r |= prio << off;
__raw_writel(r, __MMIO_P2V(P7_MPMC_GBC_PRI));
return 0;
}
unsigned p7_mpmc_get_prio(enum p7_mpmc_port port)
{
int off = port * 4;
u32 r;
r = __raw_readl(__MMIO_P2V(P7_MPMC_GBC_PRI));
r >>= off;
r &= 7UL;
return r;
}
#ifdef CONFIG_PM
static unsigned p7_mpmc_config[P7_MPMC_NR_PORT];
/* Save PRIO values on suspend */
static int p7_mpmc_suspend(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(p7_mpmc_config); i++)
p7_mpmc_config[i] = p7_mpmc_get_prio(i);
return 0;
}
/* Restore PRIO values on resume */
static void p7_mpmc_resume(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(p7_mpmc_config); i++)
p7_mpmc_set_prio(i, p7_mpmc_config[i]);
}
struct syscore_ops p7_mpmc_syscore_ops = {
.suspend = p7_mpmc_suspend,
.resume = p7_mpmc_resume,
};
#endif /* CONFIG_PM */
void __init p7_init_mpmc(void)
{
/* Default MPMC configuration. We set all ports to priority 1 to disable
* QoS. */
p7_mpmc_set_prio(P7_MPMC_CPU_DMA_PORT, 1);
p7_mpmc_set_prio(P7_MPMC_AVI_PORT, 1);
p7_mpmc_set_prio(P7_MPMC_VDEC_VENC_PORT, 1);
p7_mpmc_set_prio(P7_MPMC_HSP_AAI_PORT, 1);
p7_mpmc_set_prio(P7_MPMC_GPU_VENC_PORT, 1);
#ifdef CONFIG_PM_SLEEP
register_syscore_ops(&p7_mpmc_syscore_ops);
#endif
}