xref: /arm-trusted-firmware/drivers/renesas/common/io/io_emmcdrv.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <string.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <common/debug.h>
10*91f16700Schasinglulu #include <drivers/io/io_driver.h>
11*91f16700Schasinglulu #include <drivers/io/io_storage.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include "emmc_config.h"
14*91f16700Schasinglulu #include "emmc_def.h"
15*91f16700Schasinglulu #include "emmc_hal.h"
16*91f16700Schasinglulu #include "emmc_std.h"
17*91f16700Schasinglulu #include "io_common.h"
18*91f16700Schasinglulu #include "io_emmcdrv.h"
19*91f16700Schasinglulu #include "io_private.h"
20*91f16700Schasinglulu 
21*91f16700Schasinglulu static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)),
22*91f16700Schasinglulu 				io_dev_info_t **dev_info);
23*91f16700Schasinglulu static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info);
24*91f16700Schasinglulu 
25*91f16700Schasinglulu typedef struct {
26*91f16700Schasinglulu 	uint32_t in_use;
27*91f16700Schasinglulu 	uintptr_t base;
28*91f16700Schasinglulu 	signed long long file_pos;
29*91f16700Schasinglulu 	EMMC_PARTITION_ID partition;
30*91f16700Schasinglulu } file_state_t;
31*91f16700Schasinglulu 
32*91f16700Schasinglulu static file_state_t current_file = { 0 };
33*91f16700Schasinglulu 
34*91f16700Schasinglulu static EMMC_PARTITION_ID emmcdrv_bootpartition = PARTITION_ID_USER;
35*91f16700Schasinglulu 
36*91f16700Schasinglulu static io_type_t device_type_emmcdrv(void)
37*91f16700Schasinglulu {
38*91f16700Schasinglulu 	return IO_TYPE_MEMMAP;
39*91f16700Schasinglulu }
40*91f16700Schasinglulu 
41*91f16700Schasinglulu static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode,
42*91f16700Schasinglulu 				  signed long long offset)
43*91f16700Schasinglulu {
44*91f16700Schasinglulu 	if (mode != IO_SEEK_SET) {
45*91f16700Schasinglulu 		return IO_FAIL;
46*91f16700Schasinglulu 	}
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	((file_state_t *) entity->info)->file_pos = offset;
49*91f16700Schasinglulu 
50*91f16700Schasinglulu 	return IO_SUCCESS;
51*91f16700Schasinglulu }
52*91f16700Schasinglulu 
53*91f16700Schasinglulu static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer,
54*91f16700Schasinglulu 				  size_t length, size_t *length_read)
55*91f16700Schasinglulu {
56*91f16700Schasinglulu 	file_state_t *fp = (file_state_t *) entity->info;
57*91f16700Schasinglulu 	uint32_t sector_add, sector_num, emmc_dma = 0;
58*91f16700Schasinglulu 	int32_t result = IO_SUCCESS;
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT;
61*91f16700Schasinglulu 	sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT;
62*91f16700Schasinglulu 
63*91f16700Schasinglulu 	NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n",
64*91f16700Schasinglulu 	       buffer,
65*91f16700Schasinglulu 	       current_file.partition, current_file.file_pos,
66*91f16700Schasinglulu 	       sector_add, length, sector_num);
67*91f16700Schasinglulu 
68*91f16700Schasinglulu 	if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) {
69*91f16700Schasinglulu 		emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE;
70*91f16700Schasinglulu 	}
71*91f16700Schasinglulu 
72*91f16700Schasinglulu 	if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num,
73*91f16700Schasinglulu 			     emmc_dma) != EMMC_SUCCESS) {
74*91f16700Schasinglulu 		result = IO_FAIL;
75*91f16700Schasinglulu 	}
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 	*length_read = length;
78*91f16700Schasinglulu 	fp->file_pos += (signed long long)length;
79*91f16700Schasinglulu 
80*91f16700Schasinglulu 	return result;
81*91f16700Schasinglulu }
82*91f16700Schasinglulu 
83*91f16700Schasinglulu static int32_t emmcdrv_block_open(io_dev_info_t *dev_info,
84*91f16700Schasinglulu 				  const uintptr_t spec, io_entity_t *entity)
85*91f16700Schasinglulu {
86*91f16700Schasinglulu 	const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
87*91f16700Schasinglulu 
88*91f16700Schasinglulu 	if (current_file.in_use != 0U) {
89*91f16700Schasinglulu 		WARN("mmc_block: Only one open spec at a time\n");
90*91f16700Schasinglulu 		return IO_RESOURCES_EXHAUSTED;
91*91f16700Schasinglulu 	}
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	current_file.file_pos = 0;
94*91f16700Schasinglulu 	current_file.in_use = 1;
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 	if (emmcdrv_bootpartition == PARTITION_ID_USER) {
97*91f16700Schasinglulu 		emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en;
98*91f16700Schasinglulu 		if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) ||
99*91f16700Schasinglulu 		    (emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) {
100*91f16700Schasinglulu 			current_file.partition = emmcdrv_bootpartition;
101*91f16700Schasinglulu 
102*91f16700Schasinglulu 			NOTICE("BL2: eMMC boot from partition %d\n",
103*91f16700Schasinglulu 			       emmcdrv_bootpartition);
104*91f16700Schasinglulu 			goto done;
105*91f16700Schasinglulu 		}
106*91f16700Schasinglulu 		return IO_FAIL;
107*91f16700Schasinglulu 	}
108*91f16700Schasinglulu 
109*91f16700Schasinglulu 	if ((block_spec->partition == PARTITION_ID_USER) ||
110*91f16700Schasinglulu 	    (block_spec->partition == PARTITION_ID_BOOT_1) ||
111*91f16700Schasinglulu 	    (block_spec->partition == PARTITION_ID_BOOT_2)) {
112*91f16700Schasinglulu 		current_file.partition = block_spec->partition;
113*91f16700Schasinglulu 	} else {
114*91f16700Schasinglulu 		current_file.partition = emmcdrv_bootpartition;
115*91f16700Schasinglulu 	}
116*91f16700Schasinglulu 
117*91f16700Schasinglulu done:
118*91f16700Schasinglulu 	if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) {
119*91f16700Schasinglulu 		return IO_FAIL;
120*91f16700Schasinglulu 	}
121*91f16700Schasinglulu 
122*91f16700Schasinglulu 	entity->info = (uintptr_t) &current_file;
123*91f16700Schasinglulu 
124*91f16700Schasinglulu 	return IO_SUCCESS;
125*91f16700Schasinglulu }
126*91f16700Schasinglulu 
127*91f16700Schasinglulu static int32_t emmcdrv_block_close(io_entity_t *entity)
128*91f16700Schasinglulu {
129*91f16700Schasinglulu 	memset((void *)&current_file, 0, sizeof(current_file));
130*91f16700Schasinglulu 	entity->info = 0U;
131*91f16700Schasinglulu 
132*91f16700Schasinglulu 	return IO_SUCCESS;
133*91f16700Schasinglulu }
134*91f16700Schasinglulu 
135*91f16700Schasinglulu static const io_dev_funcs_t emmcdrv_dev_funcs = {
136*91f16700Schasinglulu 	.type = &device_type_emmcdrv,
137*91f16700Schasinglulu 	.open = &emmcdrv_block_open,
138*91f16700Schasinglulu 	.seek = &emmcdrv_block_seek,
139*91f16700Schasinglulu 	.size = NULL,
140*91f16700Schasinglulu 	.read = &emmcdrv_block_read,
141*91f16700Schasinglulu 	.write = NULL,
142*91f16700Schasinglulu 	.close = &emmcdrv_block_close,
143*91f16700Schasinglulu 	.dev_init = NULL,
144*91f16700Schasinglulu 	.dev_close = &emmcdrv_dev_close
145*91f16700Schasinglulu };
146*91f16700Schasinglulu 
147*91f16700Schasinglulu static const io_dev_info_t emmcdrv_dev_info = {
148*91f16700Schasinglulu 	.funcs = &emmcdrv_dev_funcs,
149*91f16700Schasinglulu 	.info = (uintptr_t) 0
150*91f16700Schasinglulu };
151*91f16700Schasinglulu 
152*91f16700Schasinglulu static const io_dev_connector_t emmcdrv_dev_connector = {
153*91f16700Schasinglulu 	&emmcdrv_dev_open,
154*91f16700Schasinglulu };
155*91f16700Schasinglulu 
156*91f16700Schasinglulu static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)),
157*91f16700Schasinglulu 				io_dev_info_t **dev_info)
158*91f16700Schasinglulu {
159*91f16700Schasinglulu 	*dev_info = (io_dev_info_t *) &emmcdrv_dev_info;
160*91f16700Schasinglulu 
161*91f16700Schasinglulu 	return IO_SUCCESS;
162*91f16700Schasinglulu }
163*91f16700Schasinglulu 
164*91f16700Schasinglulu static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info)
165*91f16700Schasinglulu {
166*91f16700Schasinglulu 	return IO_SUCCESS;
167*91f16700Schasinglulu }
168*91f16700Schasinglulu 
169*91f16700Schasinglulu int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con)
170*91f16700Schasinglulu {
171*91f16700Schasinglulu 	int32_t rc;
172*91f16700Schasinglulu 
173*91f16700Schasinglulu 	rc = io_register_device(&emmcdrv_dev_info);
174*91f16700Schasinglulu 	if (rc == IO_SUCCESS) {
175*91f16700Schasinglulu 		*dev_con = &emmcdrv_dev_connector;
176*91f16700Schasinglulu 	}
177*91f16700Schasinglulu 
178*91f16700Schasinglulu 	return rc;
179*91f16700Schasinglulu }
180