1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. 4 * Author: James.Qian.Wang <james.qian.wang@arm.com> 5 * 6 */ 7 #include <linux/platform_device.h> 8 #include <linux/of_device.h> 9 #include <linux/of_graph.h> 10 #include "komeda_dev.h" 11 12 struct komeda_dev *komeda_dev_create(struct device *dev) 13 { 14 struct platform_device *pdev = to_platform_device(dev); 15 const struct komeda_product_data *product; 16 struct komeda_dev *mdev; 17 struct resource *io_res; 18 int err = 0; 19 20 product = of_device_get_match_data(dev); 21 if (!product) 22 return ERR_PTR(-ENODEV); 23 24 io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 25 if (!io_res) { 26 DRM_ERROR("No registers defined.\n"); 27 return ERR_PTR(-ENODEV); 28 } 29 30 mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL); 31 if (!mdev) 32 return ERR_PTR(-ENOMEM); 33 34 mdev->dev = dev; 35 mdev->reg_base = devm_ioremap_resource(dev, io_res); 36 if (IS_ERR(mdev->reg_base)) { 37 DRM_ERROR("Map register space failed.\n"); 38 err = PTR_ERR(mdev->reg_base); 39 mdev->reg_base = NULL; 40 goto err_cleanup; 41 } 42 43 mdev->pclk = devm_clk_get(dev, "pclk"); 44 if (IS_ERR(mdev->pclk)) { 45 DRM_ERROR("Get APB clk failed.\n"); 46 err = PTR_ERR(mdev->pclk); 47 mdev->pclk = NULL; 48 goto err_cleanup; 49 } 50 51 /* Enable APB clock to access the registers */ 52 clk_prepare_enable(mdev->pclk); 53 54 mdev->funcs = product->identify(mdev->reg_base, &mdev->chip); 55 if (!komeda_product_match(mdev, product->product_id)) { 56 DRM_ERROR("DT configured %x mismatch with real HW %x.\n", 57 product->product_id, 58 MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id)); 59 err = -ENODEV; 60 goto err_cleanup; 61 } 62 63 DRM_INFO("Found ARM Mali-D%x version r%dp%d\n", 64 MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id), 65 MALIDP_CORE_ID_MAJOR(mdev->chip.core_id), 66 MALIDP_CORE_ID_MINOR(mdev->chip.core_id)); 67 68 err = mdev->funcs->enum_resources(mdev); 69 if (err) { 70 DRM_ERROR("enumerate display resource failed.\n"); 71 goto err_cleanup; 72 } 73 74 return mdev; 75 76 err_cleanup: 77 komeda_dev_destroy(mdev); 78 return ERR_PTR(err); 79 } 80 81 void komeda_dev_destroy(struct komeda_dev *mdev) 82 { 83 struct device *dev = mdev->dev; 84 struct komeda_dev_funcs *funcs = mdev->funcs; 85 int i; 86 87 for (i = 0; i < mdev->n_pipelines; i++) { 88 komeda_pipeline_destroy(mdev, mdev->pipelines[i]); 89 mdev->pipelines[i] = NULL; 90 } 91 92 mdev->n_pipelines = 0; 93 94 if (funcs && funcs->cleanup) 95 funcs->cleanup(mdev); 96 97 if (mdev->reg_base) { 98 devm_iounmap(dev, mdev->reg_base); 99 mdev->reg_base = NULL; 100 } 101 102 if (mdev->mclk) { 103 devm_clk_put(dev, mdev->mclk); 104 mdev->mclk = NULL; 105 } 106 107 if (mdev->pclk) { 108 clk_disable_unprepare(mdev->pclk); 109 devm_clk_put(dev, mdev->pclk); 110 mdev->pclk = NULL; 111 } 112 113 devm_kfree(dev, mdev); 114 } 115