Loading Documentation/devicetree/bindings/gpu/adreno.txt +7 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,13 @@ Bus Scaling Data: ab: Represents aggregated bandwidth. This value is 0 for Graphics. ib: Represents instantaneous bandwidth. This value has a range <0 8000 MB/s> - qcom,ocmem-bus-client: Container for another set of bus scaling properties qcom,msm-bus,name qcom,msm-bus,num-cases qcom,msm-bus,num-paths qcom,msm-bus,vectors-KBps to be used by ocmem msm bus scaling client. GDSC Oxili Regulators: - vddcx-supply: Phandle for vddcx regulator device node. - vdd-supply: Phandle for vdd regulator device node. Loading drivers/gpu/msm/kgsl_pwrctrl.c +50 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/msm-bus-board.h> #include <linux/ktime.h> #include <linux/delay.h> #include <linux/msm_adreno_devfreq.h> #include "kgsl.h" #include "kgsl_pwrscale.h" Loading @@ -45,6 +46,8 @@ /* Number of jiffies for a full thermal cycle */ #define TH_HZ 20 #define KGSL_MAX_BUSLEVELS 20 struct clk_pair { const char *name; uint map; Loading Loading @@ -89,6 +92,9 @@ static struct clk_pair clks[KGSL_MAX_CLKS] = { }, }; static unsigned int ib_votes[KGSL_MAX_BUSLEVELS]; static int last_vote_buslevel; static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, int requested_state); static void kgsl_pwrctrl_axi(struct kgsl_device *device, int state); Loading @@ -98,6 +104,14 @@ static void kgsl_pwrctrl_set_state(struct kgsl_device *device, static void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state); /** * kgsl_get_bw() - Return latest msm bus IB vote */ static unsigned int kgsl_get_bw(void) { return ib_votes[last_vote_buslevel]; } /** * _adjust_pwrlevel() - Given a requested power level do bounds checking on the * constraints and return the nearest possible level Loading Loading @@ -168,8 +182,12 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device, /* If the bus is being turned off, reset to default level */ pwr->bus_mod = 0; } msm_bus_scale_client_update_request(pwr->pcl, buslevel); trace_kgsl_buslevel(device, pwr->active_pwrlevel, buslevel); last_vote_buslevel = buslevel; /* vote for ocmem */ msm_bus_scale_client_update_request(pwr->pcl, buslevel); /* ask a governor to vote on behalf of us */ devfreq_vbif_update_bw(); } EXPORT_SYMBOL(kgsl_pwrctrl_buslevel_update); Loading Loading @@ -1190,6 +1208,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) struct platform_device *pdev = device->pdev; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_device_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *ocmem_bus_node; struct msm_bus_scale_pdata *ocmem_scale_table = NULL; /*acquire clocks */ for (i = 0; i < KGSL_MAX_CLKS; i++) { Loading Loading @@ -1277,13 +1297,26 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (pdata->bus_scale_table == NULL) return result; pwr->pcl = msm_bus_scale_register_client(pdata-> bus_scale_table); ocmem_bus_node = of_find_node_by_name( device->pdev->dev.of_node, "qcom,ocmem-bus-client"); /* If platform has splitted ocmem bus client - use it */ if (ocmem_bus_node) { ocmem_scale_table = msm_bus_pdata_from_node (device->pdev, ocmem_bus_node); if (ocmem_scale_table) pwr->pcl = msm_bus_scale_register_client (ocmem_scale_table); } else pwr->pcl = msm_bus_scale_register_client (pdata->bus_scale_table); if (!pwr->pcl) { KGSL_PWR_ERR(device, "msm_bus_scale_register_client failed: " "id %d table %p", device->id, pdata->bus_scale_table); "id %d table %p %p", device->id, pdata->bus_scale_table, ocmem_scale_table); result = -EINVAL; goto done; } Loading Loading @@ -1311,6 +1344,16 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) struct msm_bus_vectors *vector = &usecase->vectors[0]; if (vector->dst == MSM_BUS_SLAVE_EBI_CH0 && vector->ib != 0) { if (i < KGSL_MAX_BUSLEVELS) /* * Want to convert bytes to Mbytes, * but msm_bus_of.c uses a strange macro * #define KBTOB(a) (a * 1000ULL) * thats why 1024*1000, not 1024*1024 */ ib_votes[i] = DIV_ROUND_UP_ULL(vector->ib, 1024000); for (k = 0; k < n; k++) if (vector->ib == pwr->bus_ib[k]) { static uint64_t last_ib = 0xFFFFFFFF; Loading Loading @@ -1350,6 +1393,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) setup_timer(&pwr->thermal_timer, kgsl_thermal_timer, (unsigned long) device); devfreq_vbif_register_callback(kgsl_get_bw); return result; clk_err: Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +7 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,13 @@ Bus Scaling Data: ab: Represents aggregated bandwidth. This value is 0 for Graphics. ib: Represents instantaneous bandwidth. This value has a range <0 8000 MB/s> - qcom,ocmem-bus-client: Container for another set of bus scaling properties qcom,msm-bus,name qcom,msm-bus,num-cases qcom,msm-bus,num-paths qcom,msm-bus,vectors-KBps to be used by ocmem msm bus scaling client. GDSC Oxili Regulators: - vddcx-supply: Phandle for vddcx regulator device node. - vdd-supply: Phandle for vdd regulator device node. Loading
drivers/gpu/msm/kgsl_pwrctrl.c +50 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/msm-bus-board.h> #include <linux/ktime.h> #include <linux/delay.h> #include <linux/msm_adreno_devfreq.h> #include "kgsl.h" #include "kgsl_pwrscale.h" Loading @@ -45,6 +46,8 @@ /* Number of jiffies for a full thermal cycle */ #define TH_HZ 20 #define KGSL_MAX_BUSLEVELS 20 struct clk_pair { const char *name; uint map; Loading Loading @@ -89,6 +92,9 @@ static struct clk_pair clks[KGSL_MAX_CLKS] = { }, }; static unsigned int ib_votes[KGSL_MAX_BUSLEVELS]; static int last_vote_buslevel; static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, int requested_state); static void kgsl_pwrctrl_axi(struct kgsl_device *device, int state); Loading @@ -98,6 +104,14 @@ static void kgsl_pwrctrl_set_state(struct kgsl_device *device, static void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state); /** * kgsl_get_bw() - Return latest msm bus IB vote */ static unsigned int kgsl_get_bw(void) { return ib_votes[last_vote_buslevel]; } /** * _adjust_pwrlevel() - Given a requested power level do bounds checking on the * constraints and return the nearest possible level Loading Loading @@ -168,8 +182,12 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device, /* If the bus is being turned off, reset to default level */ pwr->bus_mod = 0; } msm_bus_scale_client_update_request(pwr->pcl, buslevel); trace_kgsl_buslevel(device, pwr->active_pwrlevel, buslevel); last_vote_buslevel = buslevel; /* vote for ocmem */ msm_bus_scale_client_update_request(pwr->pcl, buslevel); /* ask a governor to vote on behalf of us */ devfreq_vbif_update_bw(); } EXPORT_SYMBOL(kgsl_pwrctrl_buslevel_update); Loading Loading @@ -1190,6 +1208,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) struct platform_device *pdev = device->pdev; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_device_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *ocmem_bus_node; struct msm_bus_scale_pdata *ocmem_scale_table = NULL; /*acquire clocks */ for (i = 0; i < KGSL_MAX_CLKS; i++) { Loading Loading @@ -1277,13 +1297,26 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (pdata->bus_scale_table == NULL) return result; pwr->pcl = msm_bus_scale_register_client(pdata-> bus_scale_table); ocmem_bus_node = of_find_node_by_name( device->pdev->dev.of_node, "qcom,ocmem-bus-client"); /* If platform has splitted ocmem bus client - use it */ if (ocmem_bus_node) { ocmem_scale_table = msm_bus_pdata_from_node (device->pdev, ocmem_bus_node); if (ocmem_scale_table) pwr->pcl = msm_bus_scale_register_client (ocmem_scale_table); } else pwr->pcl = msm_bus_scale_register_client (pdata->bus_scale_table); if (!pwr->pcl) { KGSL_PWR_ERR(device, "msm_bus_scale_register_client failed: " "id %d table %p", device->id, pdata->bus_scale_table); "id %d table %p %p", device->id, pdata->bus_scale_table, ocmem_scale_table); result = -EINVAL; goto done; } Loading Loading @@ -1311,6 +1344,16 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) struct msm_bus_vectors *vector = &usecase->vectors[0]; if (vector->dst == MSM_BUS_SLAVE_EBI_CH0 && vector->ib != 0) { if (i < KGSL_MAX_BUSLEVELS) /* * Want to convert bytes to Mbytes, * but msm_bus_of.c uses a strange macro * #define KBTOB(a) (a * 1000ULL) * thats why 1024*1000, not 1024*1024 */ ib_votes[i] = DIV_ROUND_UP_ULL(vector->ib, 1024000); for (k = 0; k < n; k++) if (vector->ib == pwr->bus_ib[k]) { static uint64_t last_ib = 0xFFFFFFFF; Loading Loading @@ -1350,6 +1393,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) setup_timer(&pwr->thermal_timer, kgsl_thermal_timer, (unsigned long) device); devfreq_vbif_register_callback(kgsl_get_bw); return result; clk_err: Loading