1 /* 2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 * Based on drivers/misc/eeprom/sunxi_sid.c 17 */ 18 19 #include <linux/device.h> 20 #include <linux/clk.h> 21 #include <linux/completion.h> 22 #include <linux/dmaengine.h> 23 #include <linux/dma-mapping.h> 24 #include <linux/err.h> 25 #include <linux/io.h> 26 #include <linux/kernel.h> 27 #include <linux/kobject.h> 28 #include <linux/of_device.h> 29 #include <linux/platform_device.h> 30 #include <linux/random.h> 31 32 #include <soc/tegra/fuse.h> 33 34 #include "fuse.h" 35 36 #define FUSE_BEGIN 0x100 37 #define FUSE_UID_LOW 0x08 38 #define FUSE_UID_HIGH 0x0c 39 40 static u32 tegra20_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) 41 { 42 return readl_relaxed(fuse->base + FUSE_BEGIN + offset); 43 } 44 45 static void apb_dma_complete(void *args) 46 { 47 struct tegra_fuse *fuse = args; 48 49 complete(&fuse->apbdma.wait); 50 } 51 52 static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset) 53 { 54 unsigned long flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; 55 struct dma_async_tx_descriptor *dma_desc; 56 unsigned long time_left; 57 u32 value = 0; 58 int err; 59 60 mutex_lock(&fuse->apbdma.lock); 61 62 fuse->apbdma.config.src_addr = fuse->phys + FUSE_BEGIN + offset; 63 64 err = dmaengine_slave_config(fuse->apbdma.chan, &fuse->apbdma.config); 65 if (err) 66 goto out; 67 68 dma_desc = dmaengine_prep_slave_single(fuse->apbdma.chan, 69 fuse->apbdma.phys, 70 sizeof(u32), DMA_DEV_TO_MEM, 71 flags); 72 if (!dma_desc) 73 goto out; 74 75 dma_desc->callback = apb_dma_complete; 76 dma_desc->callback_param = fuse; 77 78 reinit_completion(&fuse->apbdma.wait); 79 80 clk_prepare_enable(fuse->clk); 81 82 dmaengine_submit(dma_desc); 83 dma_async_issue_pending(fuse->apbdma.chan); 84 time_left = wait_for_completion_timeout(&fuse->apbdma.wait, 85 msecs_to_jiffies(50)); 86 87 if (WARN(time_left == 0, "apb read dma timed out")) 88 dmaengine_terminate_all(fuse->apbdma.chan); 89 else 90 value = *fuse->apbdma.virt; 91 92 clk_disable_unprepare(fuse->clk); 93 94 out: 95 mutex_unlock(&fuse->apbdma.lock); 96 return value; 97 } 98 99 static bool dma_filter(struct dma_chan *chan, void *filter_param) 100 { 101 struct device_node *np = chan->device->dev->of_node; 102 103 return of_device_is_compatible(np, "nvidia,tegra20-apbdma"); 104 } 105 106 static int tegra20_fuse_probe(struct tegra_fuse *fuse) 107 { 108 dma_cap_mask_t mask; 109 110 dma_cap_zero(mask); 111 dma_cap_set(DMA_SLAVE, mask); 112 113 fuse->apbdma.chan = __dma_request_channel(&mask, dma_filter, NULL); 114 if (!fuse->apbdma.chan) 115 return -EPROBE_DEFER; 116 117 fuse->apbdma.virt = dma_alloc_coherent(fuse->dev, sizeof(u32), 118 &fuse->apbdma.phys, 119 GFP_KERNEL); 120 if (!fuse->apbdma.virt) { 121 dma_release_channel(fuse->apbdma.chan); 122 return -ENOMEM; 123 } 124 125 fuse->apbdma.config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 126 fuse->apbdma.config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 127 fuse->apbdma.config.src_maxburst = 1; 128 fuse->apbdma.config.dst_maxburst = 1; 129 fuse->apbdma.config.direction = DMA_DEV_TO_MEM; 130 fuse->apbdma.config.device_fc = false; 131 132 init_completion(&fuse->apbdma.wait); 133 mutex_init(&fuse->apbdma.lock); 134 fuse->read = tegra20_fuse_read; 135 136 return 0; 137 } 138 139 static const struct tegra_fuse_info tegra20_fuse_info = { 140 .read = tegra20_fuse_read, 141 .size = 0x1f8, 142 .spare = 0x100, 143 }; 144 145 /* Early boot code. This code is called before the devices are created */ 146 147 static void __init tegra20_fuse_add_randomness(void) 148 { 149 u32 randomness[7]; 150 151 randomness[0] = tegra_sku_info.sku_id; 152 randomness[1] = tegra_read_straps(); 153 randomness[2] = tegra_read_chipid(); 154 randomness[3] = tegra_sku_info.cpu_process_id << 16; 155 randomness[3] |= tegra_sku_info.soc_process_id; 156 randomness[4] = tegra_sku_info.cpu_speedo_id << 16; 157 randomness[4] |= tegra_sku_info.soc_speedo_id; 158 randomness[5] = tegra_fuse_read_early(FUSE_UID_LOW); 159 randomness[6] = tegra_fuse_read_early(FUSE_UID_HIGH); 160 161 add_device_randomness(randomness, sizeof(randomness)); 162 } 163 164 static void __init tegra20_fuse_init(struct tegra_fuse *fuse) 165 { 166 fuse->read_early = tegra20_fuse_read_early; 167 168 tegra_init_revision(); 169 fuse->soc->speedo_init(&tegra_sku_info); 170 tegra20_fuse_add_randomness(); 171 } 172 173 const struct tegra_fuse_soc tegra20_fuse_soc = { 174 .init = tegra20_fuse_init, 175 .speedo_init = tegra20_init_speedo_data, 176 .probe = tegra20_fuse_probe, 177 .info = &tegra20_fuse_info, 178 }; 179