From b087a940a27f00d2ae7434b2ccf9a876d5f3b046 Mon Sep 17 00:00:00 2001 From: Sugnan Prabhu S Date: Thu, 21 May 2020 20:41:03 +0530 Subject: drivers/intel/mipi_camera: Add camera power resource to SSDT This change adds support function to parse entries in the devicetree to generate PowerResource entries for the MIPI camera. Change-Id: I31e198b50acf2c64035aff9cb054fbe3602dd83e Signed-off-by: Sugnan Prabhu S Reviewed-on: https://review.coreboot.org/c/coreboot/+/41624 Reviewed-by: Rizwan Qureshi Reviewed-by: Tim Wawrzynczak Tested-by: build bot (Jenkins) --- src/drivers/intel/mipi_camera/camera.c | 98 ++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'src/drivers/intel/mipi_camera/camera.c') diff --git a/src/drivers/intel/mipi_camera/camera.c b/src/drivers/intel/mipi_camera/camera.c index 03e5ab65db..f32f744f8f 100644 --- a/src/drivers/intel/mipi_camera/camera.c +++ b/src/drivers/intel/mipi_camera/camera.c @@ -17,6 +17,7 @@ #define DEFAULT_REMOTE_NAME "\\_SB.PCI0.CIO2" #define CIO2_PCI_DEV 0x14 #define CIO2_PCI_FN 0x3 +#define POWER_RESOURCE_NAME "PRIC" /* * This implementation assumes there is only 1 endpoint at each end of every data port. It also @@ -435,6 +436,58 @@ static void camera_fill_vcm(const struct device *dev) acpi_dp_write(dsd); } +static void fill_power_res_sequence(struct drivers_intel_mipi_camera_config *config, + struct operation_seq *seq) +{ + unsigned int i; + uint8_t index; + uint8_t gpio_num; + + for (i = 0; i < seq->ops_cnt; i++) { + switch (seq->ops[i].type) { + case IMGCLK: + index = seq->ops[i].index; + if (seq->ops[i].action == ENABLE) { + acpigen_emit_namestring("MCON"); + acpigen_write_byte(config->clk_panel.clks[index].clknum); + acpigen_write_byte(config->clk_panel.clks[index].freq); + } else if (seq->ops[i].action == DISABLE) { + acpigen_emit_namestring("MCOF"); + acpigen_write_byte(config->clk_panel.clks[index].clknum); + } else { + acpigen_write_debug_string("Unsupported clock action"); + printk(BIOS_ERR, "Unsupported clock action: %x\n", + seq->ops[i].action); + printk(BIOS_ERR, "OS camera driver will likely not work"); + } + + break; + case GPIO: + index = seq->ops[i].index; + gpio_num = config->gpio_panel.gpio[index].gpio_num; + if (seq->ops[i].action == ENABLE) { + acpigen_soc_set_tx_gpio(gpio_num); + } else if (seq->ops[i].action == DISABLE) { + acpigen_soc_clear_tx_gpio(gpio_num); + } else { + acpigen_write_debug_string("Unsupported GPIO action"); + printk(BIOS_ERR, "Unsupported GPIO action: %x\n", + seq->ops[i].action); + printk(BIOS_ERR, "OS camera driver will likely not work"); + } + + break; + default: + printk(BIOS_ERR, "Unsupported power operation: %x\n", seq->ops[i].type); + printk(BIOS_ERR, "OS camera driver will likely not work"); + break; + } + + if (seq->ops[i].delay_ms) + acpigen_write_sleep(seq->ops[i].delay_ms); + } +} + static void write_pci_camera_device(const struct device *dev) { struct drivers_intel_mipi_camera_config *config = dev->chip_info; @@ -467,6 +520,40 @@ static void write_i2c_camera_device(const struct device *dev, const char *scope) acpigen_write_device(acpi_device_name(dev)); + /* add power resource */ + if (config->has_power_resource) { + acpigen_write_power_res(POWER_RESOURCE_NAME, 0, 0, NULL, 0); + acpigen_write_name_integer("STA", 0); + acpigen_write_STA_ext("STA"); + + acpigen_write_method_serialized("_ON", 0); + acpigen_write_if(); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_namestring("STA"); + acpigen_write_integer(0); + + fill_power_res_sequence(config, &config->on_seq); + + acpigen_write_store_op_to_namestr(1, "STA"); + acpigen_pop_len(); /* if */ + acpigen_pop_len(); /* _ON */ + + /* _OFF operations */ + acpigen_write_method_serialized("_OFF", 0); + acpigen_write_if(); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_namestring("STA"); + acpigen_write_integer(1); + + fill_power_res_sequence(config, &config->off_seq); + + acpigen_write_store_op_to_namestr(0, "STA"); + acpigen_pop_len(); /* if */ + acpigen_pop_len(); /* _ON */ + + acpigen_pop_len(); /* Power Resource */ + } + if (config->device_type == INTEL_ACPI_CAMERA_SENSOR) acpigen_write_name_integer("_ADR", 0); @@ -519,6 +606,17 @@ static void write_camera_device_common(const struct device *dev) acpigen_write_name_integer("CAMD", config->device_type); } + if (config->pr0 || config->has_power_resource) { + acpigen_write_name("_PR0"); + acpigen_write_package(1); + if (config->pr0) + acpigen_emit_namestring(config->pr0); /* External power resource */ + else + acpigen_emit_namestring(POWER_RESOURCE_NAME); + + acpigen_pop_len(); /* _PR0 */ + } + switch (config->device_type) { case INTEL_ACPI_CAMERA_CIO2: camera_fill_cio2(dev); -- cgit v1.2.3