Loading Documentation/devicetree/bindings/media/video/msm-vidc.txt +10 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ Optional properties: supports hevc decoder = 0x0c000000 supports hevc_hybrid encoder = 0x10000000 supports hevc_hybrid decoder = 0x30000000 - qcom,imem-ab-tbl : video core frequency in Hz and corresponding imem ab value in kbps. The imem ab value corresponds to the clock frequency at which imem should operate for a particular video core frequency. - qcom,reg-presets : list of offset-value pairs for registers to be written. The offsets are from the base offset specified in 'reg'. This is mainly used for QoS, VBIF, etc. presets for video. Loading Loading @@ -153,6 +156,13 @@ Example: <72000 133330000 0x0c000000>, /* HEVC decoder VGA 60fps */ <36000 133330000 0x0c000000>, /* HEVC VGA 30 fps */ <36000 133330000 0x01000414>; /* Legacy encoder VGA 30 fps */ qcom,imem-ab-tbl = <75000000 1500000>, /* imem clk @ 75 Mhz */ <150000000 1500000>, /* imem clk @ 75 Mhz */ <355333333 2500000>, /* imem clk @ 170 Mhz */ <533000000 6000000>; /* imem clk @ 320 Mhz */ qcom,imem-size = <4096>; qcom,firmware-name = "venus"; qcom,hfi-version = "3xx"; Loading drivers/media/platform/msm/vidc/governors/msm_vidc_bw_gov.c +73 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ module_param(debug, bool, 0644); enum governor_mode { GOVERNOR_DDR, GOVERNOR_VMEM, GOVERNOR_VMEM_PLUS, }; struct governor { Loading Loading @@ -274,6 +275,36 @@ static int __bpp(enum hal_uncompressed_format f) } } static unsigned long __calculate_vmem_plus_ab(struct vidc_bus_vote_data *d) { unsigned long i = 0, vmem_plus = 0; if (!d->imem_ab_tbl || !d->imem_ab_tbl_size) { vmem_plus = 1; /* Vote for the min ab value */ goto exit; } /* Pick up vmem frequency based on venus core frequency */ for (i = 0; i < d->imem_ab_tbl_size; i++) { if (d->imem_ab_tbl[i].core_freq == d->core_freq) { vmem_plus = d->imem_ab_tbl[i].imem_ab; break; } } /* Incase we get an unsupported freq throw a warning * and set ab to the minimum value. */ if (!vmem_plus) { vmem_plus = 1; dprintk(VIDC_WARN, "could not calculate vmem ab value due to core freq mismatch\n"); WARN_ON(1); } exit: return vmem_plus; } static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, enum governor_mode gm) { /* Loading Loading @@ -308,6 +339,8 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, total; } ddr, vmem; unsigned long ret = 0; /* Decoder parameters setup */ scenario = SCENARIO_WORST; Loading Loading @@ -573,7 +606,21 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } return kbps(fp_round((gm == GOVERNOR_DDR ? &ddr : &vmem)->total)); switch (gm) { case GOVERNOR_DDR: ret = kbps(fp_round(ddr.total)); break; case GOVERNOR_VMEM: ret = kbps(fp_round(vmem.total)); break; case GOVERNOR_VMEM_PLUS: ret = __calculate_vmem_plus_ab(d); break; default: dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); } return ret; } static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, Loading Loading @@ -620,6 +667,8 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, original_write, dpb_read, dpb_write, total; } ddr, vmem; unsigned long ret = 0; /* Encoder Parameters setup */ scenario = SCENARIO_WORST; Loading Loading @@ -961,7 +1010,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } return kbps(fp_round((gm == GOVERNOR_DDR ? &ddr : &vmem)->total)); switch (gm) { case GOVERNOR_DDR: ret = kbps(fp_round(ddr.total)); break; case GOVERNOR_VMEM: ret = kbps(fp_round(vmem.total)); break; case GOVERNOR_VMEM_PLUS: ret = __calculate_vmem_plus_ab(d); break; default: dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); } return ret; } static unsigned long __calculate(struct vidc_bus_vote_data *d, Loading Loading @@ -1046,7 +1109,14 @@ static struct governor governors[] = { .event_handler = __event_handler, }, }, { .mode = GOVERNOR_VMEM_PLUS, .devfreq_gov = { .name = "msm-vidc-vmem+", .get_target_freq = __get_target_freq, .event_handler = __event_handler, }, }, }; static int __init msm_vidc_bw_gov_init(void) Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +11 −1 Original line number Diff line number Diff line Loading @@ -297,6 +297,7 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) struct hfi_device *hdev; struct msm_vidc_inst *inst = NULL; struct vidc_bus_vote_data *vote_data = NULL; unsigned long core_freq = 0; if (!core) { dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); Loading @@ -322,6 +323,9 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) goto fail_alloc; } core_freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 0); list_for_each_entry(inst, &core->instances, list) { int codec = 0, yuv = 0; Loading @@ -344,6 +348,12 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) vote_data[i].power_mode = VIDC_POWER_LOW; else vote_data[i].power_mode = VIDC_POWER_NORMAL; if (i == 0) { vote_data[i].imem_ab_tbl = core->resources.imem_ab_tbl; vote_data[i].imem_ab_tbl_size = core->resources.imem_ab_tbl_size; vote_data[i].core_freq = core_freq; } /* * TODO: support for OBP-DBP split mode hasn't been yet Loading Loading @@ -1984,7 +1994,7 @@ static unsigned long msm_comm_get_clock_rate(struct msm_vidc_core *core) } hdev = core->device; freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data); freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 1); dprintk(VIDC_DBG, "clock freq %ld\n", freq); return freq; Loading drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +48 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,12 @@ static inline void msm_vidc_free_freq_table( res->load_freq_tbl = NULL; } static inline void msm_vidc_free_imem_ab_table( struct msm_vidc_platform_resources *res) { res->imem_ab_tbl = NULL; } static inline void msm_vidc_free_reg_table( struct msm_vidc_platform_resources *res) { Loading Loading @@ -227,6 +233,44 @@ err_qdss_addr_tbl: return rc; } static int msm_vidc_load_imem_ab_table(struct msm_vidc_platform_resources *res) { int num_elements = 0; struct platform_device *pdev = res->pdev; if (!of_find_property(pdev->dev.of_node, "qcom,imem-ab-tbl", NULL)) { /* optional property */ dprintk(VIDC_DBG, "qcom,imem-freq-tbl not found\n"); return 0; } num_elements = get_u32_array_num_elements(pdev, "qcom,imem-ab-tbl"); num_elements /= (sizeof(*res->imem_ab_tbl) / sizeof(u32)); if (!num_elements) { dprintk(VIDC_ERR, "no elements in imem ab table\n"); return -EINVAL; } res->imem_ab_tbl = devm_kzalloc(&pdev->dev, num_elements * sizeof(*res->imem_ab_tbl), GFP_KERNEL); if (!res->imem_ab_tbl) { dprintk(VIDC_ERR, "Failed to alloc imem_ab_tbl\n"); return -ENOMEM; } if (of_property_read_u32_array(pdev->dev.of_node, "qcom,imem-ab-tbl", (u32 *)res->imem_ab_tbl, num_elements * sizeof(*res->imem_ab_tbl) / sizeof(u32))) { dprintk(VIDC_ERR, "Failed to read imem_ab_tbl\n"); msm_vidc_free_imem_ab_table(res); return -EINVAL; } res->imem_ab_tbl_size = num_elements; return 0; } static int msm_vidc_load_freq_table(struct msm_vidc_platform_resources *res) { int rc = 0; Loading Loading @@ -630,6 +674,10 @@ int read_platform_resources_from_dt( goto err_load_freq_table; } rc = msm_vidc_load_imem_ab_table(res); if (rc) dprintk(VIDC_WARN, "Failed to load freq table: %d\n", rc); rc = msm_vidc_load_qdss_table(res); if (rc) dprintk(VIDC_WARN, "Failed to load qdss reg table: %d\n", rc); Loading drivers/media/platform/msm/vidc/msm_vidc_resources.h +7 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,11 @@ struct load_freq_table { u32 supported_codecs; }; struct imem_ab_table { u32 core_freq; u32 imem_ab; }; struct reg_value_pair { u32 reg; u32 value; Loading Loading @@ -121,6 +126,8 @@ struct msm_vidc_platform_resources { uint32_t irq; struct load_freq_table *load_freq_tbl; uint32_t load_freq_tbl_size; struct imem_ab_table *imem_ab_tbl; u32 imem_ab_tbl_size; struct reg_set reg_set; struct addr_set qdss_addr_set; struct buffer_usage_set buffer_usage_set; Loading Loading
Documentation/devicetree/bindings/media/video/msm-vidc.txt +10 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ Optional properties: supports hevc decoder = 0x0c000000 supports hevc_hybrid encoder = 0x10000000 supports hevc_hybrid decoder = 0x30000000 - qcom,imem-ab-tbl : video core frequency in Hz and corresponding imem ab value in kbps. The imem ab value corresponds to the clock frequency at which imem should operate for a particular video core frequency. - qcom,reg-presets : list of offset-value pairs for registers to be written. The offsets are from the base offset specified in 'reg'. This is mainly used for QoS, VBIF, etc. presets for video. Loading Loading @@ -153,6 +156,13 @@ Example: <72000 133330000 0x0c000000>, /* HEVC decoder VGA 60fps */ <36000 133330000 0x0c000000>, /* HEVC VGA 30 fps */ <36000 133330000 0x01000414>; /* Legacy encoder VGA 30 fps */ qcom,imem-ab-tbl = <75000000 1500000>, /* imem clk @ 75 Mhz */ <150000000 1500000>, /* imem clk @ 75 Mhz */ <355333333 2500000>, /* imem clk @ 170 Mhz */ <533000000 6000000>; /* imem clk @ 320 Mhz */ qcom,imem-size = <4096>; qcom,firmware-name = "venus"; qcom,hfi-version = "3xx"; Loading
drivers/media/platform/msm/vidc/governors/msm_vidc_bw_gov.c +73 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ module_param(debug, bool, 0644); enum governor_mode { GOVERNOR_DDR, GOVERNOR_VMEM, GOVERNOR_VMEM_PLUS, }; struct governor { Loading Loading @@ -274,6 +275,36 @@ static int __bpp(enum hal_uncompressed_format f) } } static unsigned long __calculate_vmem_plus_ab(struct vidc_bus_vote_data *d) { unsigned long i = 0, vmem_plus = 0; if (!d->imem_ab_tbl || !d->imem_ab_tbl_size) { vmem_plus = 1; /* Vote for the min ab value */ goto exit; } /* Pick up vmem frequency based on venus core frequency */ for (i = 0; i < d->imem_ab_tbl_size; i++) { if (d->imem_ab_tbl[i].core_freq == d->core_freq) { vmem_plus = d->imem_ab_tbl[i].imem_ab; break; } } /* Incase we get an unsupported freq throw a warning * and set ab to the minimum value. */ if (!vmem_plus) { vmem_plus = 1; dprintk(VIDC_WARN, "could not calculate vmem ab value due to core freq mismatch\n"); WARN_ON(1); } exit: return vmem_plus; } static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, enum governor_mode gm) { /* Loading Loading @@ -308,6 +339,8 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, total; } ddr, vmem; unsigned long ret = 0; /* Decoder parameters setup */ scenario = SCENARIO_WORST; Loading Loading @@ -573,7 +606,21 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } return kbps(fp_round((gm == GOVERNOR_DDR ? &ddr : &vmem)->total)); switch (gm) { case GOVERNOR_DDR: ret = kbps(fp_round(ddr.total)); break; case GOVERNOR_VMEM: ret = kbps(fp_round(vmem.total)); break; case GOVERNOR_VMEM_PLUS: ret = __calculate_vmem_plus_ab(d); break; default: dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); } return ret; } static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, Loading Loading @@ -620,6 +667,8 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, original_write, dpb_read, dpb_write, total; } ddr, vmem; unsigned long ret = 0; /* Encoder Parameters setup */ scenario = SCENARIO_WORST; Loading Loading @@ -961,7 +1010,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } return kbps(fp_round((gm == GOVERNOR_DDR ? &ddr : &vmem)->total)); switch (gm) { case GOVERNOR_DDR: ret = kbps(fp_round(ddr.total)); break; case GOVERNOR_VMEM: ret = kbps(fp_round(vmem.total)); break; case GOVERNOR_VMEM_PLUS: ret = __calculate_vmem_plus_ab(d); break; default: dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); } return ret; } static unsigned long __calculate(struct vidc_bus_vote_data *d, Loading Loading @@ -1046,7 +1109,14 @@ static struct governor governors[] = { .event_handler = __event_handler, }, }, { .mode = GOVERNOR_VMEM_PLUS, .devfreq_gov = { .name = "msm-vidc-vmem+", .get_target_freq = __get_target_freq, .event_handler = __event_handler, }, }, }; static int __init msm_vidc_bw_gov_init(void) Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +11 −1 Original line number Diff line number Diff line Loading @@ -297,6 +297,7 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) struct hfi_device *hdev; struct msm_vidc_inst *inst = NULL; struct vidc_bus_vote_data *vote_data = NULL; unsigned long core_freq = 0; if (!core) { dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); Loading @@ -322,6 +323,9 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) goto fail_alloc; } core_freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 0); list_for_each_entry(inst, &core->instances, list) { int codec = 0, yuv = 0; Loading @@ -344,6 +348,12 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) vote_data[i].power_mode = VIDC_POWER_LOW; else vote_data[i].power_mode = VIDC_POWER_NORMAL; if (i == 0) { vote_data[i].imem_ab_tbl = core->resources.imem_ab_tbl; vote_data[i].imem_ab_tbl_size = core->resources.imem_ab_tbl_size; vote_data[i].core_freq = core_freq; } /* * TODO: support for OBP-DBP split mode hasn't been yet Loading Loading @@ -1984,7 +1994,7 @@ static unsigned long msm_comm_get_clock_rate(struct msm_vidc_core *core) } hdev = core->device; freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data); freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 1); dprintk(VIDC_DBG, "clock freq %ld\n", freq); return freq; Loading
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +48 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,12 @@ static inline void msm_vidc_free_freq_table( res->load_freq_tbl = NULL; } static inline void msm_vidc_free_imem_ab_table( struct msm_vidc_platform_resources *res) { res->imem_ab_tbl = NULL; } static inline void msm_vidc_free_reg_table( struct msm_vidc_platform_resources *res) { Loading Loading @@ -227,6 +233,44 @@ err_qdss_addr_tbl: return rc; } static int msm_vidc_load_imem_ab_table(struct msm_vidc_platform_resources *res) { int num_elements = 0; struct platform_device *pdev = res->pdev; if (!of_find_property(pdev->dev.of_node, "qcom,imem-ab-tbl", NULL)) { /* optional property */ dprintk(VIDC_DBG, "qcom,imem-freq-tbl not found\n"); return 0; } num_elements = get_u32_array_num_elements(pdev, "qcom,imem-ab-tbl"); num_elements /= (sizeof(*res->imem_ab_tbl) / sizeof(u32)); if (!num_elements) { dprintk(VIDC_ERR, "no elements in imem ab table\n"); return -EINVAL; } res->imem_ab_tbl = devm_kzalloc(&pdev->dev, num_elements * sizeof(*res->imem_ab_tbl), GFP_KERNEL); if (!res->imem_ab_tbl) { dprintk(VIDC_ERR, "Failed to alloc imem_ab_tbl\n"); return -ENOMEM; } if (of_property_read_u32_array(pdev->dev.of_node, "qcom,imem-ab-tbl", (u32 *)res->imem_ab_tbl, num_elements * sizeof(*res->imem_ab_tbl) / sizeof(u32))) { dprintk(VIDC_ERR, "Failed to read imem_ab_tbl\n"); msm_vidc_free_imem_ab_table(res); return -EINVAL; } res->imem_ab_tbl_size = num_elements; return 0; } static int msm_vidc_load_freq_table(struct msm_vidc_platform_resources *res) { int rc = 0; Loading Loading @@ -630,6 +674,10 @@ int read_platform_resources_from_dt( goto err_load_freq_table; } rc = msm_vidc_load_imem_ab_table(res); if (rc) dprintk(VIDC_WARN, "Failed to load freq table: %d\n", rc); rc = msm_vidc_load_qdss_table(res); if (rc) dprintk(VIDC_WARN, "Failed to load qdss reg table: %d\n", rc); Loading
drivers/media/platform/msm/vidc/msm_vidc_resources.h +7 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,11 @@ struct load_freq_table { u32 supported_codecs; }; struct imem_ab_table { u32 core_freq; u32 imem_ab; }; struct reg_value_pair { u32 reg; u32 value; Loading Loading @@ -121,6 +126,8 @@ struct msm_vidc_platform_resources { uint32_t irq; struct load_freq_table *load_freq_tbl; uint32_t load_freq_tbl_size; struct imem_ab_table *imem_ab_tbl; u32 imem_ab_tbl_size; struct reg_set reg_set; struct addr_set qdss_addr_set; struct buffer_usage_set buffer_usage_set; Loading