void kgsl_pwrctrl_disable(struct kgsl_device *device) { /* Order pwrrail/clk sequence based upon platform */ kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_OFF); }
/* Caller must hold the device mutex. */ void kgsl_pwrctrl_wake(struct kgsl_device *device) { if (device->state == KGSL_STATE_SUSPEND) return; if (device->state != KGSL_STATE_NAP) { kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrscale_wake(device); } /* Turn on the core clocks */ kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON); /* Enable state before turning on irq */ device->state = KGSL_STATE_ACTIVE; KGSL_PWR_WARN(device, "state -> ACTIVE, device %d\n", device->id); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* Re-enable HW access */ mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); wake_lock(&device->idle_wakelock); pm_qos_update_request(&device->pm_qos_req_dma, GPU_SWFI_LATENCY); KGSL_PWR_INFO(device, "wake return for device %d\n", device->id); }
static int _sleep(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; switch (device->state) { case KGSL_STATE_ACTIVE: if (!device->ftbl->isidle(device)) { kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); return -EBUSY; } /* fall through */ case KGSL_STATE_NAP: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); if (pwr->pwrlevels[0].gpu_freq > 0) clk_set_rate(pwr->grp_clks[0], pwr->pwrlevels[pwr->num_pwrlevels - 1]. gpu_freq); _sleep_accounting(device); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP); if (device->idle_wakelock.name) wake_unlock(&device->idle_wakelock); break; case KGSL_STATE_SLEEP: case KGSL_STATE_SLUMBER: break; default: KGSL_PWR_WARN(device, "unhandled state %s\n", kgsl_pwrstate_to_str(device->state)); break; } return 0; }
void kgsl_pwrctrl_enable(struct kgsl_device *device) { /* Order pwrrail/clk sequence based upon platform */ kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); }
/* Caller must hold the device mutex. */ int kgsl_pwrctrl_wake(struct kgsl_device *device) { int status = KGSL_SUCCESS; struct kgsl_pwrctrl *pwr = &device->pwrctrl; BUG_ON(!mutex_is_locked(&device->mutex)); if (device->state == KGSL_STATE_SUSPEND) return status; KGSL_DRV_INFO("GRP_CLK= %lu BUS CLK= %lu\n", kgsl_get_clkrate(pwr->grp_clk), kgsl_get_clkrate(pwr->ebi1_clk)); /* Turn on the core clocks */ status = kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_CLK_ON); if (device->state != KGSL_STATE_NAP) { kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_AXI_ON); } /* Enable state before turning on irq */ device->state = KGSL_STATE_ACTIVE; KGSL_DRV_WARN("state -> ACTIVE, device %d\n", device->id); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_IRQ_ON); /* Re-enable HW access */ mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT); KGSL_DRV_VDBG("<-- kgsl_yamato_wake(). Return value %d\n", status); wake_lock(&device->idle_wakelock); return status; }
/* Caller must hold the device mutex. */ int kgsl_pwrctrl_sleep(struct kgsl_device *device) { KGSL_DRV_DBG("kgsl_pwrctrl_sleep device %d!!!\n", device->id); /* Work through the legal state transitions */ if (device->requested_state == KGSL_STATE_NAP) { if (device->ftbl.device_isidle(device)) goto nap; } else if (device->requested_state == KGSL_STATE_SLEEP) { if (device->state == KGSL_STATE_NAP || device->ftbl.device_isidle(device)) goto sleep; } device->requested_state = KGSL_STATE_NONE; return KGSL_FAILURE; sleep: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_IRQ_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_AXI_OFF); goto clk_off; nap: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_IRQ_OFF); clk_off: kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_CLK_OFF); device->state = device->requested_state; device->requested_state = KGSL_STATE_NONE; wake_unlock(&device->idle_wakelock); return KGSL_SUCCESS; }
/* Caller must hold the device mutex. */ int kgsl_pwrctrl_sleep(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_pwrctrl *pwr = &device->pwrctrl; KGSL_PWR_INFO(device, "sleep device %d\n", device->id); /* Work through the legal state transitions */ if (device->requested_state == KGSL_STATE_NAP) { if (device->ftbl->isidle(device)) goto nap; } else if (device->requested_state == KGSL_STATE_SLEEP) { if (device->state == KGSL_STATE_NAP || device->ftbl->isidle(device)) goto sleep; } device->requested_state = KGSL_STATE_NONE; return -EBUSY; sleep: device->ftbl->suspend_context(device); device->ftbl->stop(device); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); if (pwr->pwrlevels[0].gpu_freq > 0) clk_set_rate(pwr->grp_clks[0], pwr->pwrlevels[pwr->num_pwrlevels - 1]. gpu_freq); device->pwrctrl.time = 0; kgsl_pwrscale_sleep(device); goto clk_off; nap: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); clk_off: kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF); device->state = device->requested_state; device->requested_state = KGSL_STATE_NONE; wake_unlock(&device->idle_wakelock); pm_qos_update_request(&device->pm_qos_req_dma, PM_QOS_DEFAULT_VALUE); KGSL_PWR_WARN(device, "state -> NAP/SLEEP(%d), device %d ts 0x%x\n", device->state, device->id, adreno_dev->ringbuffer.timestamp); return 0; }
/* Caller must hold the device mutex. */ int kgsl_pwrctrl_sleep(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; KGSL_PWR_INFO(device, "sleep device %d\n", device->id); /* Work through the legal state transitions */ if (device->requested_state == KGSL_STATE_NAP) { if (device->ftbl->isidle(device)) goto nap; } else if (device->requested_state == KGSL_STATE_SLEEP) { if (device->state == KGSL_STATE_NAP || device->ftbl->isidle(device)) goto sleep; } device->requested_state = KGSL_STATE_NONE; return -EBUSY; sleep: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF); if (pwr->pwrlevels[0].gpu_freq > 0) clk_set_rate(pwr->grp_clks[0], pwr->pwrlevels[pwr->num_pwrlevels - 1]. gpu_freq); kgsl_pwrctrl_busy_time(device, false); pwr->busy.start.tv_sec = 0; device->pwrctrl.time = 0; kgsl_pwrscale_sleep(device); goto clk_off; nap: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); clk_off: kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF); device->state = device->requested_state; device->requested_state = KGSL_STATE_NONE; wake_unlock(&device->idle_wakelock); // pm_qos_update_request(PM_QOS_CPU_DMA_LATENCY, // PM_QOS_DEFAULT_VALUE); KGSL_PWR_WARN(device, "state -> NAP/SLEEP(%d), device %d\n", device->state, device->id); return 0; }
/* Caller must hold the device mutex. */ int kgsl_pwrctrl_sleep(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; KGSL_DRV_INFO("device %d, current state= %d, resquested change= %d!!\n", device->id, device->state, device->requested_state); KGSL_DRV_INFO("GRP_CLK= %lu BUS CLK= %lu\n", kgsl_get_clkrate(pwr->grp_clk), kgsl_get_clkrate(pwr->ebi1_clk)); /* Work through the legal state transitions */ if (device->requested_state == KGSL_STATE_NAP) { if (device->ftbl.device_isidle(device)) goto nap; } else if (device->requested_state == KGSL_STATE_SLEEP) { if (device->state == KGSL_STATE_NAP || device->ftbl.device_isidle(device)) goto sleep; } device->requested_state = KGSL_STATE_NONE; return KGSL_FAILURE; sleep: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_IRQ_OFF); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_AXI_OFF); goto clk_off; nap: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_IRQ_OFF); clk_off: kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_CLK_OFF); device->state = device->requested_state; device->requested_state = KGSL_STATE_NONE; wake_unlock(&device->idle_wakelock); KGSL_DRV_WARN("state -> NAP/SLEEP(%d), device %d\n", device->state, device->id); return KGSL_SUCCESS; }
/* Caller must hold the device mutex. */ void kgsl_pwrctrl_wake(struct kgsl_device *device) { int status; kgsl_pwrctrl_request_state(device, KGSL_STATE_ACTIVE); switch (device->state) { case KGSL_STATE_SLUMBER: status = device->ftbl->start(device, 0); if (status) { kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); KGSL_DRV_ERR(device, "start failed %d\n", status); break; } /* fall through */ case KGSL_STATE_SLEEP: kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrscale_wake(device); /* fall through */ case KGSL_STATE_NAP: /* Turn on the core clocks */ kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE); /* Enable state before turning on irq */ kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* Re-enable HW access */ mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); if (device->idle_wakelock.name) wake_lock(&device->idle_wakelock); case KGSL_STATE_ACTIVE: kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); break; default: KGSL_PWR_WARN(device, "unhandled state %s\n", kgsl_pwrstate_to_str(device->state)); kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); break; } }
/* Caller must hold the device mutex. */ void kgsl_pwrctrl_wake(struct kgsl_device *device) { int status; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); if (device->state == KGSL_STATE_SUSPEND) return; if (device->state == KGSL_STATE_SLEEP) { device->requested_state = KGSL_STATE_ACTIVE; status = device->ftbl->start(device, 0); if (status != 0) { KGSL_DRV_ERR(device, "start failed %d\n", status); return; } } if (device->state != KGSL_STATE_NAP) { kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrscale_wake(device); } /* Turn on the core clocks */ kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON); /* Enable state before turning on irq */ device->state = KGSL_STATE_ACTIVE; KGSL_PWR_WARN(device, "state -> ACTIVE, device %d ts 0x%x\n", device->id, adreno_dev->ringbuffer.timestamp); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* Re-enable HW access */ mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); wake_lock(&device->idle_wakelock); pm_qos_update_request(&device->pm_qos_req_dma, GPU_SWFI_LATENCY); KGSL_PWR_INFO(device, "wake return for device %d\n", device->id); }
static int _nap(struct kgsl_device *device) { switch (device->state) { case KGSL_STATE_ACTIVE: if (!device->ftbl->isidle(device)) { kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); return -EBUSY; } kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF); kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP); if (device->idle_wakelock.name) wake_unlock(&device->idle_wakelock); case KGSL_STATE_NAP: case KGSL_STATE_SLEEP: case KGSL_STATE_SLUMBER: break; default: kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); break; } return 0; }