brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 0a4b58d Raw
1004 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver4 *5 * Copyright (C) 2013 Samsung Electronics Co., Ltd.6 *7 * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>8 *          Younghwan Joo <yhwan.joo@samsung.com>9 */10#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__11 12#include <linux/device.h>13#include <linux/debugfs.h>14#include <linux/delay.h>15#include <linux/errno.h>16#include <linux/firmware.h>17#include <linux/interrupt.h>18#include <linux/kernel.h>19#include <linux/module.h>20#include <linux/i2c.h>21#include <linux/of_irq.h>22#include <linux/of_address.h>23#include <linux/of_graph.h>24#include <linux/of_platform.h>25#include <linux/platform_device.h>26#include <linux/pm_runtime.h>27#include <linux/slab.h>28#include <linux/types.h>29#include <linux/videodev2.h>30#include <media/videobuf2-dma-contig.h>31 32#include "media-dev.h"33#include "fimc-is.h"34#include "fimc-is-command.h"35#include "fimc-is-errno.h"36#include "fimc-is-i2c.h"37#include "fimc-is-param.h"38#include "fimc-is-regs.h"39 40 41static char *fimc_is_clocks[ISS_CLKS_MAX] = {42	[ISS_CLK_PPMUISPX]		= "ppmuispx",43	[ISS_CLK_PPMUISPMX]		= "ppmuispmx",44	[ISS_CLK_LITE0]			= "lite0",45	[ISS_CLK_LITE1]			= "lite1",46	[ISS_CLK_MPLL]			= "mpll",47	[ISS_CLK_ISP]			= "isp",48	[ISS_CLK_DRC]			= "drc",49	[ISS_CLK_FD]			= "fd",50	[ISS_CLK_MCUISP]		= "mcuisp",51	[ISS_CLK_GICISP]		= "gicisp",52	[ISS_CLK_PWM_ISP]		= "pwm_isp",53	[ISS_CLK_MCUCTL_ISP]		= "mcuctl_isp",54	[ISS_CLK_UART]			= "uart",55	[ISS_CLK_ISP_DIV0]		= "ispdiv0",56	[ISS_CLK_ISP_DIV1]		= "ispdiv1",57	[ISS_CLK_MCUISP_DIV0]		= "mcuispdiv0",58	[ISS_CLK_MCUISP_DIV1]		= "mcuispdiv1",59	[ISS_CLK_ACLK200]		= "aclk200",60	[ISS_CLK_ACLK200_DIV]		= "div_aclk200",61	[ISS_CLK_ACLK400MCUISP]		= "aclk400mcuisp",62	[ISS_CLK_ACLK400MCUISP_DIV]	= "div_aclk400mcuisp",63};64 65static void fimc_is_put_clocks(struct fimc_is *is)66{67	int i;68 69	for (i = 0; i < ISS_CLKS_MAX; i++) {70		if (IS_ERR(is->clocks[i]))71			continue;72		clk_put(is->clocks[i]);73		is->clocks[i] = ERR_PTR(-EINVAL);74	}75}76 77static int fimc_is_get_clocks(struct fimc_is *is)78{79	int i, ret;80 81	for (i = 0; i < ISS_CLKS_MAX; i++)82		is->clocks[i] = ERR_PTR(-EINVAL);83 84	for (i = 0; i < ISS_CLKS_MAX; i++) {85		is->clocks[i] = clk_get(&is->pdev->dev, fimc_is_clocks[i]);86		if (IS_ERR(is->clocks[i])) {87			ret = PTR_ERR(is->clocks[i]);88			goto err;89		}90	}91 92	return 0;93err:94	fimc_is_put_clocks(is);95	dev_err(&is->pdev->dev, "failed to get clock: %s\n",96		fimc_is_clocks[i]);97	return ret;98}99 100static int fimc_is_setup_clocks(struct fimc_is *is)101{102	int ret;103 104	ret = clk_set_parent(is->clocks[ISS_CLK_ACLK200],105					is->clocks[ISS_CLK_ACLK200_DIV]);106	if (ret < 0)107		return ret;108 109	ret = clk_set_parent(is->clocks[ISS_CLK_ACLK400MCUISP],110					is->clocks[ISS_CLK_ACLK400MCUISP_DIV]);111	if (ret < 0)112		return ret;113 114	ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV0], ACLK_AXI_FREQUENCY);115	if (ret < 0)116		return ret;117 118	ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV1], ACLK_AXI_FREQUENCY);119	if (ret < 0)120		return ret;121 122	ret = clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV0],123					ATCLK_MCUISP_FREQUENCY);124	if (ret < 0)125		return ret;126 127	return clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV1],128					ATCLK_MCUISP_FREQUENCY);129}130 131static int fimc_is_enable_clocks(struct fimc_is *is)132{133	int i, ret;134 135	for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {136		if (IS_ERR(is->clocks[i]))137			continue;138		ret = clk_prepare_enable(is->clocks[i]);139		if (ret < 0) {140			dev_err(&is->pdev->dev, "clock %s enable failed\n",141				fimc_is_clocks[i]);142			for (--i; i >= 0; i--)143				clk_disable_unprepare(is->clocks[i]);144			return ret;145		}146		pr_debug("enabled clock: %s\n", fimc_is_clocks[i]);147	}148	return 0;149}150 151static void fimc_is_disable_clocks(struct fimc_is *is)152{153	int i;154 155	for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {156		if (!IS_ERR(is->clocks[i])) {157			clk_disable_unprepare(is->clocks[i]);158			pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);159		}160	}161}162 163static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,164						struct device_node *node)165{166	struct fimc_is_sensor *sensor = &is->sensor[index];167	struct device_node *ep, *port;168	u32 tmp = 0;169	int ret;170 171	sensor->drvdata = fimc_is_sensor_get_drvdata(node);172	if (!sensor->drvdata) {173		dev_err(&is->pdev->dev, "no driver data found for: %pOF\n",174							 node);175		return -EINVAL;176	}177 178	ep = of_graph_get_endpoint_by_regs(node, 0, -1);179	if (!ep)180		return -ENXIO;181 182	port = of_graph_get_remote_port(ep);183	of_node_put(ep);184	if (!port)185		return -ENXIO;186 187	/* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */188	ret = of_property_read_u32(port, "reg", &tmp);189	if (ret < 0) {190		dev_err(&is->pdev->dev, "reg property not found at: %pOF\n",191							 port);192		of_node_put(port);193		return ret;194	}195 196	of_node_put(port);197	sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;198	return 0;199}200 201static int fimc_is_register_subdevs(struct fimc_is *is)202{203	struct device_node *i2c_bus, *child;204	int ret, index = 0;205 206	ret = fimc_isp_subdev_create(&is->isp);207	if (ret < 0)208		return ret;209 210	for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {211		for_each_available_child_of_node(i2c_bus, child) {212			ret = fimc_is_parse_sensor_config(is, index, child);213 214			if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {215				of_node_put(child);216				of_node_put(i2c_bus);217				return ret;218			}219			index++;220		}221	}222	return 0;223}224 225static int fimc_is_unregister_subdevs(struct fimc_is *is)226{227	fimc_isp_subdev_destroy(&is->isp);228	return 0;229}230 231static int fimc_is_load_setfile(struct fimc_is *is, char *file_name)232{233	const struct firmware *fw;234	void *buf;235	int ret;236 237	ret = request_firmware(&fw, file_name, &is->pdev->dev);238	if (ret < 0) {239		dev_err(&is->pdev->dev, "firmware request failed (%d)\n", ret);240		return ret;241	}242	buf = is->memory.vaddr + is->setfile.base;243	memcpy(buf, fw->data, fw->size);244	fimc_is_mem_barrier();245	is->setfile.size = fw->size;246 247	pr_debug("mem vaddr: %p, setfile buf: %p\n", is->memory.vaddr, buf);248 249	memcpy(is->fw.setfile_info,250		fw->data + fw->size - FIMC_IS_SETFILE_INFO_LEN,251		FIMC_IS_SETFILE_INFO_LEN - 1);252 253	is->fw.setfile_info[FIMC_IS_SETFILE_INFO_LEN - 1] = '\0';254	is->setfile.state = 1;255 256	pr_debug("FIMC-IS setfile loaded: base: %#x, size: %zu B\n",257		 is->setfile.base, fw->size);258 259	release_firmware(fw);260	return ret;261}262 263int fimc_is_cpu_set_power(struct fimc_is *is, int on)264{265	unsigned int timeout = FIMC_IS_POWER_ON_TIMEOUT;266 267	if (on) {268		/* Disable watchdog */269		mcuctl_write(0, is, REG_WDT_ISP);270 271		/* Cortex-A5 start address setting */272		mcuctl_write(is->memory.addr, is, MCUCTL_REG_BBOAR);273 274		/* Enable and start Cortex-A5 */275		pmuisp_write(0x18000, is, REG_PMU_ISP_ARM_OPTION);276		pmuisp_write(0x1, is, REG_PMU_ISP_ARM_CONFIGURATION);277	} else {278		/* A5 power off */279		pmuisp_write(0x10000, is, REG_PMU_ISP_ARM_OPTION);280		pmuisp_write(0x0, is, REG_PMU_ISP_ARM_CONFIGURATION);281 282		while (pmuisp_read(is, REG_PMU_ISP_ARM_STATUS) & 1) {283			if (timeout == 0)284				return -ETIME;285			timeout--;286			udelay(1);287		}288	}289 290	return 0;291}292 293/* Wait until @bit of @is->state is set to @state in the interrupt handler. */294int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,295		       unsigned int state, unsigned int timeout)296{297 298	int ret = wait_event_timeout(is->irq_queue,299				     !state ^ test_bit(bit, &is->state),300				     timeout);301	if (ret == 0) {302		dev_WARN(&is->pdev->dev, "%s() timed out\n", __func__);303		return -ETIME;304	}305	return 0;306}307 308int fimc_is_start_firmware(struct fimc_is *is)309{310	struct device *dev = &is->pdev->dev;311	int ret;312 313	if (is->fw.f_w == NULL) {314		dev_err(dev, "firmware is not loaded\n");315		return -EINVAL;316	}317 318	memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size);319	wmb();320 321	ret = fimc_is_cpu_set_power(is, 1);322	if (ret < 0)323		return ret;324 325	ret = fimc_is_wait_event(is, IS_ST_A5_PWR_ON, 1,326				 msecs_to_jiffies(FIMC_IS_FW_LOAD_TIMEOUT));327	if (ret < 0)328		dev_err(dev, "FIMC-IS CPU power on failed\n");329 330	return ret;331}332 333/* Allocate working memory for the FIMC-IS CPU. */334static int fimc_is_alloc_cpu_memory(struct fimc_is *is)335{336	struct device *dev = &is->pdev->dev;337 338	is->memory.vaddr = dma_alloc_coherent(dev, FIMC_IS_CPU_MEM_SIZE,339					      &is->memory.addr, GFP_KERNEL);340	if (is->memory.vaddr == NULL)341		return -ENOMEM;342 343	is->memory.size = FIMC_IS_CPU_MEM_SIZE;344 345	dev_info(dev, "FIMC-IS CPU memory base: %pad\n", &is->memory.addr);346 347	if (((u32)is->memory.addr) & FIMC_IS_FW_ADDR_MASK) {348		dev_err(dev, "invalid firmware memory alignment: %#x\n",349			(u32)is->memory.addr);350		dma_free_coherent(dev, is->memory.size, is->memory.vaddr,351				  is->memory.addr);352		return -EIO;353	}354 355	is->is_p_region = (struct is_region *)(is->memory.vaddr +356				FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE);357 358	is->is_dma_p_region = is->memory.addr +359				FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE;360 361	is->is_shared_region = (struct is_share_region *)(is->memory.vaddr +362				FIMC_IS_SHARED_REGION_OFFSET);363	return 0;364}365 366static void fimc_is_free_cpu_memory(struct fimc_is *is)367{368	struct device *dev = &is->pdev->dev;369 370	if (is->memory.vaddr == NULL)371		return;372 373	dma_free_coherent(dev, is->memory.size, is->memory.vaddr,374			  is->memory.addr);375}376 377static void fimc_is_load_firmware(const struct firmware *fw, void *context)378{379	struct fimc_is *is = context;380	struct device *dev = &is->pdev->dev;381	void *buf;382	int ret;383 384	if (fw == NULL) {385		dev_err(dev, "firmware request failed\n");386		return;387	}388	mutex_lock(&is->lock);389 390	if (fw->size < FIMC_IS_FW_SIZE_MIN || fw->size > FIMC_IS_FW_SIZE_MAX) {391		dev_err(dev, "wrong firmware size: %zu\n", fw->size);392		goto done;393	}394 395	is->fw.size = fw->size;396 397	ret = fimc_is_alloc_cpu_memory(is);398	if (ret < 0) {399		dev_err(dev, "failed to allocate FIMC-IS CPU memory\n");400		goto done;401	}402 403	memcpy(is->memory.vaddr, fw->data, fw->size);404	wmb();405 406	/* Read firmware description. */407	buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_DESC_LEN);408	memcpy(&is->fw.info, buf, FIMC_IS_FW_INFO_LEN);409	is->fw.info[FIMC_IS_FW_INFO_LEN] = 0;410 411	buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_VER_LEN);412	memcpy(&is->fw.version, buf, FIMC_IS_FW_VER_LEN);413	is->fw.version[FIMC_IS_FW_VER_LEN - 1] = 0;414 415	is->fw.state = 1;416 417	dev_info(dev, "loaded firmware: %s, rev. %s\n",418		 is->fw.info, is->fw.version);419	dev_dbg(dev, "FW size: %zu, DMA addr: %pad\n", fw->size, &is->memory.addr);420 421	is->is_shared_region->chip_id = 0xe4412;422	is->is_shared_region->chip_rev_no = 1;423 424	fimc_is_mem_barrier();425 426	/*427	 * FIXME: The firmware is not being released for now, as it is428	 * needed around for copying to the IS working memory every429	 * time before the Cortex-A5 is restarted.430	 */431	release_firmware(is->fw.f_w);432	is->fw.f_w = fw;433done:434	mutex_unlock(&is->lock);435}436 437static int fimc_is_request_firmware(struct fimc_is *is, const char *fw_name)438{439	return request_firmware_nowait(THIS_MODULE,440				FW_ACTION_UEVENT, fw_name, &is->pdev->dev,441				GFP_KERNEL, is, fimc_is_load_firmware);442}443 444/* General IS interrupt handler */445static void fimc_is_general_irq_handler(struct fimc_is *is)446{447	is->i2h_cmd.cmd = mcuctl_read(is, MCUCTL_REG_ISSR(10));448 449	switch (is->i2h_cmd.cmd) {450	case IHC_GET_SENSOR_NUM:451		fimc_is_hw_get_params(is, 1);452		fimc_is_hw_wait_intmsr0_intmsd0(is);453		fimc_is_hw_set_sensor_num(is);454		pr_debug("ISP FW version: %#x\n", is->i2h_cmd.args[0]);455		break;456	case IHC_SET_FACE_MARK:457	case IHC_FRAME_DONE:458		fimc_is_hw_get_params(is, 2);459		break;460	case IHC_SET_SHOT_MARK:461	case IHC_AA_DONE:462	case IH_REPLY_DONE:463		fimc_is_hw_get_params(is, 3);464		break;465	case IH_REPLY_NOT_DONE:466		fimc_is_hw_get_params(is, 4);467		break;468	case IHC_NOT_READY:469		break;470	default:471		pr_info("unknown command: %#x\n", is->i2h_cmd.cmd);472	}473 474	fimc_is_fw_clear_irq1(is, FIMC_IS_INT_GENERAL);475 476	switch (is->i2h_cmd.cmd) {477	case IHC_GET_SENSOR_NUM:478		fimc_is_hw_set_intgr0_gd0(is);479		set_bit(IS_ST_A5_PWR_ON, &is->state);480		break;481 482	case IHC_SET_SHOT_MARK:483		break;484 485	case IHC_SET_FACE_MARK:486		is->fd_header.count = is->i2h_cmd.args[0];487		is->fd_header.index = is->i2h_cmd.args[1];488		is->fd_header.offset = 0;489		break;490 491	case IHC_FRAME_DONE:492		break;493 494	case IHC_AA_DONE:495		pr_debug("AA_DONE - %d, %d, %d\n", is->i2h_cmd.args[0],496			 is->i2h_cmd.args[1], is->i2h_cmd.args[2]);497		break;498 499	case IH_REPLY_DONE:500		pr_debug("ISR_DONE: args[0]: %#x\n", is->i2h_cmd.args[0]);501 502		switch (is->i2h_cmd.args[0]) {503		case HIC_PREVIEW_STILL...HIC_CAPTURE_VIDEO:504			/* Get CAC margin */505			set_bit(IS_ST_CHANGE_MODE, &is->state);506			is->isp.cac_margin_x = is->i2h_cmd.args[1];507			is->isp.cac_margin_y = is->i2h_cmd.args[2];508			pr_debug("CAC margin (x,y): (%d,%d)\n",509				 is->isp.cac_margin_x, is->isp.cac_margin_y);510			break;511 512		case HIC_STREAM_ON:513			clear_bit(IS_ST_STREAM_OFF, &is->state);514			set_bit(IS_ST_STREAM_ON, &is->state);515			break;516 517		case HIC_STREAM_OFF:518			clear_bit(IS_ST_STREAM_ON, &is->state);519			set_bit(IS_ST_STREAM_OFF, &is->state);520			break;521 522		case HIC_SET_PARAMETER:523			is->config[is->config_index].p_region_index[0] = 0;524			is->config[is->config_index].p_region_index[1] = 0;525			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);526			pr_debug("HIC_SET_PARAMETER\n");527			break;528 529		case HIC_GET_PARAMETER:530			break;531 532		case HIC_SET_TUNE:533			break;534 535		case HIC_GET_STATUS:536			break;537 538		case HIC_OPEN_SENSOR:539			set_bit(IS_ST_OPEN_SENSOR, &is->state);540			pr_debug("data lanes: %d, settle line: %d\n",541				 is->i2h_cmd.args[2], is->i2h_cmd.args[1]);542			break;543 544		case HIC_CLOSE_SENSOR:545			clear_bit(IS_ST_OPEN_SENSOR, &is->state);546			is->sensor_index = 0;547			break;548 549		case HIC_MSG_TEST:550			pr_debug("config MSG level completed\n");551			break;552 553		case HIC_POWER_DOWN:554			clear_bit(IS_ST_PWR_SUBIP_ON, &is->state);555			break;556 557		case HIC_GET_SET_FILE_ADDR:558			is->setfile.base = is->i2h_cmd.args[1];559			set_bit(IS_ST_SETFILE_LOADED, &is->state);560			break;561 562		case HIC_LOAD_SET_FILE:563			set_bit(IS_ST_SETFILE_LOADED, &is->state);564			break;565		}566		break;567 568	case IH_REPLY_NOT_DONE:569		pr_err("ISR_NDONE: %d: %#x, %s\n", is->i2h_cmd.args[0],570		       is->i2h_cmd.args[1],571		       fimc_is_strerr(is->i2h_cmd.args[1]));572 573		if (is->i2h_cmd.args[1] & IS_ERROR_TIME_OUT_FLAG)574			pr_err("IS_ERROR_TIME_OUT\n");575 576		switch (is->i2h_cmd.args[1]) {577		case IS_ERROR_SET_PARAMETER:578			fimc_is_mem_barrier();579		}580 581		switch (is->i2h_cmd.args[0]) {582		case HIC_SET_PARAMETER:583			is->config[is->config_index].p_region_index[0] = 0;584			is->config[is->config_index].p_region_index[1] = 0;585			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);586			break;587		}588		break;589 590	case IHC_NOT_READY:591		pr_err("IS control sequence error: Not Ready\n");592		break;593	}594 595	wake_up(&is->irq_queue);596}597 598static irqreturn_t fimc_is_irq_handler(int irq, void *priv)599{600	struct fimc_is *is = priv;601	unsigned long flags;602	u32 status;603 604	spin_lock_irqsave(&is->slock, flags);605	status = mcuctl_read(is, MCUCTL_REG_INTSR1);606 607	if (status & (1UL << FIMC_IS_INT_GENERAL))608		fimc_is_general_irq_handler(is);609 610	if (status & (1UL << FIMC_IS_INT_FRAME_DONE_ISP))611		fimc_isp_irq_handler(is);612 613	spin_unlock_irqrestore(&is->slock, flags);614	return IRQ_HANDLED;615}616 617static int fimc_is_hw_open_sensor(struct fimc_is *is,618				  struct fimc_is_sensor *sensor)619{620	struct sensor_open_extended *soe = (void *)&is->is_p_region->shared;621 622	fimc_is_hw_wait_intmsr0_intmsd0(is);623 624	soe->self_calibration_mode = 1;625	soe->actuator_type = 0;626	soe->mipi_lane_num = 0;627	soe->mclk = 0;628	soe->mipi_speed	= 0;629	soe->fast_open_sensor = 0;630	soe->i2c_sclk = 88000000;631 632	fimc_is_mem_barrier();633 634	/*635	 * Some user space use cases hang up here without this636	 * empirically chosen delay.637	 */638	udelay(100);639 640	mcuctl_write(HIC_OPEN_SENSOR, is, MCUCTL_REG_ISSR(0));641	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));642	mcuctl_write(sensor->drvdata->id, is, MCUCTL_REG_ISSR(2));643	mcuctl_write(sensor->i2c_bus, is, MCUCTL_REG_ISSR(3));644	mcuctl_write(is->is_dma_p_region, is, MCUCTL_REG_ISSR(4));645 646	fimc_is_hw_set_intgr0_gd0(is);647 648	return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,649				  sensor->drvdata->open_timeout);650}651 652 653int fimc_is_hw_initialize(struct fimc_is *is)654{655	static const int config_ids[] = {656		IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO,657		IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO658	};659	struct device *dev = &is->pdev->dev;660	u32 prev_id;661	int i, ret;662 663	/* Sensor initialization. Only one sensor is currently supported. */664	ret = fimc_is_hw_open_sensor(is, &is->sensor[0]);665	if (ret < 0)666		return ret;667 668	/* Get the setfile address. */669	fimc_is_hw_get_setfile_addr(is);670 671	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,672				 FIMC_IS_CONFIG_TIMEOUT);673	if (ret < 0) {674		dev_err(dev, "get setfile address timed out\n");675		return ret;676	}677	pr_debug("setfile.base: %#x\n", is->setfile.base);678 679	/* Load the setfile. */680	fimc_is_load_setfile(is, FIMC_IS_SETFILE_6A3);681	clear_bit(IS_ST_SETFILE_LOADED, &is->state);682	fimc_is_hw_load_setfile(is);683	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,684				 FIMC_IS_CONFIG_TIMEOUT);685	if (ret < 0) {686		dev_err(dev, "loading setfile timed out\n");687		return ret;688	}689 690	pr_debug("setfile: base: %#x, size: %d\n",691		 is->setfile.base, is->setfile.size);692	pr_info("FIMC-IS Setfile info: %s\n", is->fw.setfile_info);693 694	/* Check magic number. */695	if (is->is_p_region->shared[MAX_SHARED_COUNT - 1] !=696	    FIMC_IS_MAGIC_NUMBER) {697		dev_err(dev, "magic number error!\n");698		return -EIO;699	}700 701	pr_debug("shared region: %pad, parameter region: %pad\n",702		 &is->memory.addr + FIMC_IS_SHARED_REGION_OFFSET,703		 &is->is_dma_p_region);704 705	is->setfile.sub_index = 0;706 707	/* Stream off. */708	fimc_is_hw_stream_off(is);709	ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,710				 FIMC_IS_CONFIG_TIMEOUT);711	if (ret < 0) {712		dev_err(dev, "stream off timeout\n");713		return ret;714	}715 716	/* Preserve previous mode. */717	prev_id = is->config_index;718 719	/* Set initial parameter values. */720	for (i = 0; i < ARRAY_SIZE(config_ids); i++) {721		is->config_index = config_ids[i];722		fimc_is_set_initial_params(is);723		ret = fimc_is_itf_s_param(is, true);724		if (ret < 0) {725			is->config_index = prev_id;726			return ret;727		}728	}729	is->config_index = prev_id;730 731	set_bit(IS_ST_INIT_DONE, &is->state);732	dev_info(dev, "initialization sequence completed (%d)\n",733						is->config_index);734	return 0;735}736 737static int fimc_is_show(struct seq_file *s, void *data)738{739	struct fimc_is *is = s->private;740	const u8 *buf = is->memory.vaddr + FIMC_IS_DEBUG_REGION_OFFSET;741 742	if (is->memory.vaddr == NULL) {743		dev_err(&is->pdev->dev, "firmware memory is not initialized\n");744		return -EIO;745	}746 747	seq_printf(s, "%s\n", buf);748	return 0;749}750 751DEFINE_SHOW_ATTRIBUTE(fimc_is);752 753static void fimc_is_debugfs_remove(struct fimc_is *is)754{755	debugfs_remove_recursive(is->debugfs_entry);756	is->debugfs_entry = NULL;757}758 759static void fimc_is_debugfs_create(struct fimc_is *is)760{761	is->debugfs_entry = debugfs_create_dir("fimc_is", NULL);762 763	debugfs_create_file("fw_log", S_IRUGO, is->debugfs_entry, is,764			    &fimc_is_fops);765}766 767static int fimc_is_runtime_resume(struct device *dev);768static int fimc_is_runtime_suspend(struct device *dev);769 770static void __iomem *fimc_is_get_pmu_regs(struct device *dev)771{772	struct device_node *node;773	void __iomem *regs;774 775	node = of_parse_phandle(dev->of_node, "samsung,pmu-syscon", 0);776	if (!node) {777		node = of_get_child_by_name(dev->of_node, "pmu");778		if (!node)779			return IOMEM_ERR_PTR(-ENODEV);780		dev_warn(dev, "Found PMU node via deprecated method, update your DTB\n");781	}782 783	regs = of_iomap(node, 0);784	of_node_put(node);785	if (!regs)786		return IOMEM_ERR_PTR(-ENOMEM);787 788	return regs;789}790 791static int fimc_is_probe(struct platform_device *pdev)792{793	struct device *dev = &pdev->dev;794	struct fimc_is *is;795	struct resource res;796	int ret;797 798	is = devm_kzalloc(&pdev->dev, sizeof(*is), GFP_KERNEL);799	if (!is)800		return -ENOMEM;801 802	is->pdev = pdev;803	is->isp.pdev = pdev;804 805	init_waitqueue_head(&is->irq_queue);806	spin_lock_init(&is->slock);807	mutex_init(&is->lock);808 809	ret = of_address_to_resource(dev->of_node, 0, &res);810	if (ret < 0)811		return ret;812 813	is->regs = devm_ioremap_resource(dev, &res);814	if (IS_ERR(is->regs))815		return PTR_ERR(is->regs);816 817	is->pmu_regs = fimc_is_get_pmu_regs(dev);818	if (IS_ERR(is->pmu_regs))819		return PTR_ERR(is->pmu_regs);820 821	is->irq = irq_of_parse_and_map(dev->of_node, 0);822	if (!is->irq) {823		dev_err(dev, "no irq found\n");824		ret = -EINVAL;825		goto err_iounmap;826	}827 828	ret = fimc_is_get_clocks(is);829	if (ret < 0)830		goto err_iounmap;831 832	platform_set_drvdata(pdev, is);833 834	ret = request_irq(is->irq, fimc_is_irq_handler, 0, dev_name(dev), is);835	if (ret < 0) {836		dev_err(dev, "irq request failed\n");837		goto err_clk;838	}839	pm_runtime_enable(dev);840 841	if (!pm_runtime_enabled(dev)) {842		ret = fimc_is_runtime_resume(dev);843		if (ret < 0)844			goto err_irq;845	}846 847	ret = pm_runtime_resume_and_get(dev);848	if (ret < 0)849		goto err_pm_disable;850 851	vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));852 853	ret = devm_of_platform_populate(dev);854	if (ret < 0)855		goto err_pm;856 857	/*858	 * Register FIMC-IS V4L2 subdevs to this driver. The video nodes859	 * will be created within the subdev's registered() callback.860	 */861	ret = fimc_is_register_subdevs(is);862	if (ret < 0)863		goto err_pm;864 865	fimc_is_debugfs_create(is);866 867	ret = fimc_is_request_firmware(is, FIMC_IS_FW_FILENAME);868	if (ret < 0)869		goto err_dfs;870 871	pm_runtime_put_sync(dev);872 873	dev_dbg(dev, "FIMC-IS registered successfully\n");874	return 0;875 876err_dfs:877	fimc_is_debugfs_remove(is);878	fimc_is_unregister_subdevs(is);879err_pm:880	pm_runtime_put_noidle(dev);881	if (!pm_runtime_enabled(dev))882		fimc_is_runtime_suspend(dev);883err_pm_disable:884	pm_runtime_disable(dev);885err_irq:886	free_irq(is->irq, is);887err_clk:888	fimc_is_put_clocks(is);889err_iounmap:890	iounmap(is->pmu_regs);891	return ret;892}893 894static int fimc_is_runtime_resume(struct device *dev)895{896	struct fimc_is *is = dev_get_drvdata(dev);897	int ret;898 899	ret = fimc_is_setup_clocks(is);900	if (ret)901		return ret;902 903	return fimc_is_enable_clocks(is);904}905 906static int fimc_is_runtime_suspend(struct device *dev)907{908	struct fimc_is *is = dev_get_drvdata(dev);909 910	fimc_is_disable_clocks(is);911	return 0;912}913 914#ifdef CONFIG_PM_SLEEP915static int fimc_is_resume(struct device *dev)916{917	/* TODO: */918	return 0;919}920 921static int fimc_is_suspend(struct device *dev)922{923	struct fimc_is *is = dev_get_drvdata(dev);924 925	/* TODO: */926	if (test_bit(IS_ST_A5_PWR_ON, &is->state))927		return -EBUSY;928 929	return 0;930}931#endif /* CONFIG_PM_SLEEP */932 933static void fimc_is_remove(struct platform_device *pdev)934{935	struct device *dev = &pdev->dev;936	struct fimc_is *is = dev_get_drvdata(dev);937 938	pm_runtime_disable(dev);939	pm_runtime_set_suspended(dev);940	if (!pm_runtime_status_suspended(dev))941		fimc_is_runtime_suspend(dev);942	free_irq(is->irq, is);943	fimc_is_unregister_subdevs(is);944	vb2_dma_contig_clear_max_seg_size(dev);945	fimc_is_put_clocks(is);946	iounmap(is->pmu_regs);947	fimc_is_debugfs_remove(is);948	release_firmware(is->fw.f_w);949	fimc_is_free_cpu_memory(is);950}951 952static const struct of_device_id fimc_is_of_match[] = {953	{ .compatible = "samsung,exynos4212-fimc-is" },954	{ /* sentinel */ },955};956MODULE_DEVICE_TABLE(of, fimc_is_of_match);957 958static const struct dev_pm_ops fimc_is_pm_ops = {959	SET_SYSTEM_SLEEP_PM_OPS(fimc_is_suspend, fimc_is_resume)960	SET_RUNTIME_PM_OPS(fimc_is_runtime_suspend, fimc_is_runtime_resume,961			   NULL)962};963 964static struct platform_driver fimc_is_driver = {965	.probe		= fimc_is_probe,966	.remove_new	= fimc_is_remove,967	.driver = {968		.of_match_table	= fimc_is_of_match,969		.name		= FIMC_IS_DRV_NAME,970		.pm		= &fimc_is_pm_ops,971	}972};973 974static int fimc_is_module_init(void)975{976	int ret;977 978	ret = fimc_is_register_i2c_driver();979	if (ret < 0)980		return ret;981 982	ret = platform_driver_register(&fimc_is_driver);983 984	if (ret < 0)985		fimc_is_unregister_i2c_driver();986 987	return ret;988}989 990static void fimc_is_module_exit(void)991{992	fimc_is_unregister_i2c_driver();993	platform_driver_unregister(&fimc_is_driver);994}995 996module_init(fimc_is_module_init);997module_exit(fimc_is_module_exit);998 999MODULE_ALIAS("platform:" FIMC_IS_DRV_NAME);1000MODULE_AUTHOR("Younghwan Joo <yhwan.joo@samsung.com>");1001MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");1002MODULE_DESCRIPTION("Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver");1003MODULE_LICENSE("GPL v2");1004