Lines Matching refs:falcon
12 #include "falcon.h"
20 static void falcon_writel(struct falcon *falcon, u32 value, u32 offset)
22 writel(value, falcon->regs + offset);
25 int falcon_wait_idle(struct falcon *falcon)
29 return readl_poll_timeout(falcon->regs + FALCON_IDLESTATE, value,
33 static int falcon_dma_wait_idle(struct falcon *falcon)
37 return readl_poll_timeout(falcon->regs + FALCON_DMATRFCMD, value,
41 static int falcon_copy_chunk(struct falcon *falcon,
59 falcon_writel(falcon, offset, FALCON_DMATRFMOFFS);
60 falcon_writel(falcon, base, FALCON_DMATRFFBOFFS);
61 falcon_writel(falcon, cmd, FALCON_DMATRFCMD);
63 return falcon_dma_wait_idle(falcon);
66 static void falcon_copy_firmware_image(struct falcon *falcon,
69 u32 *virt = falcon->firmware.virt;
77 static int falcon_parse_firmware_image(struct falcon *falcon)
79 struct falcon_fw_bin_header_v1 *bin = (void *)falcon->firmware.virt;
84 dev_err(falcon->dev, "incorrect firmware magic\n");
90 dev_err(falcon->dev, "unsupported firmware version\n");
95 if (bin->size > falcon->firmware.size) {
96 dev_err(falcon->dev, "firmware image size inconsistency\n");
100 os = falcon->firmware.virt + bin->os_header_offset;
102 falcon->firmware.bin_data.size = bin->os_size;
103 falcon->firmware.bin_data.offset = bin->os_data_offset;
104 falcon->firmware.code.offset = os->code_offset;
105 falcon->firmware.code.size = os->code_size;
106 falcon->firmware.data.offset = os->data_offset;
107 falcon->firmware.data.size = os->data_size;
112 int falcon_read_firmware(struct falcon *falcon, const char *name)
117 err = request_firmware(&falcon->firmware.firmware, name, falcon->dev);
121 falcon->firmware.size = falcon->firmware.firmware->size;
126 int falcon_load_firmware(struct falcon *falcon)
128 const struct firmware *firmware = falcon->firmware.firmware;
132 falcon_copy_firmware_image(falcon, firmware);
135 err = falcon_parse_firmware_image(falcon);
137 dev_err(falcon->dev, "failed to parse firmware image\n");
142 falcon->firmware.firmware = NULL;
147 int falcon_init(struct falcon *falcon)
149 falcon->firmware.virt = NULL;
154 void falcon_exit(struct falcon *falcon)
156 if (falcon->firmware.firmware)
157 release_firmware(falcon->firmware.firmware);
160 int falcon_boot(struct falcon *falcon)
166 if (!falcon->firmware.virt)
169 err = readl_poll_timeout(falcon->regs + FALCON_DMACTL, value,
176 falcon_writel(falcon, 0, FALCON_DMACTL);
179 falcon_writel(falcon, (falcon->firmware.iova +
180 falcon->firmware.bin_data.offset) >> 8,
184 for (offset = 0; offset < falcon->firmware.data.size; offset += 256)
185 falcon_copy_chunk(falcon,
186 falcon->firmware.data.offset + offset,
190 for (offset = 0; offset < falcon->firmware.code.size; offset += 256)
191 falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset,
194 /* setup falcon interrupts */
195 falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) |
202 falcon_writel(falcon, FALCON_IRQDEST_EXT(0xff) |
210 falcon_writel(falcon, FALCON_ITFEN_MTHDEN |
214 /* boot falcon */
215 falcon_writel(falcon, 0x00000000, FALCON_BOOTVEC);
216 falcon_writel(falcon, FALCON_CPUCTL_STARTCPU, FALCON_CPUCTL);
218 err = falcon_wait_idle(falcon);
220 dev_err(falcon->dev, "Falcon boot failed due to timeout\n");
227 void falcon_execute_method(struct falcon *falcon, u32 method, u32 data)
229 falcon_writel(falcon, method >> 2, FALCON_UCLASS_METHOD_OFFSET);
230 falcon_writel(falcon, data, FALCON_UCLASS_METHOD_DATA);