summaryrefslogtreecommitdiff
path: root/chip/ish/ish_dma.h
blob: 89d6cb734295b5f28cd37187f593af2c315622b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* Copyright 2019 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef __CROS_EC_ISH_DMA_H
#define __CROS_EC_ISH_DMA_H

/* DMA return codes */
#define DMA_RC_OK 0 /* Success */
#define DMA_RC_TO 1 /* Time out */
#define DMA_RC_HW 2 /* HW error (OCP) */

/* DMA channels */
#define PAGING_CHAN 0
#define KERNEL_CHAN 1

#define DST_IS_DRAM BIT(0)
#define SRC_IS_DRAM BIT(1)
#define NON_SNOOP BIT(2)

/* ISH5 and on */
#define RS0 0x0
#define RS3 0x3
#define RS_SRC_OFFSET 3
#define RS_DST_OFFSET 5

#define PAGE_SIZE 4096

static inline uint32_t interrupt_lock(void)
{
	uint32_t eflags = 0;

	__asm__ volatile("pushfl;" /* save eflag value */
			 "popl  %0;"
			 "cli;"
			 : "=r"(eflags)); /* shut off interrupts */
	return eflags;
}

static inline void interrupt_unlock(uint32_t eflags)
{
	__asm__ volatile("pushl  %0;" /* restore elfag values */
			 "popfl;"
			 :
			 : "r"(eflags));
}

static inline int dma_poll(uint32_t addr, uint32_t expected, uint32_t mask)
{
	int retval = -1;
	uint32_t counter = 0;

	/*
	 * The timeout is approximately 2.2 seconds according to
	 * value of UINT32_MAX, 120MHZ ISH clock frequency and
	 * instruction count which is around 4.
	 */
	while (counter < (UINT32_MAX / 64)) {
		/* test condition */
		if ((REG32(addr) & mask) == expected) {
			retval = DMA_RC_OK;
			break;
		}
		counter++;
	}

	return retval;
}

/**
 * SRAM: ISH local static ram
 * UMA: Protected system DRAM region dedicated for ISH
 * HOST_DRAM: OS owned buffer in system DRAM
 */
enum dma_mode {
	SRAM_TO_SRAM = 0,
	SRAM_TO_UMA = DST_IS_DRAM | (RS3 << RS_DST_OFFSET),
	UMA_TO_SRAM = SRC_IS_DRAM | (RS3 << RS_SRC_OFFSET),
	HOST_DRAM_TO_SRAM = SRC_IS_DRAM | (RS0 << RS_SRC_OFFSET),
	SRAM_TO_HOST_DRAM = DST_IS_DRAM | (RS0 << RS_DST_OFFSET)
};

/* Disable DMA engine */
void ish_dma_disable(void);
/* Initialize  DMA engine */
void ish_dma_init(void);

/**
 * Main DMA transfer function
 *
 * @param chan          DMA channel
 * @param dst           Destination address
 * @param src           Source address
 * @param length        Transfer size
 * @param mode          Transfer mode
 * @return DMA_RC_OK, or non-zero if error.
 */
int ish_dma_copy(uint32_t chan, uint32_t dst, uint32_t src, uint32_t length,
		 enum dma_mode mode);
/**
 * Set upper 32 bits address for DRAM
 *
 * @param chan          DMA channel
 * @param dst_msb       Destination DRAM upper 32 bits address
 * @param src_msb       Source DRAM upper 32 bits address
 */
void ish_dma_set_msb(uint32_t chan, uint32_t dst_msb, uint32_t src_msb);

/**
 * Wait for DMA transfer finish
 *
 * @param chan          DMA channel
 * @return DMA_RC_OK, or non-zero if error.
 */
int ish_wait_for_dma_done(uint32_t ch);

/* Disable OCP (Open Core Protocol) fabric time out */
void ish_dma_ocp_timeout_disable(void);
#endif