All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Vijendar.Mukunda@amd.com
Cc: amd-gfx@lists.freedesktop.org
Subject: [bug report] drm/amdgpu: create I2S platform devices for Jadeite platform
Date: Tue, 26 Jul 2022 18:17:22 +0300	[thread overview]
Message-ID: <YuAFgoepMHvkw3CB@kili> (raw)

Hello Vijendar Mukunda,

The patch 4c33e5179ff1: "drm/amdgpu: create I2S platform devices for
Jadeite platform" from Jun 30, 2022, leads to the following Smatch
static checker warning:

    drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
    error: buffer overflow 'i2s_pdata' 3 <= 3
    drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
    error: buffer overflow 'i2s_pdata' 3 <= 3

drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
    225 static int acp_hw_init(void *handle)
    226 {
    227         int r;
    228         u64 acp_base;
    229         u32 val = 0;
    230         u32 count = 0;
    231         struct i2s_platform_data *i2s_pdata = NULL;
    232 
    233         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    234 
    235         const struct amdgpu_ip_block *ip_block =
    236                 amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP);
    237 
    238         if (!ip_block)
    239                 return -EINVAL;
    240 
    241         r = amd_acp_hw_init(adev->acp.cgs_device,
    242                             ip_block->version->major, ip_block->version->minor);
    243         /* -ENODEV means board uses AZ rather than ACP */
    244         if (r == -ENODEV) {
    245                 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
    246                 return 0;
    247         } else if (r) {
    248                 return r;
    249         }
    250 
    251         if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)
    252                 return -EINVAL;
    253 
    254         acp_base = adev->rmmio_base;
    255         adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
    256         if (!adev->acp.acp_genpd)
    257                 return -ENOMEM;
    258 
    259         adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
    260         adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
    261         adev->acp.acp_genpd->gpd.power_on = acp_poweron;
    262         adev->acp.acp_genpd->adev = adev;
    263 
    264         pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
    265         dmi_check_system(acp_quirk_table);
    266         switch (acp_machine_id) {
    267         case ST_JADEITE:
    268         {
    269                 adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell),
    270                                              GFP_KERNEL);
    271                 if (!adev->acp.acp_cell) {
    272                         r = -ENOMEM;
    273                         goto failure;
    274                 }
    275 
    276                 adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL);
    277                 if (!adev->acp.acp_res) {
    278                         r = -ENOMEM;
    279                         goto failure;
    280                 }
    281 
    282                 i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL);
    283                 if (!i2s_pdata) {
    284                         r = -ENOMEM;
    285                         goto failure;
    286                 }
    287 
    288                 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
    289                                       DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
    290                 i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
    291                 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
    292                 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
    293                 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
    294 
    295                 adev->acp.acp_res[0].name = "acp2x_dma";
    296                 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
    297                 adev->acp.acp_res[0].start = acp_base;
    298                 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
    299 
    300                 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap";
    301                 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
    302                 adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START;
    303                 adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END;
    304 
    305                 adev->acp.acp_res[2].name = "acp2x_dma_irq";
    306                 adev->acp.acp_res[2].flags = IORESOURCE_IRQ;
    307                 adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162);
    308                 adev->acp.acp_res[2].end = adev->acp.acp_res[2].start;
    309 
    310                 adev->acp.acp_cell[0].name = "acp_audio_dma";
    311                 adev->acp.acp_cell[0].num_resources = 3;
    312                 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
    313                 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
    314                 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
    315 
    316                 adev->acp.acp_cell[1].name = "designware-i2s";
    317                 adev->acp.acp_cell[1].num_resources = 1;
    318                 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
    319                 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
    320                 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
    321                 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2);
    322                 if (r)
    323                         goto failure;
    324                 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
    325                                           acp_genpd_add_device);
    326                 if (r)
    327                         goto failure;
    328                 break;
    329         }
    330         default:
    331                 adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
    332                                              GFP_KERNEL);
    333 
    334                 if (!adev->acp.acp_cell) {
    335                         r = -ENOMEM;
    336                         goto failure;
    337                 }
    338 
    339                 adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
    340                 if (!adev->acp.acp_res) {
    341                         r = -ENOMEM;
    342                         goto failure;
    343                 }
    344 
    345                 i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
                                            ^
3 elements

    346                 if (!i2s_pdata) {
    347                         r = -ENOMEM;
    348                         goto failure;
    349                 }
    350 
    351                 switch (adev->asic_type) {
    352                 case CHIP_STONEY:
    353                         i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
    354                                 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
    355                         break;
    356                 default:
    357                         i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
    358                 }
    359                 i2s_pdata[0].cap = DWC_I2S_PLAY;
    360                 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
    361                 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
    362                 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
    363                 switch (adev->asic_type) {
    364                 case CHIP_STONEY:
    365                         i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
    366                                 DW_I2S_QUIRK_COMP_PARAM1 |
    367                                 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
    368                         break;
    369                 default:
    370                         i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
    371                                 DW_I2S_QUIRK_COMP_PARAM1;
    372                 }
    373 
    374                 i2s_pdata[1].cap = DWC_I2S_RECORD;
    375                 i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
    376                 i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
    377                 i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
    378 
    379                 i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
    380                 switch (adev->asic_type) {
    381                 case CHIP_STONEY:
    382                         i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
    383                         break;
    384                 default:
    385                         break;
    386                 }
    387 
    388                 i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
    389                 i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;
    390                 i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
    391                 i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
    392 
--> 393                 i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
                        ^^^^^^^^^^^^

    394                 switch (adev->asic_type) {
    395                 case CHIP_STONEY:
    396                         i2s_pdata[3].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
                                ^^^^^^^^^^^^

Out of boundses.

    397                         break;
    398                 default:
    399                         break;
    400                 }
    401                 adev->acp.acp_res[0].name = "acp2x_dma";
    402                 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
    403                 adev->acp.acp_res[0].start = acp_base;
    404                 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
    405 
    406                 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";
    407                 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
    408                 adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;
    409                 adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;
    410 
    411                 adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";
    412                 adev->acp.acp_res[2].flags = IORESOURCE_MEM;
    413                 adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;
    414                 adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;
    415 
    416                 adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";
    417                 adev->acp.acp_res[3].flags = IORESOURCE_MEM;
    418                 adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;
    419                 adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;
    420 
    421                 adev->acp.acp_res[4].name = "acp2x_dma_irq";
    422                 adev->acp.acp_res[4].flags = IORESOURCE_IRQ;
    423                 adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);
    424                 adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;
    425 
    426                 adev->acp.acp_cell[0].name = "acp_audio_dma";
    427                 adev->acp.acp_cell[0].num_resources = 5;
    428                 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
    429                 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
    430                 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
    431 
    432                 adev->acp.acp_cell[1].name = "designware-i2s";
    433                 adev->acp.acp_cell[1].num_resources = 1;
    434                 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
    435                 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
    436                 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
    437 
    438                 adev->acp.acp_cell[2].name = "designware-i2s";
    439                 adev->acp.acp_cell[2].num_resources = 1;
    440                 adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];
    441                 adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];
    442                 adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);
    443 
    444                 adev->acp.acp_cell[3].name = "designware-i2s";
    445                 adev->acp.acp_cell[3].num_resources = 1;
    446                 adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];
    447                 adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];
    448                 adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);
    449 
    450                 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS);
    451                 if (r)
    452                         goto failure;
    453 
    454                 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
    455                                           acp_genpd_add_device);
    456                 if (r)
    457                         goto failure;
    458         }
    459 
    460         /* Assert Soft reset of ACP */
    461         val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
    462 
    463         val |= ACP_SOFT_RESET__SoftResetAud_MASK;
    464         cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
    465 
    466         count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
    467         while (true) {
    468                 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
    469                 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
    470                     (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
    471                         break;
    472                 if (--count == 0) {
    473                         dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
    474                         r = -ETIMEDOUT;
    475                         goto failure;
    476                 }
    477                 udelay(100);
    478         }
    479         /* Enable clock to ACP and wait until the clock is enabled */
    480         val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);
    481         val = val | ACP_CONTROL__ClkEn_MASK;
    482         cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);
    483 
    484         count = ACP_CLOCK_EN_TIME_OUT_VALUE;
    485 
    486         while (true) {
    487                 val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);
    488                 if (val & (u32) 0x1)
    489                         break;
    490                 if (--count == 0) {
    491                         dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
    492                         r = -ETIMEDOUT;
    493                         goto failure;
    494                 }
    495                 udelay(100);
    496         }
    497         /* Deassert the SOFT RESET flags */
    498         val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
    499         val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
    500         cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
    501         return 0;
    502 
    503 failure:
    504         kfree(i2s_pdata);
    505         kfree(adev->acp.acp_res);
    506         kfree(adev->acp.acp_cell);
    507         kfree(adev->acp.acp_genpd);
    508         return r;
    509 }

regards,
dan carpenter

             reply	other threads:[~2022-07-26 15:17 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-26 15:17 Dan Carpenter [this message]
2022-07-27  6:36 ` [bug report] drm/amdgpu: create I2S platform devices for Jadeite platform Mukunda,Vijendar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YuAFgoepMHvkw3CB@kili \
    --to=dan.carpenter@oracle.com \
    --cc=Vijendar.Mukunda@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.