diff options
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 293 | 
1 files changed, 184 insertions, 109 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index 4c265ad198b8..bcc7ee02e0fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -262,125 +262,200 @@ static int acp_hw_init(void *handle)  	adev->acp.acp_genpd->adev = adev;  	pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); +	dmi_check_system(acp_quirk_table); +	switch (acp_machine_id) { +	case ST_JADEITE: +	{ +		adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell), +					     GFP_KERNEL); +		if (!adev->acp.acp_cell) { +			r = -ENOMEM; +			goto failure; +		} -	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell), GFP_KERNEL); - -	if (!adev->acp.acp_cell) { -		r = -ENOMEM; -		goto failure; -	} - -	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL); -	if (!adev->acp.acp_res) { -		r = -ENOMEM; -		goto failure; -	} +		adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL); +		if (!adev->acp.acp_res) { +			r = -ENOMEM; +			goto failure; +		} -	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL); -	if (!i2s_pdata) { -		r = -ENOMEM; -		goto failure; -	} +		i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL); +		if (!i2s_pdata) { +			r = -ENOMEM; +			goto failure; +		} -	switch (adev->asic_type) { -	case CHIP_STONEY:  		i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | -			DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +				      DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +		i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; +		i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; +		i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; +		i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; + +		adev->acp.acp_res[0].name = "acp2x_dma"; +		adev->acp.acp_res[0].flags = IORESOURCE_MEM; +		adev->acp.acp_res[0].start = acp_base; +		adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END; + +		adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap"; +		adev->acp.acp_res[1].flags = IORESOURCE_MEM; +		adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START; +		adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END; + +		adev->acp.acp_res[2].name = "acp2x_dma_irq"; +		adev->acp.acp_res[2].flags = IORESOURCE_IRQ; +		adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162); +		adev->acp.acp_res[2].end = adev->acp.acp_res[2].start; + +		adev->acp.acp_cell[0].name = "acp_audio_dma"; +		adev->acp.acp_cell[0].num_resources = 3; +		adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; +		adev->acp.acp_cell[0].platform_data = &adev->asic_type; +		adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); + +		adev->acp.acp_cell[1].name = "designware-i2s"; +		adev->acp.acp_cell[1].num_resources = 1; +		adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1]; +		adev->acp.acp_cell[1].platform_data = &i2s_pdata[0]; +		adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data); +		r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2); +		if (r) +			goto failure; +		r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd, +					  acp_genpd_add_device); +		if (r) +			goto failure;  		break; -	default: -		i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;  	} -	i2s_pdata[0].cap = DWC_I2S_PLAY; -	i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; -	i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; -	i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; -	switch (adev->asic_type) { -	case CHIP_STONEY: -		i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | -			DW_I2S_QUIRK_COMP_PARAM1 | -			DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; -		break;  	default: -		i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | -			DW_I2S_QUIRK_COMP_PARAM1; -	} +		adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell), +					     GFP_KERNEL); -	i2s_pdata[1].cap = DWC_I2S_RECORD; -	i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; -	i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; -	i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; +		if (!adev->acp.acp_cell) { +			r = -ENOMEM; +			goto failure; +		} -	i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; -	switch (adev->asic_type) { -	case CHIP_STONEY: -		i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; -		break; -	default: -		break; -	} +		adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL); +		if (!adev->acp.acp_res) { +			r = -ENOMEM; +			goto failure; +		} + +		i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL); +		if (!i2s_pdata) { +			r = -ENOMEM; +			goto failure; +		} + +		switch (adev->asic_type) { +		case CHIP_STONEY: +			i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | +				DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +			break; +		default: +			i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; +		} +		i2s_pdata[0].cap = DWC_I2S_PLAY; +		i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; +		i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; +		i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; +		switch (adev->asic_type) { +		case CHIP_STONEY: +			i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | +				DW_I2S_QUIRK_COMP_PARAM1 | +				DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +			break; +		default: +			i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | +				DW_I2S_QUIRK_COMP_PARAM1; +		} + +		i2s_pdata[1].cap = DWC_I2S_RECORD; +		i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; +		i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; +		i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; -	i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; -	i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000; -	i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET; -	i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET; - -	adev->acp.acp_res[0].name = "acp2x_dma"; -	adev->acp.acp_res[0].flags = IORESOURCE_MEM; -	adev->acp.acp_res[0].start = acp_base; -	adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END; - -	adev->acp.acp_res[1].name = "acp2x_dw_i2s_play"; -	adev->acp.acp_res[1].flags = IORESOURCE_MEM; -	adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START; -	adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END; - -	adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap"; -	adev->acp.acp_res[2].flags = IORESOURCE_MEM; -	adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; -	adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; - -	adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap"; -	adev->acp.acp_res[3].flags = IORESOURCE_MEM; -	adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START; -	adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END; - -	adev->acp.acp_res[4].name = "acp2x_dma_irq"; -	adev->acp.acp_res[4].flags = IORESOURCE_IRQ; -	adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162); -	adev->acp.acp_res[4].end = adev->acp.acp_res[4].start; - -	adev->acp.acp_cell[0].name = "acp_audio_dma"; -	adev->acp.acp_cell[0].num_resources = 5; -	adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; -	adev->acp.acp_cell[0].platform_data = &adev->asic_type; -	adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); - -	adev->acp.acp_cell[1].name = "designware-i2s"; -	adev->acp.acp_cell[1].num_resources = 1; -	adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1]; -	adev->acp.acp_cell[1].platform_data = &i2s_pdata[0]; -	adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data); - -	adev->acp.acp_cell[2].name = "designware-i2s"; -	adev->acp.acp_cell[2].num_resources = 1; -	adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2]; -	adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; -	adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); - -	adev->acp.acp_cell[3].name = "designware-i2s"; -	adev->acp.acp_cell[3].num_resources = 1; -	adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3]; -	adev->acp.acp_cell[3].platform_data = &i2s_pdata[2]; -	adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data); - -	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS); -	if (r) -		goto failure; - -	r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd, -				  acp_genpd_add_device); -	if (r) -		goto failure; +		i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; +		switch (adev->asic_type) { +		case CHIP_STONEY: +			i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +			break; +		default: +			break; +		} + +		i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; +		i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000; +		i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET; +		i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET; + +		i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; +		switch (adev->asic_type) { +		case CHIP_STONEY: +			i2s_pdata[3].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +			break; +		default: +			break; +		} +		adev->acp.acp_res[0].name = "acp2x_dma"; +		adev->acp.acp_res[0].flags = IORESOURCE_MEM; +		adev->acp.acp_res[0].start = acp_base; +		adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END; + +		adev->acp.acp_res[1].name = "acp2x_dw_i2s_play"; +		adev->acp.acp_res[1].flags = IORESOURCE_MEM; +		adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START; +		adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END; + +		adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap"; +		adev->acp.acp_res[2].flags = IORESOURCE_MEM; +		adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; +		adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; + +		adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap"; +		adev->acp.acp_res[3].flags = IORESOURCE_MEM; +		adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START; +		adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END; + +		adev->acp.acp_res[4].name = "acp2x_dma_irq"; +		adev->acp.acp_res[4].flags = IORESOURCE_IRQ; +		adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162); +		adev->acp.acp_res[4].end = adev->acp.acp_res[4].start; + +		adev->acp.acp_cell[0].name = "acp_audio_dma"; +		adev->acp.acp_cell[0].num_resources = 5; +		adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; +		adev->acp.acp_cell[0].platform_data = &adev->asic_type; +		adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); + +		adev->acp.acp_cell[1].name = "designware-i2s"; +		adev->acp.acp_cell[1].num_resources = 1; +		adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1]; +		adev->acp.acp_cell[1].platform_data = &i2s_pdata[0]; +		adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data); + +		adev->acp.acp_cell[2].name = "designware-i2s"; +		adev->acp.acp_cell[2].num_resources = 1; +		adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2]; +		adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; +		adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); + +		adev->acp.acp_cell[3].name = "designware-i2s"; +		adev->acp.acp_cell[3].num_resources = 1; +		adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3]; +		adev->acp.acp_cell[3].platform_data = &i2s_pdata[2]; +		adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data); + +		r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS); +		if (r) +			goto failure; + +		r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd, +					  acp_genpd_add_device); +		if (r) +			goto failure; +	}  	/* Assert Soft reset of ACP */  	val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);  | 
