*
*/
#include <linux/io.h>
+#include <linux/iommu.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
pipe = mdev->pipelines[pipe_id];
- clk = of_clk_get_by_name(np, "aclk");
- if (IS_ERR(clk)) {
- DRM_ERROR("get aclk for pipeline %d failed!\n", pipe_id);
- return PTR_ERR(clk);
- }
- pipe->aclk = clk;
-
clk = of_clk_get_by_name(np, "pxclk");
if (IS_ERR(clk)) {
DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe_id);
{
struct platform_device *pdev = to_platform_device(dev);
struct device_node *child, *np = dev->of_node;
- struct clk *clk;
int ret;
- clk = devm_clk_get(dev, "mclk");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- mdev->mclk = clk;
mdev->irq = platform_get_irq(pdev, 0);
if (mdev->irq < 0) {
DRM_ERROR("could not get IRQ number.\n");
goto err_cleanup;
}
- mdev->pclk = devm_clk_get(dev, "pclk");
- if (IS_ERR(mdev->pclk)) {
- DRM_ERROR("Get APB clk failed.\n");
- err = PTR_ERR(mdev->pclk);
- mdev->pclk = NULL;
+ mdev->aclk = devm_clk_get(dev, "aclk");
+ if (IS_ERR(mdev->aclk)) {
+ DRM_ERROR("Get engine clk failed.\n");
+ err = PTR_ERR(mdev->aclk);
+ mdev->aclk = NULL;
goto err_cleanup;
}
- /* Enable APB clock to access the registers */
- clk_prepare_enable(mdev->pclk);
+ clk_prepare_enable(mdev->aclk);
mdev->funcs = product->identify(mdev->reg_base, &mdev->chip);
if (!komeda_product_match(mdev, product->product_id)) {
goto err_cleanup;
}
+ dev->dma_parms = &mdev->dma_parms;
+ dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
+ mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
+ if (!mdev->iommu)
+ DRM_INFO("continue without IOMMU support!\n");
+
+ if (mdev->iommu && mdev->funcs->connect_iommu) {
+ err = mdev->funcs->connect_iommu(mdev);
+ if (err) {
+ mdev->iommu = NULL;
+ goto err_cleanup;
+ }
+ }
+
err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
void komeda_dev_destroy(struct komeda_dev *mdev)
{
struct device *dev = mdev->dev;
- struct komeda_dev_funcs *funcs = mdev->funcs;
+ const struct komeda_dev_funcs *funcs = mdev->funcs;
int i;
sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group);
debugfs_remove_recursive(mdev->debugfs_root);
#endif
+ if (mdev->iommu && mdev->funcs->disconnect_iommu)
+ mdev->funcs->disconnect_iommu(mdev);
+ mdev->iommu = NULL;
+
for (i = 0; i < mdev->n_pipelines; i++) {
komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
mdev->pipelines[i] = NULL;
mdev->reg_base = NULL;
}
- if (mdev->mclk) {
- devm_clk_put(dev, mdev->mclk);
- mdev->mclk = NULL;
- }
-
- if (mdev->pclk) {
- clk_disable_unprepare(mdev->pclk);
- devm_clk_put(dev, mdev->pclk);
- mdev->pclk = NULL;
+ if (mdev->aclk) {
+ clk_disable_unprepare(mdev->aclk);
+ devm_clk_put(dev, mdev->aclk);
+ mdev->aclk = NULL;
}
devm_kfree(dev, mdev);