diff --git a/drivers/gpu/drm/tegra/falcon.c b/drivers/gpu/drm/tegra/falcon.c index 56edef06c48e..223ab2ceb7e6 100644 --- a/drivers/gpu/drm/tegra/falcon.c +++ b/drivers/gpu/drm/tegra/falcon.c @@ -72,7 +72,7 @@ static int falcon_parse_firmware_image(struct falcon *falcon) struct falcon_fw_os_header_v1 *os; /* endian problems would show up right here */ - if (bin->magic != PCI_VENDOR_ID_NVIDIA) { + if (bin->magic != PCI_VENDOR_ID_NVIDIA && bin->magic != 0x10fe) { dev_err(falcon->dev, "incorrect firmware magic\n"); return -EINVAL; } @@ -178,9 +178,10 @@ int falcon_boot(struct falcon *falcon) falcon->firmware.data.offset + offset, offset, FALCON_MEMORY_DATA); - /* copy the first code segment into Falcon internal memory */ - falcon_copy_chunk(falcon, falcon->firmware.code.offset, - 0, FALCON_MEMORY_IMEM); + /* copy the code segment into Falcon internal memory */ + for (offset = 0; offset < falcon->firmware.code.size; offset += 256) + falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset, + offset, FALCON_MEMORY_IMEM); /* setup falcon interrupts */ falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) | diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index ade56b860cf9..a3dbb8813faf 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -135,16 +135,21 @@ static int vic_boot(struct vic *vic) hdr = vic->falcon.firmware.virt; fce_bin_data_offset = *(u32 *)(hdr + VIC_UCODE_FCE_DATA_OFFSET); - hdr = vic->falcon.firmware.virt + - *(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET); - fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET); falcon_execute_method(&vic->falcon, VIC_SET_APPLICATION_ID, 1); - falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE, - fce_ucode_size); - falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_OFFSET, - (vic->falcon.firmware.iova + fce_bin_data_offset) - >> 8); + + /* Old VIC firmware needs kernel help with setting up FCE microcode. */ + if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) { + hdr = vic->falcon.firmware.virt + + *(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET); + fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET); + + falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE, + fce_ucode_size); + falcon_execute_method( + &vic->falcon, VIC_SET_FCE_UCODE_OFFSET, + (vic->falcon.firmware.iova + fce_bin_data_offset) >> 8); + } err = falcon_wait_idle(&vic->falcon); if (err < 0) {