Loading drivers/gpu/msm/a6xx_reg.h +33 −27 Original line number Diff line number Diff line Loading @@ -1058,33 +1058,39 @@ #define A6XX_RSCC_TCS3_DRV0_STATUS 0x23B7E /* GPU PDC sequencer registers in AOSS.RPMh domain */ #define PDC_GPU_ENABLE_PDC 0x21140 #define PDC_GPU_SEQ_START_ADDR 0x21148 #define PDC_GPU_TCS0_CONTROL 0x21540 #define PDC_GPU_TCS0_CMD_ENABLE_BANK 0x21541 #define PDC_GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK 0x21542 #define PDC_GPU_TCS0_CMD0_MSGID 0x21543 #define PDC_GPU_TCS0_CMD0_ADDR 0x21544 #define PDC_GPU_TCS0_CMD0_DATA 0x21545 #define PDC_GPU_TCS1_CONTROL 0x21572 #define PDC_GPU_TCS1_CMD_ENABLE_BANK 0x21573 #define PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK 0x21574 #define PDC_GPU_TCS1_CMD0_MSGID 0x21575 #define PDC_GPU_TCS1_CMD0_ADDR 0x21576 #define PDC_GPU_TCS1_CMD0_DATA 0x21577 #define PDC_GPU_TCS2_CONTROL 0x215A4 #define PDC_GPU_TCS2_CMD_ENABLE_BANK 0x215A5 #define PDC_GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK 0x215A6 #define PDC_GPU_TCS2_CMD0_MSGID 0x215A7 #define PDC_GPU_TCS2_CMD0_ADDR 0x215A8 #define PDC_GPU_TCS2_CMD0_DATA 0x215A9 #define PDC_GPU_TCS3_CONTROL 0x215D6 #define PDC_GPU_TCS3_CMD_ENABLE_BANK 0x215D7 #define PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK 0x215D8 #define PDC_GPU_TCS3_CMD0_MSGID 0x215D9 #define PDC_GPU_TCS3_CMD0_ADDR 0x215DA #define PDC_GPU_TCS3_CMD0_DATA 0x215DB #define PDC_GPU_SEQ_MEM_0 0xA0000 #define PDC_GPU_ENABLE_PDC 0x1140 #define PDC_GPU_SEQ_START_ADDR 0x1148 #define PDC_GPU_TCS0_CONTROL 0x1540 #define PDC_GPU_TCS0_CMD_ENABLE_BANK 0x1541 #define PDC_GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK 0x1542 #define PDC_GPU_TCS0_CMD0_MSGID 0x1543 #define PDC_GPU_TCS0_CMD0_ADDR 0x1544 #define PDC_GPU_TCS0_CMD0_DATA 0x1545 #define PDC_GPU_TCS1_CONTROL 0x1572 #define PDC_GPU_TCS1_CMD_ENABLE_BANK 0x1573 #define PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK 0x1574 #define PDC_GPU_TCS1_CMD0_MSGID 0x1575 #define PDC_GPU_TCS1_CMD0_ADDR 0x1576 #define PDC_GPU_TCS1_CMD0_DATA 0x1577 #define PDC_GPU_TCS2_CONTROL 0x15A4 #define PDC_GPU_TCS2_CMD_ENABLE_BANK 0x15A5 #define PDC_GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK 0x15A6 #define PDC_GPU_TCS2_CMD0_MSGID 0x15A7 #define PDC_GPU_TCS2_CMD0_ADDR 0x15A8 #define PDC_GPU_TCS2_CMD0_DATA 0x15A9 #define PDC_GPU_TCS3_CONTROL 0x15D6 #define PDC_GPU_TCS3_CMD_ENABLE_BANK 0x15D7 #define PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK 0x15D8 #define PDC_GPU_TCS3_CMD0_MSGID 0x15D9 #define PDC_GPU_TCS3_CMD0_ADDR 0x15DA #define PDC_GPU_TCS3_CMD0_DATA 0x15DB /* * Legacy DTSI used an offset from the start of the PDC resource * for PDC SEQ programming. We are now using PDC subsections so * start the PDC SEQ offset at zero. */ #define PDC_GPU_SEQ_MEM_0 0x0 #endif /* _A6XX_REG_H */ drivers/gpu/msm/adreno_a6xx_gmu.c +111 −56 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ #include <linux/firmware.h> #include <linux/jiffies.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/of_platform.h> #include "kgsl_gmu_core.h" #include "kgsl_gmu.h" Loading Loading @@ -79,10 +81,70 @@ static void _regwrite(void __iomem *regbase, * PDC and RSC execute GPU power on/off RPMh sequence * @device: Pointer to KGSL device */ static void _load_gmu_rpmh_ucode(struct kgsl_device *device) static int _load_gmu_rpmh_ucode(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct resource *res_pdc, *res_cfg, *res_seq; void __iomem *cfg = NULL, *seq = NULL; unsigned int cfg_offset, seq_offset; /* Offsets from the base PDC (if no PDC subsections in the DTSI) */ if (adreno_is_a640v2(adreno_dev)) { cfg_offset = 0x90000; seq_offset = 0x290000; } else { cfg_offset = 0x80000; seq_offset = 0x280000; } /* * Older A6x platforms specified PDC registers in the DT using a * single base pointer that encompassed the entire PDC range. Current * targets specify the individual GPU-owned PDC register blocks * (sequence and config). * * This code handles both possibilities and generates individual * pointers to the GPU PDC blocks, either as offsets from the single * base, or as directly specified ranges. */ /* Get pointers to each of the possible PDC resources */ res_pdc = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_reg"); res_cfg = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_cfg"); res_seq = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_seq"); /* * Map the starting address for pdc_cfg programming. If the pdc_cfg * resource is not available use an offset from the base PDC resource. */ if (res_cfg) cfg = ioremap(res_cfg->start, resource_size(res_cfg)); else if (res_pdc) cfg = ioremap(res_pdc->start + cfg_offset, 0x10000); if (!cfg) { dev_err(&gmu->pdev->dev, "Failed to map PDC CFG\n"); return -ENODEV; } /* * Map the starting address for pdc_seq programming. If the pdc_seq * resource is not available use an offset from the base PDC resource. */ if (res_seq) seq = ioremap(res_seq->start, resource_size(res_seq)); else if (res_pdc) seq = ioremap(res_pdc->start + seq_offset, 0x10000); if (!seq) { dev_err(&gmu->pdev->dev, "Failed to map PDC SEQ\n"); iounmap(cfg); return -ENODEV; } /* Disable SDE clock gating */ gmu_core_regwrite(device, A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24)); Loading Loading @@ -118,68 +180,62 @@ static void _load_gmu_rpmh_ucode(struct kgsl_device *device) gmu_core_regwrite(device, A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020E8A8); /* Load PDC sequencer uCode for power up and power down sequence */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0, 0xFEBEA1E1); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 1, 0xA5A4A3A2); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 2, 0x8382A6E0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 3, 0xBCE3E284); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 4, 0x002081FC); _regwrite(seq, PDC_GPU_SEQ_MEM_0, 0xFEBEA1E1); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 1, 0xA5A4A3A2); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 2, 0x8382A6E0); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 3, 0xBCE3E284); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 4, 0x002081FC); /* Set TCS commands used by PDC sequence for low power modes */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD_ENABLE_BANK, 7); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CONTROL, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR, 0x30010); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA, 1); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET, 0x0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD_ENABLE_BANK, 7); _regwrite(cfg, PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(cfg, PDC_GPU_TCS1_CONTROL, 0); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR, 0x30010); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA, 1); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET, 0x0); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); else _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD_ENABLE_BANK, 7); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CONTROL, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR, 0x30010); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA, 2); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x3); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x0); _regwrite(cfg, PDC_GPU_TCS3_CMD_ENABLE_BANK, 7); _regwrite(cfg, PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(cfg, PDC_GPU_TCS3_CONTROL, 0); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID, 0x10108); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR, 0x30010); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA, 2); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x3); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); else _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x3); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x3); /* Setup GPU PDC */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_START_ADDR, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_ENABLE_PDC, 0x80000001); _regwrite(cfg, PDC_GPU_SEQ_START_ADDR, 0); _regwrite(cfg, PDC_GPU_ENABLE_PDC, 0x80000001); /* ensure no writes happen before the uCode is fully written */ wmb(); iounmap(seq); iounmap(cfg); return 0; } /* GMU timeouts */ Loading Loading @@ -900,12 +956,11 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device, gmu_core_regwrite(device, A6XX_GMU_GENERAL_7, 1); if (!test_and_set_bit(GMU_BOOT_INIT_DONE, &gmu->flags)) _load_gmu_rpmh_ucode(device); else { ret = _load_gmu_rpmh_ucode(device); else ret = a6xx_rpmh_power_on_gpu(device); if (ret) return ret; } if (gmu->load_mode == TCM_BOOT) { /* Load GMU image via AHB bus */ Loading drivers/gpu/msm/kgsl_gmu.c +14 −32 Original line number Diff line number Diff line Loading @@ -1076,44 +1076,35 @@ static int gmu_pwrlevel_probe(struct gmu_device *gmu, struct device_node *node) return 0; } static int gmu_reg_probe(struct gmu_device *gmu, const char *name, bool is_gmu) static int gmu_reg_probe(struct gmu_device *gmu) { struct resource *res; res = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, name); res = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_reg"); if (res == NULL) { dev_err(&gmu->pdev->dev, "platform_get_resource %s failed\n", name); "platform_get_resource kgsl_gmu_reg failed\n"); return -EINVAL; } if (res->start == 0 || resource_size(res) == 0) { dev_err(&gmu->pdev->dev, "dev %d %s invalid register region\n", gmu->pdev->dev.id, name); "dev %d kgsl_gmu_reg invalid register region\n", gmu->pdev->dev.id); return -EINVAL; } if (is_gmu) { gmu->reg_phys = res->start; gmu->reg_len = resource_size(res); gmu->reg_virt = devm_ioremap(&gmu->pdev->dev, res->start, resource_size(res)); if (gmu->reg_virt == NULL) { dev_err(&gmu->pdev->dev, "GMU regs ioremap failed\n"); dev_err(&gmu->pdev->dev, "kgsl_gmu_reg ioremap failed\n"); return -ENODEV; } } else { gmu->pdc_reg_virt = devm_ioremap(&gmu->pdev->dev, res->start, resource_size(res)); if (gmu->pdc_reg_virt == NULL) { dev_err(&gmu->pdev->dev, "PDC regs ioremap failed\n"); return -ENODEV; } } return 0; } Loading Loading @@ -1314,11 +1305,7 @@ static int gmu_probe(struct kgsl_device *device, mem_addr = gmu->hfi_mem; /* Map and reserve GMU CSRs registers */ ret = gmu_reg_probe(gmu, "kgsl_gmu_reg", true); if (ret) goto error; ret = gmu_reg_probe(gmu, "kgsl_gmu_pdc_reg", false); ret = gmu_reg_probe(gmu); if (ret) goto error; Loading Loading @@ -1740,11 +1727,6 @@ static void gmu_remove(struct kgsl_device *device) gmu->pcl = 0; } if (gmu->pdc_reg_virt) { devm_iounmap(&gmu->pdev->dev, gmu->pdc_reg_virt); gmu->pdc_reg_virt = NULL; } if (gmu->reg_virt) { devm_iounmap(&gmu->pdev->dev, gmu->reg_virt); gmu->reg_virt = NULL; Loading drivers/gpu/msm/kgsl_gmu.h +0 −2 Original line number Diff line number Diff line Loading @@ -105,7 +105,6 @@ enum gmu_load_mode { * @reg_phys: GMU CSR physical address * @reg_virt: GMU CSR virtual address * @reg_len: GMU CSR range * @pdc_reg_virt: starting kernel virtual address for RPMh PDC registers * @gmu_interrupt_num: GMU interrupt number * @fw_image: descriptor of GMU memory that has GMU image in it * @hfi_mem: pointer to HFI shared memory Loading Loading @@ -142,7 +141,6 @@ struct gmu_device { unsigned long reg_phys; void __iomem *reg_virt; unsigned int reg_len; void __iomem *pdc_reg_virt; unsigned int gmu_interrupt_num; struct gmu_memdesc cached_fw_image; struct gmu_memdesc *fw_image; Loading Loading
drivers/gpu/msm/a6xx_reg.h +33 −27 Original line number Diff line number Diff line Loading @@ -1058,33 +1058,39 @@ #define A6XX_RSCC_TCS3_DRV0_STATUS 0x23B7E /* GPU PDC sequencer registers in AOSS.RPMh domain */ #define PDC_GPU_ENABLE_PDC 0x21140 #define PDC_GPU_SEQ_START_ADDR 0x21148 #define PDC_GPU_TCS0_CONTROL 0x21540 #define PDC_GPU_TCS0_CMD_ENABLE_BANK 0x21541 #define PDC_GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK 0x21542 #define PDC_GPU_TCS0_CMD0_MSGID 0x21543 #define PDC_GPU_TCS0_CMD0_ADDR 0x21544 #define PDC_GPU_TCS0_CMD0_DATA 0x21545 #define PDC_GPU_TCS1_CONTROL 0x21572 #define PDC_GPU_TCS1_CMD_ENABLE_BANK 0x21573 #define PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK 0x21574 #define PDC_GPU_TCS1_CMD0_MSGID 0x21575 #define PDC_GPU_TCS1_CMD0_ADDR 0x21576 #define PDC_GPU_TCS1_CMD0_DATA 0x21577 #define PDC_GPU_TCS2_CONTROL 0x215A4 #define PDC_GPU_TCS2_CMD_ENABLE_BANK 0x215A5 #define PDC_GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK 0x215A6 #define PDC_GPU_TCS2_CMD0_MSGID 0x215A7 #define PDC_GPU_TCS2_CMD0_ADDR 0x215A8 #define PDC_GPU_TCS2_CMD0_DATA 0x215A9 #define PDC_GPU_TCS3_CONTROL 0x215D6 #define PDC_GPU_TCS3_CMD_ENABLE_BANK 0x215D7 #define PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK 0x215D8 #define PDC_GPU_TCS3_CMD0_MSGID 0x215D9 #define PDC_GPU_TCS3_CMD0_ADDR 0x215DA #define PDC_GPU_TCS3_CMD0_DATA 0x215DB #define PDC_GPU_SEQ_MEM_0 0xA0000 #define PDC_GPU_ENABLE_PDC 0x1140 #define PDC_GPU_SEQ_START_ADDR 0x1148 #define PDC_GPU_TCS0_CONTROL 0x1540 #define PDC_GPU_TCS0_CMD_ENABLE_BANK 0x1541 #define PDC_GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK 0x1542 #define PDC_GPU_TCS0_CMD0_MSGID 0x1543 #define PDC_GPU_TCS0_CMD0_ADDR 0x1544 #define PDC_GPU_TCS0_CMD0_DATA 0x1545 #define PDC_GPU_TCS1_CONTROL 0x1572 #define PDC_GPU_TCS1_CMD_ENABLE_BANK 0x1573 #define PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK 0x1574 #define PDC_GPU_TCS1_CMD0_MSGID 0x1575 #define PDC_GPU_TCS1_CMD0_ADDR 0x1576 #define PDC_GPU_TCS1_CMD0_DATA 0x1577 #define PDC_GPU_TCS2_CONTROL 0x15A4 #define PDC_GPU_TCS2_CMD_ENABLE_BANK 0x15A5 #define PDC_GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK 0x15A6 #define PDC_GPU_TCS2_CMD0_MSGID 0x15A7 #define PDC_GPU_TCS2_CMD0_ADDR 0x15A8 #define PDC_GPU_TCS2_CMD0_DATA 0x15A9 #define PDC_GPU_TCS3_CONTROL 0x15D6 #define PDC_GPU_TCS3_CMD_ENABLE_BANK 0x15D7 #define PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK 0x15D8 #define PDC_GPU_TCS3_CMD0_MSGID 0x15D9 #define PDC_GPU_TCS3_CMD0_ADDR 0x15DA #define PDC_GPU_TCS3_CMD0_DATA 0x15DB /* * Legacy DTSI used an offset from the start of the PDC resource * for PDC SEQ programming. We are now using PDC subsections so * start the PDC SEQ offset at zero. */ #define PDC_GPU_SEQ_MEM_0 0x0 #endif /* _A6XX_REG_H */
drivers/gpu/msm/adreno_a6xx_gmu.c +111 −56 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ #include <linux/firmware.h> #include <linux/jiffies.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/of_platform.h> #include "kgsl_gmu_core.h" #include "kgsl_gmu.h" Loading Loading @@ -79,10 +81,70 @@ static void _regwrite(void __iomem *regbase, * PDC and RSC execute GPU power on/off RPMh sequence * @device: Pointer to KGSL device */ static void _load_gmu_rpmh_ucode(struct kgsl_device *device) static int _load_gmu_rpmh_ucode(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct resource *res_pdc, *res_cfg, *res_seq; void __iomem *cfg = NULL, *seq = NULL; unsigned int cfg_offset, seq_offset; /* Offsets from the base PDC (if no PDC subsections in the DTSI) */ if (adreno_is_a640v2(adreno_dev)) { cfg_offset = 0x90000; seq_offset = 0x290000; } else { cfg_offset = 0x80000; seq_offset = 0x280000; } /* * Older A6x platforms specified PDC registers in the DT using a * single base pointer that encompassed the entire PDC range. Current * targets specify the individual GPU-owned PDC register blocks * (sequence and config). * * This code handles both possibilities and generates individual * pointers to the GPU PDC blocks, either as offsets from the single * base, or as directly specified ranges. */ /* Get pointers to each of the possible PDC resources */ res_pdc = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_reg"); res_cfg = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_cfg"); res_seq = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_pdc_seq"); /* * Map the starting address for pdc_cfg programming. If the pdc_cfg * resource is not available use an offset from the base PDC resource. */ if (res_cfg) cfg = ioremap(res_cfg->start, resource_size(res_cfg)); else if (res_pdc) cfg = ioremap(res_pdc->start + cfg_offset, 0x10000); if (!cfg) { dev_err(&gmu->pdev->dev, "Failed to map PDC CFG\n"); return -ENODEV; } /* * Map the starting address for pdc_seq programming. If the pdc_seq * resource is not available use an offset from the base PDC resource. */ if (res_seq) seq = ioremap(res_seq->start, resource_size(res_seq)); else if (res_pdc) seq = ioremap(res_pdc->start + seq_offset, 0x10000); if (!seq) { dev_err(&gmu->pdev->dev, "Failed to map PDC SEQ\n"); iounmap(cfg); return -ENODEV; } /* Disable SDE clock gating */ gmu_core_regwrite(device, A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24)); Loading Loading @@ -118,68 +180,62 @@ static void _load_gmu_rpmh_ucode(struct kgsl_device *device) gmu_core_regwrite(device, A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020E8A8); /* Load PDC sequencer uCode for power up and power down sequence */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0, 0xFEBEA1E1); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 1, 0xA5A4A3A2); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 2, 0x8382A6E0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 3, 0xBCE3E284); _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_MEM_0 + 4, 0x002081FC); _regwrite(seq, PDC_GPU_SEQ_MEM_0, 0xFEBEA1E1); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 1, 0xA5A4A3A2); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 2, 0x8382A6E0); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 3, 0xBCE3E284); _regwrite(seq, PDC_GPU_SEQ_MEM_0 + 4, 0x002081FC); /* Set TCS commands used by PDC sequence for low power modes */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD_ENABLE_BANK, 7); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CONTROL, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR, 0x30010); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA, 1); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET, 0x0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD_ENABLE_BANK, 7); _regwrite(cfg, PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(cfg, PDC_GPU_TCS1_CONTROL, 0); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR, 0x30010); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA, 1); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET, 0x0); _regwrite(cfg, PDC_GPU_TCS1_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); else _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD_ENABLE_BANK, 7); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CONTROL, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR, 0x30010); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA, 2); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x3); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); _regwrite(cfg, PDC_GPU_TCS1_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(cfg, PDC_GPU_TCS1_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x0); _regwrite(cfg, PDC_GPU_TCS3_CMD_ENABLE_BANK, 7); _regwrite(cfg, PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0); _regwrite(cfg, PDC_GPU_TCS3_CONTROL, 0); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID, 0x10108); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR, 0x30010); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA, 2); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET, 0x10108); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x3); _regwrite(cfg, PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108); if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30090); else _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(gmu->pdc_reg_virt, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x3); _regwrite(cfg, PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET * 2, 0x30080); _regwrite(cfg, PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET * 2, 0x3); /* Setup GPU PDC */ _regwrite(gmu->pdc_reg_virt, PDC_GPU_SEQ_START_ADDR, 0); _regwrite(gmu->pdc_reg_virt, PDC_GPU_ENABLE_PDC, 0x80000001); _regwrite(cfg, PDC_GPU_SEQ_START_ADDR, 0); _regwrite(cfg, PDC_GPU_ENABLE_PDC, 0x80000001); /* ensure no writes happen before the uCode is fully written */ wmb(); iounmap(seq); iounmap(cfg); return 0; } /* GMU timeouts */ Loading Loading @@ -900,12 +956,11 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device, gmu_core_regwrite(device, A6XX_GMU_GENERAL_7, 1); if (!test_and_set_bit(GMU_BOOT_INIT_DONE, &gmu->flags)) _load_gmu_rpmh_ucode(device); else { ret = _load_gmu_rpmh_ucode(device); else ret = a6xx_rpmh_power_on_gpu(device); if (ret) return ret; } if (gmu->load_mode == TCM_BOOT) { /* Load GMU image via AHB bus */ Loading
drivers/gpu/msm/kgsl_gmu.c +14 −32 Original line number Diff line number Diff line Loading @@ -1076,44 +1076,35 @@ static int gmu_pwrlevel_probe(struct gmu_device *gmu, struct device_node *node) return 0; } static int gmu_reg_probe(struct gmu_device *gmu, const char *name, bool is_gmu) static int gmu_reg_probe(struct gmu_device *gmu) { struct resource *res; res = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, name); res = platform_get_resource_byname(gmu->pdev, IORESOURCE_MEM, "kgsl_gmu_reg"); if (res == NULL) { dev_err(&gmu->pdev->dev, "platform_get_resource %s failed\n", name); "platform_get_resource kgsl_gmu_reg failed\n"); return -EINVAL; } if (res->start == 0 || resource_size(res) == 0) { dev_err(&gmu->pdev->dev, "dev %d %s invalid register region\n", gmu->pdev->dev.id, name); "dev %d kgsl_gmu_reg invalid register region\n", gmu->pdev->dev.id); return -EINVAL; } if (is_gmu) { gmu->reg_phys = res->start; gmu->reg_len = resource_size(res); gmu->reg_virt = devm_ioremap(&gmu->pdev->dev, res->start, resource_size(res)); if (gmu->reg_virt == NULL) { dev_err(&gmu->pdev->dev, "GMU regs ioremap failed\n"); dev_err(&gmu->pdev->dev, "kgsl_gmu_reg ioremap failed\n"); return -ENODEV; } } else { gmu->pdc_reg_virt = devm_ioremap(&gmu->pdev->dev, res->start, resource_size(res)); if (gmu->pdc_reg_virt == NULL) { dev_err(&gmu->pdev->dev, "PDC regs ioremap failed\n"); return -ENODEV; } } return 0; } Loading Loading @@ -1314,11 +1305,7 @@ static int gmu_probe(struct kgsl_device *device, mem_addr = gmu->hfi_mem; /* Map and reserve GMU CSRs registers */ ret = gmu_reg_probe(gmu, "kgsl_gmu_reg", true); if (ret) goto error; ret = gmu_reg_probe(gmu, "kgsl_gmu_pdc_reg", false); ret = gmu_reg_probe(gmu); if (ret) goto error; Loading Loading @@ -1740,11 +1727,6 @@ static void gmu_remove(struct kgsl_device *device) gmu->pcl = 0; } if (gmu->pdc_reg_virt) { devm_iounmap(&gmu->pdev->dev, gmu->pdc_reg_virt); gmu->pdc_reg_virt = NULL; } if (gmu->reg_virt) { devm_iounmap(&gmu->pdev->dev, gmu->reg_virt); gmu->reg_virt = NULL; Loading
drivers/gpu/msm/kgsl_gmu.h +0 −2 Original line number Diff line number Diff line Loading @@ -105,7 +105,6 @@ enum gmu_load_mode { * @reg_phys: GMU CSR physical address * @reg_virt: GMU CSR virtual address * @reg_len: GMU CSR range * @pdc_reg_virt: starting kernel virtual address for RPMh PDC registers * @gmu_interrupt_num: GMU interrupt number * @fw_image: descriptor of GMU memory that has GMU image in it * @hfi_mem: pointer to HFI shared memory Loading Loading @@ -142,7 +141,6 @@ struct gmu_device { unsigned long reg_phys; void __iomem *reg_virt; unsigned int reg_len; void __iomem *pdc_reg_virt; unsigned int gmu_interrupt_num; struct gmu_memdesc cached_fw_image; struct gmu_memdesc *fw_image; Loading