Linux Audio

Check our new training course

Loading...
v4.6
 
  1/*
  2 * arch/sh/kernel/cpu/sh4a/ubc.c
  3 *
  4 * On-chip UBC support for SH-4A CPUs.
  5 *
  6 * Copyright (C) 2009 - 2010  Paul Mundt
  7 *
  8 * This file is subject to the terms and conditions of the GNU General Public
  9 * License.  See the file "COPYING" in the main directory of this archive
 10 * for more details.
 11 */
 12#include <linux/init.h>
 13#include <linux/err.h>
 14#include <linux/clk.h>
 15#include <linux/io.h>
 16#include <asm/hw_breakpoint.h>
 17
 18#define UBC_CBR(idx)	(0xff200000 + (0x20 * idx))
 19#define UBC_CRR(idx)	(0xff200004 + (0x20 * idx))
 20#define UBC_CAR(idx)	(0xff200008 + (0x20 * idx))
 21#define UBC_CAMR(idx)	(0xff20000c + (0x20 * idx))
 22
 23#define UBC_CCMFR	0xff200600
 24#define UBC_CBCR	0xff200620
 25
 26/* CRR */
 27#define UBC_CRR_PCB	(1 << 1)
 28#define UBC_CRR_BIE	(1 << 0)
 29
 30/* CBR */
 31#define UBC_CBR_CE	(1 << 0)
 32
 33static struct sh_ubc sh4a_ubc;
 34
 35static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
 36{
 37	__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
 38	__raw_writel(info->address, UBC_CAR(idx));
 39}
 40
 41static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
 42{
 43	__raw_writel(0, UBC_CBR(idx));
 44	__raw_writel(0, UBC_CAR(idx));
 45}
 46
 47static void sh4a_ubc_enable_all(unsigned long mask)
 48{
 49	int i;
 50
 51	for (i = 0; i < sh4a_ubc.num_events; i++)
 52		if (mask & (1 << i))
 53			__raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
 54				     UBC_CBR(i));
 55}
 56
 57static void sh4a_ubc_disable_all(void)
 58{
 59	int i;
 60
 61	for (i = 0; i < sh4a_ubc.num_events; i++)
 62		__raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
 63			     UBC_CBR(i));
 64}
 65
 66static unsigned long sh4a_ubc_active_mask(void)
 67{
 68	unsigned long active = 0;
 69	int i;
 70
 71	for (i = 0; i < sh4a_ubc.num_events; i++)
 72		if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
 73			active |= (1 << i);
 74
 75	return active;
 76}
 77
 78static unsigned long sh4a_ubc_triggered_mask(void)
 79{
 80	return __raw_readl(UBC_CCMFR);
 81}
 82
 83static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
 84{
 85	__raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
 86}
 87
 88static struct sh_ubc sh4a_ubc = {
 89	.name			= "SH-4A",
 90	.num_events		= 2,
 91	.trap_nr		= 0x1e0,
 92	.enable			= sh4a_ubc_enable,
 93	.disable		= sh4a_ubc_disable,
 94	.enable_all		= sh4a_ubc_enable_all,
 95	.disable_all		= sh4a_ubc_disable_all,
 96	.active_mask		= sh4a_ubc_active_mask,
 97	.triggered_mask		= sh4a_ubc_triggered_mask,
 98	.clear_triggered_mask	= sh4a_ubc_clear_triggered_mask,
 99};
100
101static int __init sh4a_ubc_init(void)
102{
103	struct clk *ubc_iclk = clk_get(NULL, "ubc0");
104	int i;
105
106	/*
107	 * The UBC MSTP bit is optional, as not all platforms will have
108	 * it. Just ignore it if we can't find it.
109	 */
110	if (IS_ERR(ubc_iclk))
111		ubc_iclk = NULL;
112
113	clk_enable(ubc_iclk);
114
115	__raw_writel(0, UBC_CBCR);
116
117	for (i = 0; i < sh4a_ubc.num_events; i++) {
118		__raw_writel(0, UBC_CAMR(i));
119		__raw_writel(0, UBC_CBR(i));
120
121		__raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
122
123		/* dummy read for write posting */
124		(void)__raw_readl(UBC_CRR(i));
125	}
126
127	clk_disable(ubc_iclk);
128
129	sh4a_ubc.clk = ubc_iclk;
130
131	return register_sh_ubc(&sh4a_ubc);
132}
133arch_initcall(sh4a_ubc_init);
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * arch/sh/kernel/cpu/sh4a/ubc.c
  4 *
  5 * On-chip UBC support for SH-4A CPUs.
  6 *
  7 * Copyright (C) 2009 - 2010  Paul Mundt
 
 
 
 
  8 */
  9#include <linux/init.h>
 10#include <linux/err.h>
 11#include <linux/clk.h>
 12#include <linux/io.h>
 13#include <asm/hw_breakpoint.h>
 14
 15#define UBC_CBR(idx)	(0xff200000 + (0x20 * idx))
 16#define UBC_CRR(idx)	(0xff200004 + (0x20 * idx))
 17#define UBC_CAR(idx)	(0xff200008 + (0x20 * idx))
 18#define UBC_CAMR(idx)	(0xff20000c + (0x20 * idx))
 19
 20#define UBC_CCMFR	0xff200600
 21#define UBC_CBCR	0xff200620
 22
 23/* CRR */
 24#define UBC_CRR_PCB	(1 << 1)
 25#define UBC_CRR_BIE	(1 << 0)
 26
 27/* CBR */
 28#define UBC_CBR_CE	(1 << 0)
 29
 30static struct sh_ubc sh4a_ubc;
 31
 32static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
 33{
 34	__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
 35	__raw_writel(info->address, UBC_CAR(idx));
 36}
 37
 38static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
 39{
 40	__raw_writel(0, UBC_CBR(idx));
 41	__raw_writel(0, UBC_CAR(idx));
 42}
 43
 44static void sh4a_ubc_enable_all(unsigned long mask)
 45{
 46	int i;
 47
 48	for (i = 0; i < sh4a_ubc.num_events; i++)
 49		if (mask & (1 << i))
 50			__raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
 51				     UBC_CBR(i));
 52}
 53
 54static void sh4a_ubc_disable_all(void)
 55{
 56	int i;
 57
 58	for (i = 0; i < sh4a_ubc.num_events; i++)
 59		__raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
 60			     UBC_CBR(i));
 61}
 62
 63static unsigned long sh4a_ubc_active_mask(void)
 64{
 65	unsigned long active = 0;
 66	int i;
 67
 68	for (i = 0; i < sh4a_ubc.num_events; i++)
 69		if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
 70			active |= (1 << i);
 71
 72	return active;
 73}
 74
 75static unsigned long sh4a_ubc_triggered_mask(void)
 76{
 77	return __raw_readl(UBC_CCMFR);
 78}
 79
 80static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
 81{
 82	__raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
 83}
 84
 85static struct sh_ubc sh4a_ubc = {
 86	.name			= "SH-4A",
 87	.num_events		= 2,
 88	.trap_nr		= 0x1e0,
 89	.enable			= sh4a_ubc_enable,
 90	.disable		= sh4a_ubc_disable,
 91	.enable_all		= sh4a_ubc_enable_all,
 92	.disable_all		= sh4a_ubc_disable_all,
 93	.active_mask		= sh4a_ubc_active_mask,
 94	.triggered_mask		= sh4a_ubc_triggered_mask,
 95	.clear_triggered_mask	= sh4a_ubc_clear_triggered_mask,
 96};
 97
 98static int __init sh4a_ubc_init(void)
 99{
100	struct clk *ubc_iclk = clk_get(NULL, "ubc0");
101	int i;
102
103	/*
104	 * The UBC MSTP bit is optional, as not all platforms will have
105	 * it. Just ignore it if we can't find it.
106	 */
107	if (IS_ERR(ubc_iclk))
108		ubc_iclk = NULL;
109
110	clk_enable(ubc_iclk);
111
112	__raw_writel(0, UBC_CBCR);
113
114	for (i = 0; i < sh4a_ubc.num_events; i++) {
115		__raw_writel(0, UBC_CAMR(i));
116		__raw_writel(0, UBC_CBR(i));
117
118		__raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
119
120		/* dummy read for write posting */
121		(void)__raw_readl(UBC_CRR(i));
122	}
123
124	clk_disable(ubc_iclk);
125
126	sh4a_ubc.clk = ubc_iclk;
127
128	return register_sh_ubc(&sh4a_ubc);
129}
130arch_initcall(sh4a_ubc_init);