Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1/*
  2 * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
  3 *
  4 * Copyright 2004-2008 Analog Devices Inc.
  5 * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
  6 * Licensed under the GPL-2 or later.
  7 */
  8
  9#include <linux/linkage.h>
 10#include <asm/blackfin.h>
 11
 12.align 2
 13
 14#ifdef CONFIG_IPIPE
 15# define DO_CLI \
 16	[--sp] = rets; \
 17	[--sp] = (P5:0); \
 18	sp += -12; \
 19	call ___ipipe_disable_root_irqs_hw; \
 20	sp += 12; \
 21	(P5:0) = [sp++];
 22# define CLI_INNER_NOP
 23#else
 24# define DO_CLI cli R3;
 25# define CLI_INNER_NOP nop; nop; nop;
 26#endif
 27
 28#ifdef CONFIG_IPIPE
 29# define DO_STI \
 30	sp += -12; \
 31	call ___ipipe_enable_root_irqs_hw; \
 32	sp += 12; \
 332:	rets = [sp++];
 34#else
 35# define DO_STI 2: sti R3;
 36#endif
 37
 38#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
 39# define CLI_OUTER DO_CLI;
 40# define STI_OUTER DO_STI;
 41# define CLI_INNER 1:
 42# if ANOMALY_05000416
 43#  define STI_INNER nop; 2: nop;
 44# else
 45#  define STI_INNER 2:
 46# endif
 47#else
 48# define CLI_OUTER
 49# define STI_OUTER
 50# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
 51# define STI_INNER DO_STI;
 52#endif
 53
 54/*
 55 * Reads on the Blackfin are speculative. In Blackfin terms, this means they
 56 * can be interrupted at any time (even after they have been issued on to the
 57 * external bus), and re-issued after the interrupt occurs.
 58 *
 59 * If a FIFO is sitting on the end of the read, it will see two reads,
 60 * when the core only sees one. The FIFO receives the read which is cancelled,
 61 * and not delivered to the core.
 62 *
 63 * To solve this, interrupts are turned off before reads occur to I/O space.
 64 * There are 3 versions of all these functions
 65 *  - turns interrupts off every read (higher overhead, but lower latency)
 66 *  - turns interrupts off every loop (low overhead, but longer latency)
 67 *  - DMA version, which do not suffer from this issue. DMA versions have
 68 *      different name (prefixed by dma_ ), and are located in
 69 *      ../kernel/bfin_dma.c
 70 * Using the dma related functions are recommended for transferring large
 71 * buffers in/out of FIFOs.
 72 */
 73
 74#define COMMON_INS(func, ops) \
 75ENTRY(_ins##func) \
 76	P0 = R0;	/* P0 = port */ \
 77	CLI_OUTER;	/* 3 instructions before first read access */ \
 78	P1 = R1;	/* P1 = address */ \
 79	P2 = R2;	/* P2 = count */ \
 80	SSYNC; \
 81 \
 82	LSETUP(1f, 2f) LC0 = P2; \
 83	CLI_INNER; \
 84	ops; \
 85	STI_INNER; \
 86 \
 87	STI_OUTER; \
 88	RTS; \
 89ENDPROC(_ins##func)
 90
 91COMMON_INS(l, \
 92	R0 = [P0]; \
 93	[P1++] = R0; \
 94)
 95
 96COMMON_INS(w, \
 97	R0 = W[P0]; \
 98	W[P1++] = R0; \
 99)
100
101COMMON_INS(w_8, \
102	R0 = W[P0]; \
103	B[P1++] = R0; \
104	R0 = R0 >> 8; \
105	B[P1++] = R0; \
106)
107
108COMMON_INS(b, \
109	R0 = B[P0]; \
110	B[P1++] = R0; \
111)
112
113COMMON_INS(l_16, \
114	R0 = [P0]; \
115	W[P1++] = R0; \
116	R0 = R0 >> 16; \
117	W[P1++] = R0; \
118)