void nvhost_scale_emc_callback(struct nvhost_device_profile *profile, unsigned long freq) { struct nvhost_gr3d_params *gr3d_params = profile->private_data; struct nvhost_emc_params *emc_params = &gr3d_params->emc_params; long hz; long after; /* Set EMC clockrate */ after = (long) clk_get_rate(clk(profile, gr3d_params->clk_3d)); hz = nvhost_scale_emc_get_emc_rate(emc_params, after); nvhost_module_set_rate(profile->pdev, gr3d_params, hz, gr3d_params->clk_3d_emc, NVHOST_CLOCK); }
static long nvhost_channelctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct nvhost_channel_userctx *priv = filp->private_data; u8 buf[NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE]; int err = 0; if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) || (_IOC_NR(cmd) == 0) || (_IOC_NR(cmd) > NVHOST_IOCTL_CHANNEL_LAST)) return -EFAULT; BUG_ON(_IOC_SIZE(cmd) > NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE); if (_IOC_DIR(cmd) & _IOC_WRITE) { if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; } switch (cmd) { case NVHOST_IOCTL_CHANNEL_FLUSH: err = nvhost_ioctl_channel_flush(priv, (void *)buf, 0); break; case NVHOST_IOCTL_CHANNEL_NULL_KICKOFF: err = nvhost_ioctl_channel_flush(priv, (void *)buf, 1); break; case NVHOST_IOCTL_CHANNEL_SUBMIT_EXT: { struct nvhost_submit_hdr_ext *hdr; if (priv->hdr.num_relocs || priv->num_relocshifts || priv->hdr.num_cmdbufs || priv->hdr.num_waitchks) { reset_submit(priv); dev_err(&priv->ch->dev->pdev->dev, "channel submit out of sync\n"); err = -EIO; break; } hdr = (struct nvhost_submit_hdr_ext *)buf; if (hdr->submit_version > NVHOST_SUBMIT_VERSION_MAX_SUPPORTED) { dev_err(&priv->ch->dev->pdev->dev, "submit version %d > max supported %d\n", hdr->submit_version, NVHOST_SUBMIT_VERSION_MAX_SUPPORTED); err = -EINVAL; break; } memcpy(&priv->hdr, hdr, sizeof(struct nvhost_submit_hdr_ext)); err = set_submit(priv); trace_nvhost_ioctl_channel_submit(priv->ch->desc->name, priv->hdr.submit_version, priv->hdr.num_cmdbufs, priv->hdr.num_relocs, priv->hdr.num_waitchks, priv->hdr.syncpt_id, priv->hdr.syncpt_incrs); break; } case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS: /* host syncpt ID is used by the RM (and never be given out) */ BUG_ON(priv->ch->desc->syncpts & (1 << NVSYNCPT_GRAPHICS_HOST)); ((struct nvhost_get_param_args *)buf)->value = priv->ch->desc->syncpts; break; case NVHOST_IOCTL_CHANNEL_GET_WAITBASES: ((struct nvhost_get_param_args *)buf)->value = priv->ch->desc->waitbases; break; case NVHOST_IOCTL_CHANNEL_GET_MODMUTEXES: ((struct nvhost_get_param_args *)buf)->value = priv->ch->desc->modulemutexes; break; case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD: { int fd = (int)((struct nvhost_set_nvmap_fd_args *)buf)->fd; struct nvmap_client *new_client = nvmap_client_get_file(fd); if (IS_ERR(new_client)) { err = PTR_ERR(new_client); break; } if (priv->nvmap) nvmap_client_put(priv->nvmap); priv->nvmap = new_client; break; } case NVHOST_IOCTL_CHANNEL_READ_3D_REG: err = nvhost_ioctl_channel_read_3d_reg(priv, (void *)buf); break; case NVHOST_IOCTL_CHANNEL_GET_CLK_RATE: { unsigned long rate; struct nvhost_clk_rate_args *arg = (struct nvhost_clk_rate_args *)buf; err = nvhost_module_get_rate(priv->ch->dev, &priv->ch->mod, &rate, 0); if (err == 0) arg->rate = rate; break; } case NVHOST_IOCTL_CHANNEL_SET_CLK_RATE: { struct nvhost_clk_rate_args *arg = (struct nvhost_clk_rate_args *)buf; unsigned long rate = (unsigned long)arg->rate; err = nvhost_module_set_rate(priv->ch->dev, &priv->ch->mod, priv, rate, 0); break; } case NVHOST_IOCTL_CHANNEL_SET_TIMEOUT: priv->timeout = (u32)((struct nvhost_set_timeout_args *)buf)->timeout; dev_dbg(&priv->ch->dev->pdev->dev, "%s: setting buffer timeout (%d ms) for userctx 0x%p\n", __func__, priv->timeout, priv); break; case NVHOST_IOCTL_CHANNEL_GET_TIMEDOUT: ((struct nvhost_get_param_args *)buf)->value = priv->hwctx->has_timedout; break; case NVHOST_IOCTL_CHANNEL_SET_PRIORITY: priv->priority = (u32)((struct nvhost_set_priority_args *)buf)->priority; break; default: err = -ENOTTY; break; } if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd)); return err; }