ste_dma40.c (339f5041089a22646372d3ebdeec94c25e8d4e29) | ste_dma40.c (2893f6bc9d4076c48f8dd717b71baa29fe6adcae) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) Ericsson AB 2007-2008 4 * Copyright (C) ST-Ericsson SA 2008-2010 5 * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson 6 * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson 7 */ 8 --- 3118 unchanged lines hidden (view full) --- 3127/* Called from the registered devm action */ 3128static void d40_drop_kmem_cache_action(void *d) 3129{ 3130 struct kmem_cache *desc_slab = d; 3131 3132 kmem_cache_destroy(desc_slab); 3133} 3134 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) Ericsson AB 2007-2008 4 * Copyright (C) ST-Ericsson SA 2008-2010 5 * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson 6 * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson 7 */ 8 --- 3118 unchanged lines hidden (view full) --- 3127/* Called from the registered devm action */ 3128static void d40_drop_kmem_cache_action(void *d) 3129{ 3130 struct kmem_cache *desc_slab = d; 3131 3132 kmem_cache_destroy(desc_slab); 3133} 3134 |
3135static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | 3135static int __init d40_hw_detect_init(struct platform_device *pdev, 3136 struct d40_base **retbase) |
3136{ 3137 struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); 3138 struct device *dev = &pdev->dev; 3139 struct clk *clk; 3140 void __iomem *virtbase; 3141 struct d40_base *base; 3142 int num_log_chans; 3143 int num_phy_chans; 3144 int num_memcpy_chans; 3145 int i; 3146 u32 pid; 3147 u32 cid; 3148 u8 rev; 3149 int ret; 3150 3151 clk = devm_clk_get_enabled(dev, NULL); 3152 if (IS_ERR(clk)) | 3137{ 3138 struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); 3139 struct device *dev = &pdev->dev; 3140 struct clk *clk; 3141 void __iomem *virtbase; 3142 struct d40_base *base; 3143 int num_log_chans; 3144 int num_phy_chans; 3145 int num_memcpy_chans; 3146 int i; 3147 u32 pid; 3148 u32 cid; 3149 u8 rev; 3150 int ret; 3151 3152 clk = devm_clk_get_enabled(dev, NULL); 3153 if (IS_ERR(clk)) |
3153 return NULL; | 3154 return PTR_ERR(clk); |
3154 3155 /* Get IO for DMAC base address */ 3156 virtbase = devm_platform_ioremap_resource_byname(pdev, "base"); | 3155 3156 /* Get IO for DMAC base address */ 3157 virtbase = devm_platform_ioremap_resource_byname(pdev, "base"); |
3157 if (IS_ERR(virtbase)) { 3158 dev_err(dev, "No IO base defined\n"); 3159 return NULL; 3160 } | 3158 if (IS_ERR(virtbase)) 3159 return PTR_ERR(virtbase); |
3161 3162 /* This is just a regular AMBA PrimeCell ID actually */ 3163 for (pid = 0, i = 0; i < 4; i++) 3164 pid |= (readl(virtbase + SZ_4K - 0x20 + 4 * i) 3165 & 255) << (i * 8); 3166 for (cid = 0, i = 0; i < 4; i++) 3167 cid |= (readl(virtbase + SZ_4K - 0x10 + 4 * i) 3168 & 255) << (i * 8); 3169 3170 if (cid != AMBA_CID) { 3171 d40_err(dev, "Unknown hardware! No PrimeCell ID\n"); | 3160 3161 /* This is just a regular AMBA PrimeCell ID actually */ 3162 for (pid = 0, i = 0; i < 4; i++) 3163 pid |= (readl(virtbase + SZ_4K - 0x20 + 4 * i) 3164 & 255) << (i * 8); 3165 for (cid = 0, i = 0; i < 4; i++) 3166 cid |= (readl(virtbase + SZ_4K - 0x10 + 4 * i) 3167 & 255) << (i * 8); 3168 3169 if (cid != AMBA_CID) { 3170 d40_err(dev, "Unknown hardware! No PrimeCell ID\n"); |
3172 return NULL; | 3171 return -EINVAL; |
3173 } 3174 if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) { 3175 d40_err(dev, "Unknown designer! Got %x wanted %x\n", 3176 AMBA_MANF_BITS(pid), 3177 AMBA_VENDOR_ST); | 3172 } 3173 if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) { 3174 d40_err(dev, "Unknown designer! Got %x wanted %x\n", 3175 AMBA_MANF_BITS(pid), 3176 AMBA_VENDOR_ST); |
3178 return NULL; | 3177 return -EINVAL; |
3179 } 3180 /* 3181 * HW revision: 3182 * DB8500ed has revision 0 3183 * ? has revision 1 3184 * DB8500v1 has revision 2 3185 * DB8500v2 has revision 3 3186 * AP9540v1 has revision 4 3187 * DB8540v1 has revision 4 3188 */ 3189 rev = AMBA_REV_BITS(pid); 3190 if (rev < 2) { 3191 d40_err(dev, "hardware revision: %d is not supported", rev); | 3178 } 3179 /* 3180 * HW revision: 3181 * DB8500ed has revision 0 3182 * ? has revision 1 3183 * DB8500v1 has revision 2 3184 * DB8500v2 has revision 3 3185 * AP9540v1 has revision 4 3186 * DB8540v1 has revision 4 3187 */ 3188 rev = AMBA_REV_BITS(pid); 3189 if (rev < 2) { 3190 d40_err(dev, "hardware revision: %d is not supported", rev); |
3192 return NULL; | 3191 return -EINVAL; |
3193 } 3194 3195 /* The number of physical channels on this HW */ 3196 if (plat_data->num_of_phy_chans) 3197 num_phy_chans = plat_data->num_of_phy_chans; 3198 else 3199 num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; 3200 --- 10 unchanged lines hidden (view full) --- 3211 rev, num_phy_chans, num_log_chans); 3212 3213 base = devm_kzalloc(dev, 3214 ALIGN(sizeof(struct d40_base), 4) + 3215 (num_phy_chans + num_log_chans + num_memcpy_chans) * 3216 sizeof(struct d40_chan), GFP_KERNEL); 3217 3218 if (!base) | 3192 } 3193 3194 /* The number of physical channels on this HW */ 3195 if (plat_data->num_of_phy_chans) 3196 num_phy_chans = plat_data->num_of_phy_chans; 3197 else 3198 num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; 3199 --- 10 unchanged lines hidden (view full) --- 3210 rev, num_phy_chans, num_log_chans); 3211 3212 base = devm_kzalloc(dev, 3213 ALIGN(sizeof(struct d40_base), 4) + 3214 (num_phy_chans + num_log_chans + num_memcpy_chans) * 3215 sizeof(struct d40_chan), GFP_KERNEL); 3216 3217 if (!base) |
3219 return NULL; | 3218 return -ENOMEM; |
3220 3221 base->rev = rev; 3222 base->clk = clk; 3223 base->num_memcpy_chans = num_memcpy_chans; 3224 base->num_phy_chans = num_phy_chans; 3225 base->num_log_chans = num_log_chans; 3226 base->virtbase = virtbase; 3227 base->plat_data = plat_data; --- 30 unchanged lines hidden (view full) --- 3258 base->gen_dmac.init_reg = dma_init_reg_v4a; 3259 base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4a); 3260 } 3261 3262 base->phy_res = devm_kcalloc(dev, num_phy_chans, 3263 sizeof(*base->phy_res), 3264 GFP_KERNEL); 3265 if (!base->phy_res) | 3219 3220 base->rev = rev; 3221 base->clk = clk; 3222 base->num_memcpy_chans = num_memcpy_chans; 3223 base->num_phy_chans = num_phy_chans; 3224 base->num_log_chans = num_log_chans; 3225 base->virtbase = virtbase; 3226 base->plat_data = plat_data; --- 30 unchanged lines hidden (view full) --- 3257 base->gen_dmac.init_reg = dma_init_reg_v4a; 3258 base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4a); 3259 } 3260 3261 base->phy_res = devm_kcalloc(dev, num_phy_chans, 3262 sizeof(*base->phy_res), 3263 GFP_KERNEL); 3264 if (!base->phy_res) |
3266 return NULL; | 3265 return -ENOMEM; |
3267 3268 base->lookup_phy_chans = devm_kcalloc(dev, num_phy_chans, 3269 sizeof(*base->lookup_phy_chans), 3270 GFP_KERNEL); 3271 if (!base->lookup_phy_chans) | 3266 3267 base->lookup_phy_chans = devm_kcalloc(dev, num_phy_chans, 3268 sizeof(*base->lookup_phy_chans), 3269 GFP_KERNEL); 3270 if (!base->lookup_phy_chans) |
3272 return NULL; | 3271 return -ENOMEM; |
3273 3274 base->lookup_log_chans = devm_kcalloc(dev, num_log_chans, 3275 sizeof(*base->lookup_log_chans), 3276 GFP_KERNEL); 3277 if (!base->lookup_log_chans) | 3272 3273 base->lookup_log_chans = devm_kcalloc(dev, num_log_chans, 3274 sizeof(*base->lookup_log_chans), 3275 GFP_KERNEL); 3276 if (!base->lookup_log_chans) |
3278 return NULL; | 3277 return -ENOMEM; |
3279 3280 base->reg_val_backup_chan = devm_kmalloc_array(dev, base->num_phy_chans, 3281 sizeof(d40_backup_regs_chan), 3282 GFP_KERNEL); 3283 if (!base->reg_val_backup_chan) | 3278 3279 base->reg_val_backup_chan = devm_kmalloc_array(dev, base->num_phy_chans, 3280 sizeof(d40_backup_regs_chan), 3281 GFP_KERNEL); 3282 if (!base->reg_val_backup_chan) |
3284 return NULL; | 3283 return -ENOMEM; |
3285 3286 base->lcla_pool.alloc_map = devm_kcalloc(dev, num_phy_chans 3287 * D40_LCLA_LINK_PER_EVENT_GRP, 3288 sizeof(*base->lcla_pool.alloc_map), 3289 GFP_KERNEL); 3290 if (!base->lcla_pool.alloc_map) | 3284 3285 base->lcla_pool.alloc_map = devm_kcalloc(dev, num_phy_chans 3286 * D40_LCLA_LINK_PER_EVENT_GRP, 3287 sizeof(*base->lcla_pool.alloc_map), 3288 GFP_KERNEL); 3289 if (!base->lcla_pool.alloc_map) |
3291 return NULL; | 3290 return -ENOMEM; |
3292 3293 base->regs_interrupt = devm_kmalloc_array(dev, base->gen_dmac.il_size, 3294 sizeof(*base->regs_interrupt), 3295 GFP_KERNEL); 3296 if (!base->regs_interrupt) | 3291 3292 base->regs_interrupt = devm_kmalloc_array(dev, base->gen_dmac.il_size, 3293 sizeof(*base->regs_interrupt), 3294 GFP_KERNEL); 3295 if (!base->regs_interrupt) |
3297 return NULL; | 3296 return -ENOMEM; |
3298 3299 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), 3300 0, SLAB_HWCACHE_ALIGN, 3301 NULL); 3302 if (!base->desc_slab) | 3297 3298 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), 3299 0, SLAB_HWCACHE_ALIGN, 3300 NULL); 3301 if (!base->desc_slab) |
3303 return NULL; | 3302 return -ENOMEM; |
3304 3305 ret = devm_add_action_or_reset(dev, d40_drop_kmem_cache_action, 3306 base->desc_slab); 3307 if (ret) | 3303 3304 ret = devm_add_action_or_reset(dev, d40_drop_kmem_cache_action, 3305 base->desc_slab); 3306 if (ret) |
3308 return NULL; | 3307 return ret; |
3309 | 3308 |
3310 return base; | 3309 *retbase = base; 3310 3311 return 0; |
3311} 3312 3313static void __init d40_hw_init(struct d40_base *base) 3314{ 3315 3316 int i; 3317 u32 prmseo[2] = {0, 0}; 3318 u32 activeo[2] = {0xFFFFFFFF, 0xFFFFFFFF}; --- 179 unchanged lines hidden (view full) --- 3498 return 0; 3499} 3500 3501static int __init d40_probe(struct platform_device *pdev) 3502{ 3503 struct device *dev = &pdev->dev; 3504 struct device_node *np = pdev->dev.of_node; 3505 struct device_node *np_lcpa; | 3312} 3313 3314static void __init d40_hw_init(struct d40_base *base) 3315{ 3316 3317 int i; 3318 u32 prmseo[2] = {0, 0}; 3319 u32 activeo[2] = {0xFFFFFFFF, 0xFFFFFFFF}; --- 179 unchanged lines hidden (view full) --- 3499 return 0; 3500} 3501 3502static int __init d40_probe(struct platform_device *pdev) 3503{ 3504 struct device *dev = &pdev->dev; 3505 struct device_node *np = pdev->dev.of_node; 3506 struct device_node *np_lcpa; |
3506 int ret = -ENOENT; | |
3507 struct d40_base *base; 3508 struct resource *res; 3509 struct resource res_lcpa; 3510 int num_reserved_chans; 3511 u32 val; | 3507 struct d40_base *base; 3508 struct resource *res; 3509 struct resource res_lcpa; 3510 int num_reserved_chans; 3511 u32 val; |
3512 int ret; |
|
3512 3513 if (d40_of_probe(dev, np)) { 3514 ret = -ENOMEM; 3515 goto report_failure; 3516 } 3517 | 3513 3514 if (d40_of_probe(dev, np)) { 3515 ret = -ENOMEM; 3516 goto report_failure; 3517 } 3518 |
3518 base = d40_hw_detect_init(pdev); 3519 if (!base) | 3519 ret = d40_hw_detect_init(pdev, &base); 3520 if (ret) |
3520 goto report_failure; 3521 3522 num_reserved_chans = d40_phy_res_init(base); 3523 3524 platform_set_drvdata(pdev, base); 3525 3526 spin_lock_init(&base->interrupt_lock); 3527 spin_lock_init(&base->execmd_lock); 3528 3529 /* Get IO for logical channel parameter address (LCPA) */ 3530 np_lcpa = of_parse_phandle(np, "sram", 0); 3531 if (!np_lcpa) { 3532 dev_err(dev, "no LCPA SRAM node\n"); | 3521 goto report_failure; 3522 3523 num_reserved_chans = d40_phy_res_init(base); 3524 3525 platform_set_drvdata(pdev, base); 3526 3527 spin_lock_init(&base->interrupt_lock); 3528 spin_lock_init(&base->execmd_lock); 3529 3530 /* Get IO for logical channel parameter address (LCPA) */ 3531 np_lcpa = of_parse_phandle(np, "sram", 0); 3532 if (!np_lcpa) { 3533 dev_err(dev, "no LCPA SRAM node\n"); |
3534 ret = -EINVAL; |
|
3533 goto report_failure; 3534 } 3535 /* This is no device so read the address directly from the node */ 3536 ret = of_address_to_resource(np_lcpa, 0, &res_lcpa); 3537 if (ret) { 3538 dev_err(dev, "no LCPA SRAM resource\n"); 3539 goto report_failure; 3540 } --- 148 unchanged lines hidden --- | 3535 goto report_failure; 3536 } 3537 /* This is no device so read the address directly from the node */ 3538 ret = of_address_to_resource(np_lcpa, 0, &res_lcpa); 3539 if (ret) { 3540 dev_err(dev, "no LCPA SRAM resource\n"); 3541 goto report_failure; 3542 } --- 148 unchanged lines hidden --- |