1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <ddk/debug.h> 6#include <ddk/metadata.h> 7#include <ddk/protocol/platform-defs.h> 8#include <hw/reg.h> 9#include <soc/aml-s912/s912-hw.h> 10#include <soc/aml-a113/a113-hw.h> 11#include <soc/aml-s912/s912-gpio.h> 12#include <soc/aml-common/aml-sd-emmc.h> 13 14#include "vim.h" 15 16#define BIT_MASK(start, count) (((1 << (count)) - 1) << (start)) 17#define SET_BITS(dest, start, count, value) \ 18 ((dest & ~BIT_MASK(start, count)) | (((value) << (start)) & BIT_MASK(start, count))) 19 20/*static const pbus_mmio_t sdio_mmios[] = { 21 { 22 .base = 0xD0070000, 23 .length = 0x2000, 24 } 25}; 26 27static const pbus_mmio_t sd_mmios[] = { 28 { 29 .base = 0xD0072000, 30 .length = 0x2000, 31 } 32};*/ 33 34/*static const pbus_irq_t sdio_irqs[] = { 35 { 36 .irq = 248, 37 }, 38}; 39 40static const pbus_irq_t sd_irqs[] = { 41 { 42 .irq = 249, 43 }, 44};*/ 45 46static const pbus_mmio_t emmc_mmios[] = { 47 { 48 .base = 0xD0074000, 49 .length = 0x2000, 50 } 51}; 52 53static const pbus_irq_t emmc_irqs[] = { 54 { 55 .irq = 250, 56 }, 57}; 58 59static const pbus_bti_t emmc_btis[] = { 60 { 61 .iommu_index = 0, 62 .bti_id = BTI_EMMC, 63 }, 64}; 65 66static const pbus_gpio_t emmc_gpios[] = { 67 { 68 .gpio = S912_EMMC_RST, 69 }, 70}; 71 72static aml_sd_emmc_config_t config = { 73 .supports_dma = true, 74 //As per AMlogic, on S912 chipset, HS400 mode can be operated at 125MHZ or low. 75 .min_freq = 400000, 76 .max_freq = 120000000, 77}; 78 79static const pbus_metadata_t emmc_metadata[] = { 80 { 81 .type = DEVICE_METADATA_PRIVATE, 82 .data = &config, 83 .len = sizeof(config), 84 }, 85}; 86 87static const pbus_boot_metadata_t emmc_boot_metadata[] = { 88 { 89 .zbi_type = DEVICE_METADATA_PARTITION_MAP, 90 .zbi_extra = 0, 91 }, 92}; 93 94static const pbus_dev_t emmc_dev = { 95 .name = "aml_emmc", 96 .vid = PDEV_VID_AMLOGIC, 97 .pid = PDEV_PID_GENERIC, 98 .did = PDEV_DID_AMLOGIC_SD_EMMC, 99 .mmios = emmc_mmios, 100 .mmio_count = countof(emmc_mmios), 101 .irqs = emmc_irqs, 102 .irq_count = countof(emmc_irqs), 103 .btis = emmc_btis, 104 .bti_count = countof(emmc_btis), 105 .gpios = emmc_gpios, 106 .gpio_count = countof(emmc_gpios), 107 .metadata = emmc_metadata, 108 .metadata_count = countof(emmc_metadata), 109 .boot_metadata = emmc_boot_metadata, 110 .boot_metadata_count = countof(emmc_boot_metadata), 111}; 112 113zx_status_t vim_sd_emmc_init(vim_bus_t* bus) { 114 zx_status_t status; 115 116 // set alternate functions to enable EMMC 117 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D0, S912_EMMC_NAND_D0_FN); 118 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D1, S912_EMMC_NAND_D1_FN); 119 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D2, S912_EMMC_NAND_D2_FN); 120 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D3, S912_EMMC_NAND_D3_FN); 121 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D4, S912_EMMC_NAND_D4_FN); 122 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D5, S912_EMMC_NAND_D5_FN); 123 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D6, S912_EMMC_NAND_D6_FN); 124 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_NAND_D7, S912_EMMC_NAND_D7_FN); 125 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_CLK, S912_EMMC_CLK_FN); 126 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_RST, S912_EMMC_RST_FN); 127 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_CMD, S912_EMMC_CMD_FN); 128 gpio_impl_set_alt_function(&bus->gpio, S912_EMMC_DS, S912_EMMC_DS_FN); 129 130 if ((status = pbus_device_add(&bus->pbus, &emmc_dev)) != ZX_OK) { 131 zxlogf(ERROR, "vim_sd_emmc_init could not add emmc_dev: %d\n", status); 132 return status; 133 } 134 135 return ZX_OK; 136} 137