mb/ocp/tiogapass: Fix GPIOs
[coreboot2.git] / src / mainboard / ti / beaglebone / sd_media.c
blobe104d5e9c1a160d0ad19d5d1d900d1ce7a5585e0
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <boot_device.h>
4 #include <symbols.h>
5 #include <console/console.h>
6 #include <assert.h>
7 #include <commonlib/storage/sd_mmc.h>
8 #include <cbfs.h>
10 #include <soc/ti/am335x/mmc.h>
11 #include <soc/ti/am335x/header.h>
13 // Where the coreboot image is expected to be located on the SD card
14 // Only certain locations are allowed - check the AM335x technical reference
15 // manual for more details.
16 #define COREBOOT_IMAGE_OFFSET (128 * KiB)
18 #define SD_BLOCK_SIZE 512
20 static struct am335x_mmc_host sd_host;
21 static struct storage_media media;
23 static size_t partial_block_read(uint8_t *dest, uint64_t block, uint32_t offset, uint32_t count)
25 static uint8_t overflow_block[SD_BLOCK_SIZE];
27 uint64_t blocks_read = storage_block_read(&media, block, 1, &overflow_block);
29 if (blocks_read != 1) {
30 printk(BIOS_ERR, "Expected to read 1 block but read: %llu\n", blocks_read);
31 return 0;
34 assert((offset + count) <= SD_BLOCK_SIZE);
36 int dest_index = 0;
37 for (int overflow_index = offset; overflow_index < (offset + count); overflow_index++)
38 dest[dest_index++] = overflow_block[overflow_index];
40 return count;
43 // This supports reads from a SD card that aren't necessarily aligned to the
44 // sd block size
45 static ssize_t sd_readat(const struct region_device *rdev, void *dest, size_t offset,
46 size_t count)
48 uint8_t *buffer = (uint8_t *)dest;
50 uint64_t block_start = offset / SD_BLOCK_SIZE;
51 uint64_t block_end = (offset + count) / SD_BLOCK_SIZE;
52 uint64_t blocks = block_end - block_start + 1;
54 // Read the last first, which might not be aligned on a SD block
55 uint32_t first_block_offset = offset % SD_BLOCK_SIZE;
56 size_t first_block_to_read = MIN(SD_BLOCK_SIZE - first_block_offset, count);
57 size_t bytes_read = partial_block_read(buffer, block_start, first_block_offset,
58 first_block_to_read);
60 if (blocks == 1)
61 return bytes_read;
63 buffer += bytes_read;
65 if (blocks > 2) {
66 // Read all the "whole" blocks between the start and end blocks
67 uint64_t to_read = blocks - 2;
68 uint64_t blocks_read =
69 storage_block_read(&media, block_start + 1, to_read, (void *)buffer);
71 if (blocks_read != to_read) {
72 printk(BIOS_ERR, "Expecting to read %llu blocks but only read %llu\n",
73 to_read, blocks_read);
74 return blocks_read * SD_BLOCK_SIZE;
77 buffer += to_read * SD_BLOCK_SIZE;
78 bytes_read += to_read * SD_BLOCK_SIZE;
81 // Read the last block, which might not be aligned on a SD block
82 bytes_read += partial_block_read(buffer, block_end, 0, count - bytes_read);
84 return bytes_read;
87 static const struct region_device_ops am335x_sd_ops = {
88 .mmap = mmap_helper_rdev_mmap,
89 .munmap = mmap_helper_rdev_munmap,
90 .readat = sd_readat,
93 extern struct omap_image_headers headers;
95 static struct mmap_helper_region_device sd_mdev = MMAP_HELPER_DEV_INIT(
96 &am335x_sd_ops, COREBOOT_IMAGE_OFFSET + sizeof(headers), CONFIG_ROM_SIZE,
97 &cbfs_cache);
99 static bool init_done = false;
101 void boot_device_init(void)
103 if (init_done)
104 return;
106 sd_host.sd_clock_hz = 96000000;
107 sd_host.reg = (void *)MMCHS0_BASE;
108 am335x_mmc_init_storage(&sd_host);
109 storage_setup_media(&media, &sd_host.sd_mmc_ctrlr);
110 storage_display_setup(&media);
112 init_done = true;
115 const struct region_device *boot_device_ro(void)
117 return &sd_mdev.rdev;